From 5e97c3fcce787a5bc0f8ceef43aa3e05195b480a Mon Sep 17 00:00:00 2001 From: dlezcano Date: Wed, 6 Aug 2008 14:32:29 +0000 Subject: [PATCH] Initial revision --- .cvsignore | 7 + AUTHORS | 1 + COPYING | 504 +++ ChangeLog | 0 INSTALL | 234 ++ Makefile.am | 8 + NEWS | 0 README | 275 ++ RELEASE-NOTES | 0 bootstrap | 11 + config/.cvsignore | 2 + config/Makefile.am | 0 config/config.guess | 1500 ++++++++ config/config.sub | 1616 +++++++++ config/depcomp | 584 ++++ config/install-sh | 507 +++ config/ltmain.sh | 6909 +++++++++++++++++++++++++++++++++++++ config/missing | 367 ++ configure.in | 38 + doc/fstab | 2 + doc/lxc.conf | 36 + etc/.cvsignore | 7 + etc/Makefile.am | 13 + etc/lxc-complex-config.in | 23 + etc/lxc-macvlan.conf.in | 8 + etc/lxc-no-netns.conf.in | 2 + etc/lxc-phys.conf.in | 9 + etc/lxc-veth.conf.in | 9 + lxc.spec.in | 99 + src/.cvsignore | 5 + src/Makefile.am | 1 + src/liblxc/.cvsignore | 4 + src/liblxc/Makefile.am | 26 + src/liblxc/cgroup.c | 188 + src/liblxc/cgroup.h | 30 + src/liblxc/conf.c | 1250 +++++++ src/liblxc/conf.h | 144 + src/liblxc/create.c | 153 + src/liblxc/destroy.c | 123 + src/liblxc/execute.c | 278 ++ src/liblxc/freezer.c | 73 + src/liblxc/genl.c | 148 + src/liblxc/genl.h | 121 + src/liblxc/kill.c | 74 + src/liblxc/list.c | 23 + src/liblxc/list.h | 57 + src/liblxc/lock.c | 61 + src/liblxc/lock.h | 30 + src/liblxc/log.c | 9 + src/liblxc/log.h | 20 + src/liblxc/lxc.h | 220 ++ src/liblxc/monitor.c | 97 + src/liblxc/namespace.h | 71 + src/liblxc/network.c | 727 ++++ src/liblxc/network.h | 126 + src/liblxc/nl.c | 260 ++ src/liblxc/nl.h | 228 ++ src/liblxc/rtnl.c | 72 + src/liblxc/rtnl.h | 110 + src/liblxc/start.c | 261 ++ src/liblxc/state.c | 193 ++ src/liblxc/state.h | 33 + src/liblxc/stop.c | 95 + src/liblxc/utils.h | 51 + src/lxc/.cvsignore | 15 + src/lxc/Makefile.am | 61 + src/lxc/config.c | 550 +++ src/lxc/config.h | 28 + src/lxc/lxc-priority.c | 33 + src/lxc/lxc-ps.in | 17 + src/lxc/lxc_console.c | 33 + src/lxc/lxc_create.c | 86 + src/lxc/lxc_destroy.c | 63 + src/lxc/lxc_execute.c | 68 + src/lxc/lxc_freeze.c | 64 + src/lxc/lxc_kill.c | 33 + src/lxc/lxc_monitor.c | 98 + src/lxc/lxc_start.c | 74 + src/lxc/lxc_state.c | 67 + src/lxc/lxc_stop.c | 62 + src/lxc/lxc_unfreeze.c | 63 + test/.cvsignore | 19 + test/Makefile.am | 91 + test/conf.c | 102 + test/confile.c | 82 + test/dev.c | 76 + test/forward.c | 77 + test/ipv4_add.c | 66 + test/ipv6_add.c | 66 + test/lxc_create.c | 176 + test/lxc_destroy.c | 55 + test/lxc_monitor.c | 100 + test/lxc_start.c | 84 + test/lxc_state.c | 66 + test/lxc_stop.c | 59 + test/macvlan.c | 66 + test/movedev.c | 64 + test/proxy.c | 77 + test/tst_list.c | 66 + test/veth.c | 66 + 100 files changed, 21006 insertions(+) create mode 100644 .cvsignore create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 RELEASE-NOTES create mode 100755 bootstrap create mode 100644 config/.cvsignore create mode 100644 config/Makefile.am create mode 100755 config/config.guess create mode 100755 config/config.sub create mode 100755 config/depcomp create mode 100755 config/install-sh create mode 100644 config/ltmain.sh create mode 100755 config/missing create mode 100644 configure.in create mode 100644 doc/fstab create mode 100644 doc/lxc.conf create mode 100644 etc/.cvsignore create mode 100644 etc/Makefile.am create mode 100644 etc/lxc-complex-config.in create mode 100644 etc/lxc-macvlan.conf.in create mode 100644 etc/lxc-no-netns.conf.in create mode 100644 etc/lxc-phys.conf.in create mode 100644 etc/lxc-veth.conf.in create mode 100644 lxc.spec.in create mode 100644 src/.cvsignore create mode 100644 src/Makefile.am create mode 100644 src/liblxc/.cvsignore create mode 100644 src/liblxc/Makefile.am create mode 100644 src/liblxc/cgroup.c create mode 100644 src/liblxc/cgroup.h create mode 100644 src/liblxc/conf.c create mode 100644 src/liblxc/conf.h create mode 100644 src/liblxc/create.c create mode 100644 src/liblxc/destroy.c create mode 100644 src/liblxc/execute.c create mode 100644 src/liblxc/freezer.c create mode 100644 src/liblxc/genl.c create mode 100644 src/liblxc/genl.h create mode 100644 src/liblxc/kill.c create mode 100644 src/liblxc/list.c create mode 100644 src/liblxc/list.h create mode 100644 src/liblxc/lock.c create mode 100644 src/liblxc/lock.h create mode 100644 src/liblxc/log.c create mode 100644 src/liblxc/log.h create mode 100644 src/liblxc/lxc.h create mode 100644 src/liblxc/monitor.c create mode 100644 src/liblxc/namespace.h create mode 100644 src/liblxc/network.c create mode 100644 src/liblxc/network.h create mode 100644 src/liblxc/nl.c create mode 100644 src/liblxc/nl.h create mode 100644 src/liblxc/rtnl.c create mode 100644 src/liblxc/rtnl.h create mode 100644 src/liblxc/start.c create mode 100644 src/liblxc/state.c create mode 100644 src/liblxc/state.h create mode 100644 src/liblxc/stop.c create mode 100644 src/liblxc/utils.h create mode 100644 src/lxc/.cvsignore create mode 100644 src/lxc/Makefile.am create mode 100644 src/lxc/config.c create mode 100644 src/lxc/config.h create mode 100644 src/lxc/lxc-priority.c create mode 100755 src/lxc/lxc-ps.in create mode 100644 src/lxc/lxc_console.c create mode 100644 src/lxc/lxc_create.c create mode 100644 src/lxc/lxc_destroy.c create mode 100644 src/lxc/lxc_execute.c create mode 100644 src/lxc/lxc_freeze.c create mode 100644 src/lxc/lxc_kill.c create mode 100644 src/lxc/lxc_monitor.c create mode 100644 src/lxc/lxc_start.c create mode 100644 src/lxc/lxc_state.c create mode 100644 src/lxc/lxc_stop.c create mode 100644 src/lxc/lxc_unfreeze.c create mode 100644 test/.cvsignore create mode 100644 test/Makefile.am create mode 100644 test/conf.c create mode 100644 test/confile.c create mode 100644 test/dev.c create mode 100644 test/forward.c create mode 100644 test/ipv4_add.c create mode 100644 test/ipv6_add.c create mode 100644 test/lxc_create.c create mode 100644 test/lxc_destroy.c create mode 100644 test/lxc_monitor.c create mode 100644 test/lxc_start.c create mode 100644 test/lxc_state.c create mode 100644 test/lxc_stop.c create mode 100644 test/macvlan.c create mode 100644 test/movedev.c create mode 100644 test/proxy.c create mode 100644 test/tst_list.c create mode 100644 test/veth.c diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 000000000..57b72619f --- /dev/null +++ b/.cvsignore @@ -0,0 +1,7 @@ +Makefile +Makefile.in +configure +config.status +config.log +autom4te.cache +aclocal.m4 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..7e36433a2 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +IBM Corporation. diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..5ab7695ab --- /dev/null +++ b/COPYING @@ -0,0 +1,504 @@ + 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 000000000..e69de29bb diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..5458714e1 --- /dev/null +++ b/INSTALL @@ -0,0 +1,234 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006 Free Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..61b68fcf1 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,8 @@ +# Makefile.am + +SUBDIRS = src test etc +DIST_SUBDIRS = config src test etc +EXTRA_DIST = lxc.spec + +rpm: dist + rpmbuild --clean -ta ${distdir}.tar.gz diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/README b/README new file mode 100644 index 000000000..7eb3f7754 --- /dev/null +++ b/README @@ -0,0 +1,275 @@ + +Linux Container - LXC: +---------------------- + +This document provides a quick help to use the linux container. + +Change log: +----------- + +version 0.1.0 : initial document, Daniel Lezcano , Aug 01, 2008 + +Contents: +--------- + 0) Quick start + 1) Overview + 2) Requirements + 3) Functional Specification + 4) Future work + + +0) Quick start +-------------- + +You are in a hurry, and you don't want to read this README. Ok, +without warranty, here are the commands to launch a shell inside a +container with a predefined configuration template, it may work. + + lxc-create -n foo -f /etc/lxc/lxc-macvlan.conf + + lxc-execute -n foo /bin/bash + +When your bash exits, you don't have to create 'foo' again, just call +lxc-execute again. + +1) Overview +----------- + +The container technology is actively being pushed into the mainstream +linux kernel. It provides the resource management through the control +groups aka process containers and resource isolation through the +namespaces. + +The LXC aims to use these new functionnalities to provide an userspace +container object which provides full resource isolation and resource +control for an applications or a system. + +The first objective of this project is to make the life easier for the +kernel developpers involved in the containers project and especially +to continue working on the Checkpoint/Restart new features. The LXC is +small enough to easily manage a container with simple command lines +and complete enough to be used for other purposes. + +2) Requirements +--------------- + +The LXC relies on a set of functionnalies provided by the kernel which +needs to be active. Depending of the missing functionnality the LXC +will work with a restricted number of functionnality or will simply +fails. + +This is the list of the kernel features which needs to be compiled in: + +* General + * Control Group support + -> namespace cgroup subsystem + -> cpuset support + -> Group CPU scheduler + -> control group freeze subsystem + -> Basis for grouping tasks (Control Groups) + -> Simple CPU accounting + -> Resource counters + -> Memory resource controllers for Control Groups + -> Namespace support + -> UTS namespace + -> IPC namespace + -> User namespace + -> Pid namespace +* Network support + -> Networking options + -> Network namespace support + +For the moment the easiest way to have all the features in the kernel +is to use the git tree at: + +git://git.kernel.org/pub/scm/linux/kernel/git/daveh/linux-2.6-lxc.git + +Otherwise the latest version of 2.6.26 kernel is usable with LXC but +without sysfs if the network namespace is activated and without the +freezer subsystem. + +Before using LXC, the system should be configured as followed: + +* Control group file system must be mounted + + mount -t cgroup cgroup /cgroup + +* You must have root privileges + +3) Functional Specification +--------------------------- + +A container is an object where the configuration is persistent. The +application will be launched inside this container and it will +use the configuration which was previously created. + +3.1 Container life cycle +------------------------ + +When the container is created, it contains the configuration +information. When a process is launched, the container will be +starting and running. When the last process running inside the +container exits, the container is stopped. + +In case of failure when the container is initialized, it will pass +through the aborting state. + + --------- + | STOPPED |<--------------- + --------- | + | | + start | + | | + V | + ---------- | + | STARTING |--error- | + ---------- | | + | | | + V V | + --------- ---------- | + | RUNNING | | ABORTING | | + --------- ---------- | + | | | + no process | | + | | | + V | | + ---------- | | + | STOPPING |<------- | + ---------- | + | | + --------------------- + +3.2 Configuration file +---------------------- + +The configuration file has the following format: + +-------------------------------------------------------------------------------- + +# the fstab mount file. +lxc.mount = ./fstab + +# the hostname to be set into the container +lxc.utsname = virtnode + +# the chroot if needed for the running application +lxc.chroot = /mnt/root + +# The network has several of kind of configuration: +# +# * veth : the network will use the veth virtual device, the +# specified link must be a bridge +# * macvlan : the network will use the macvlan device, the specified +# link should be an existing interface, usually it is +# eth0 +# * phys : the network will use a physical network device, the +# specified link should be an existing interface +lxc.network.type = macvlan + +# specify the flags to be used for the network, actually only is +# allowed which mean the network should be set up when created. If the +# network is set up, the loopback is automatically set up too. +lxc.network.flags = up + +# specify the physical network device which will communicate with the +# outside world +lxc.network.link = eth0 + +# NIC ethernet mac address +lxc.network.hwaddr = 4a:49:43:49:79:bd + +# specify the ipv4 address of the container. Several lines are allowed +# and will mean several addresses will be assigned to the interface +lxc.network.ipv4 = 1.2.3.5/24 + +# specify the ipv6 address of the container. Several lines are allowed +# and will mean several addresses will be assigned to the interface +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 + +-------------------------------------------------------------------------------- + + * lxc.mount is optional + * lxc.utsname is optional + * lxc.network.xxx are optional, if not specified, the network + namespace will not be created + * lxc.chroot is optional + +3.3 Container creation +---------------------- + +The container is created via the 'lxc-create' command. The command +specifies the container name and the container configuration file. + + lxc-create -n foo -f + + +3.4 Starting a container +------------------------ + +As the container has been create with the lxc-create command, it is +possible now to start an application inside. + + lxc-execute -n foo /bin/bash + +When the application has exited, it is possible to continue using the +container configuration to launch another application. + +3.5 Stopping a container +------------------------ + +Usually, a container stops when the last process exits but in some +cases, it is usefully to wipe out such application. The following +command will kill the processes. + + lxc-stop -n foo + +3.6 Freezing/Unfreezing a container +----------------------------------- + +All the processes belonging to a container can be stopped and resumed. + + lxc-freeze -n foo + + lxc-unfreeze -n foo + +3.7 Sending a signal to a container +----------------------------------- + +A signal can be sent to all processes running inside the container. + + lxc-kill -n foo -s + +3.8 Monitoring container states +------------------------------- + +A container has a life cycle and pass though different states as +defined in section 3.1. The following command allows to watch such +states for a specific container. + + lxc-monitor -n foo + +3.9 Getting the container state +------------------------------- + +At any time, the following command will retrieve the state of the +container. + + lxc-state -n foo + +3.10 Showing processes list for a container +------------------------------------------ + +The following command will show all the processes for all the running +container. + + lxc-ps + +4) Future work +-------------- + + * change the lxc-start command to support system container + * change the lxc-execute to have the first process to exec + * take into account all the resource management + * man pages + * improve monitoring support + * and more :) diff --git a/RELEASE-NOTES b/RELEASE-NOTES new file mode 100644 index 000000000..e69de29bb diff --git a/bootstrap b/bootstrap new file mode 100755 index 000000000..8323eb3ce --- /dev/null +++ b/bootstrap @@ -0,0 +1,11 @@ +#!/bin/sh + +set -x + +test -d autom4te.cache && rm -rf autom4te.cache + +ACLOCAL_AMFLAGS="-I config $ACLOCAL_AMFLAGS" +aclocal $ACLOCAL_AMFLAGS || exit 1 +autoheader || exit 1 +autoconf || exit 1 +automake --add-missing --copy || exit 1 diff --git a/config/.cvsignore b/config/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/config/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/config/Makefile.am b/config/Makefile.am new file mode 100644 index 000000000..e69de29bb diff --git a/config/config.guess b/config/config.guess new file mode 100755 index 000000000..396482d6c --- /dev/null +++ b/config/config.guess @@ -0,0 +1,1500 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2006-07-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 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. +# +# 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 Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +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 + +# 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 tupples: *-*-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=`(/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 ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + 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 + # 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/[-_].*/\./'` + ;; + 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}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${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 ;; + 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'` + exit ;; + 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 ;; + 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:SunOS:5.*:*) + echo i386-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:*:[45]) + 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/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + 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 __LP64__ >/dev/null + 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:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[3456]*) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T:Interix*:[3456]*) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-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-gnu`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 '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + 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 ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${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-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; 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.0*:*) + 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 i386. + echo i386-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; } ;; + 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.0*:*) + 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 ;; + 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 ;; + 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 + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + 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 ;; + 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 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +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` +/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/config.sub b/config/config.sub new file mode 100755 index 000000000..fab0aa355 --- /dev/null +++ b/config/config.sub @@ -0,0 +1,1616 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2006-09-20' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 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. +# +# 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. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# 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. + +# 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 + $0 [OPTION] 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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +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-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + 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) + os= + basic_machine=$1 + ;; + -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*) + 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 \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | 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 \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-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-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | 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-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # 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 + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + 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 + ;; + cr16c) + basic_machine=cr16c-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 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + 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'm not sure what "Sysv32" means. Should this be sysv3.2? + 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 + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + 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 + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + 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 + ;; + 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 + ;; + 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) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + 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 | ppc64-le | powerpc64-little) + 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) + 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 + ;; + 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 + ;; + 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 + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + 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 + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-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[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. + -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* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -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* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -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*) + # 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 + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -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 + ;; + # 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 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + 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 + ;; + -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/config/depcomp b/config/depcomp new file mode 100755 index 000000000..ca5ea4e1e --- /dev/null +++ b/config/depcomp @@ -0,0 +1,584 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2006-10-15.18 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software +# Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# 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 outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +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" + +# 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 + +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 -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## 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). +## - 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 -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## 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. + tr ' ' ' +' < "$tmpdepfile" | +## 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. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -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 -eq 0; then : + else + 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 ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +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. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + 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. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + 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 -eq 0; then : + else + 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,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" + else + echo "#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. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # 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.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#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 $1 != '--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:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + 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 $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + 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. + -*|$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" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + 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 $1 != '--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, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +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-end: "$" +# End: diff --git a/config/install-sh b/config/install-sh new file mode 100755 index 000000000..4fbbae7b7 --- /dev/null +++ b/config/install-sh @@ -0,0 +1,507 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-10-14.15 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +posix_glob= +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chmodcmd=$chmodprog +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + shift + shift + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac +done + +if test $# -ne 0 && test -z "$dir_arg$dstarg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix=/ ;; + -*) prefix=./ ;; + *) prefix= ;; + esac + + case $posix_glob in + '') + if (set -f) 2>/dev/null; then + posix_glob=true + else + posix_glob=false + fi ;; + esac + + oIFS=$IFS + IFS=/ + $posix_glob && set -f + set fnord $dstdir + shift + $posix_glob && set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dst"; then + $doit $rmcmd -f "$dst" 2>/dev/null \ + || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ + && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ + || { + echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + } || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/config/ltmain.sh b/config/ltmain.sh new file mode 100644 index 000000000..d70dc75c3 --- /dev/null +++ b/config/ltmain.sh @@ -0,0 +1,6909 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# 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. +# +# 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. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.5.22 +TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)" + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs 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 + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +duplicate_deps=no +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $mkdir "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || { + $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 + exit $EXIT_FAILURE + } + fi + + $echo "X$my_tmpdir" | $Xsed +} + + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + + $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" + $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 + exit $EXIT_FAILURE + fi +} + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + extracted_serial=`expr $extracted_serial + 1` + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then + exit $exit_status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + ${rm}r unfat-$$ + cd "$darwin_orig_dir" + else + cd "$darwin_orig_dir" + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + fi # $run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +disable_libs=no + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + $echo + $echo "Copyright (C) 2005 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $? + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $? + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $? + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) + prevopt="--tag" + prev=tag + preserve_args="$preserve_args --tag" + ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +case $disable_libs in +no) + ;; +shared) + build_libtool_libs=no + build_old_libs=yes + ;; +static) + build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` + ;; +esac + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, and some SunOS ksh mistreat backslash-escaping + # in scan sets (worked around with variable expansion), + # and furthermore cannot handle '|' '&' '(' ')' in scan sets + # at all, so we specify them separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + *.obj) xform=obj ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` + case $qlibobj in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qlibobj="\"$qlibobj\"" ;; + esac + test "X$libobj" != "X$qlibobj" \ + && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo "$srcfile" > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` + case $qsrcfile in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qsrcfile="\"$qsrcfile\"" ;; + esac + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + darwin_framework|darwin_framework_skip) + test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework|-arch|-isysroot) + case " $CC " in + *" ${arg} ${1} "* | *" ${arg} ${1} "*) + prev=darwin_framework_skip ;; + *) compiler_flags="$compiler_flags $arg" + prev=darwin_framework ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + notinst_path="$notinst_path $dir" + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + -model) + compile_command="$compile_command $arg" + compiler_flags="$compiler_flags $arg" + finalize_command="$finalize_command $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m* pass through architecture-specific compiler args for GCC + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -pg pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \ + -t[45]*|-txscale*|@*) + + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then + exit $exit_status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $absdir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes ; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | + $EGREP ": [^:]* bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. +# for path in $notinst_path; do +# lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` +# deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` +# dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` +# done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name=`expr $a_deplib : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$echo "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$output_la-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadable object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + else + $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +" + + case $host in + *cygwin* | *mingw* ) + $echo >> "$output_objdir/$dlsyms" "\ +/* DATA imports from DLLs on WIN32 can't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs */ +struct { +" + ;; + * ) + $echo >> "$output_objdir/$dlsyms" "\ +const struct { +" + ;; + esac + + + $echo >> "$output_objdir/$dlsyms" "\ + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + case $host in + *cygwin* | *mingw* ) + if test -f "$output_objdir/${outputname}.def" ; then + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + else + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + fi + ;; + * ) + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + ;; + esac + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + exit_status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $exit_status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + output_name=`basename $output` + output_path=`dirname $output` + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +/* -DDEBUG is fairly common in CFLAGS. */ +#undef DEBUG +#if defined DEBUGWRAPPER +# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) +#else +# define DEBUG(format, ...) +#endif + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +const char * base_name (const char *name); +char * find_executable(const char *wrapper); +int check_executable(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + DEBUG("(main) argv[0] : %s\n",argv[0]); + DEBUG("(main) program_name : %s\n",program_name); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = find_executable(argv[0]); + if (newargz[1] == NULL) + lt_fatal("Couldn't find %s", argv[0]); + DEBUG("(main) found exe at : %s\n",newargz[1]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; + + for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" + return 127; +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char)name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable(const char * path) +{ + struct stat st; + + DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) && + ( + /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ +#if defined (S_IXOTH) + ((st.st_mode & S_IXOTH) == S_IXOTH) || +#endif +#if defined (S_IXGRP) + ((st.st_mode & S_IXGRP) == S_IXGRP) || +#endif + ((st.st_mode & S_IXUSR) == S_IXUSR)) + ) + return 1; + else + return 0; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise */ +char * +find_executable (const char* wrapper) +{ + int has_slash = 0; + const char* p; + const char* p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char* concat_name; + + DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char* path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char* q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR(*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + return NULL; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs 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 + +# 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 + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \$*\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$gentop"; then + exit $exit_status + fi + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) prev=$arg ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` + else + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir=`func_mktempdir` + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "X----------------------------------------------------------------------" | $Xsed + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + fi" + done + + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to ." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $? + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +disable_libs=shared +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +disable_libs=static +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/config/missing b/config/missing new file mode 100755 index 000000000..1c8ff7049 --- /dev/null +++ b/config/missing @@ -0,0 +1,367 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2006-05-10.23 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# 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. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case $1 in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $1 in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..80b926e52 --- /dev/null +++ b/configure.in @@ -0,0 +1,38 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_INIT([lxc], [0.1.0]) + +AC_CONFIG_SRCDIR([configure.in]) +AC_CONFIG_AUX_DIR([config]) +AM_CONFIG_HEADER([src/config.h]) +AM_INIT_AUTOMAKE([-Wno-portability]) +AC_CANONICAL_HOST +AC_PROG_RANLIB +AM_PROG_CC_C_O +AC_GNU_SOURCE +AC_CHECK_HEADERS([linux/netlink.h linux/genetlink.h],, AC_MSG_ERROR([netlink headers not found]), [[]]) +AC_PROG_GCC_TRADITIONAL + +if test "x$GCC" = "xyes"; then + CFLAGS="$CFLAGS -Wall -Werror" +fi + +AC_CONFIG_FILES([ + Makefile + lxc.spec + config/Makefile + src/Makefile + src/liblxc/Makefile + src/lxc/Makefile + src/lxc/lxc-ps + etc/Makefile + etc/lxc-macvlan.conf + etc/lxc-no-netns.conf + etc/lxc-phys.conf + etc/lxc-veth.conf + etc/lxc-complex-config + test/Makefile +]) +AC_CONFIG_COMMANDS([default],[[]],[[]]) +AC_OUTPUT diff --git a/doc/fstab b/doc/fstab new file mode 100644 index 000000000..808c6e0f2 --- /dev/null +++ b/doc/fstab @@ -0,0 +1,2 @@ +proc /proc proc defaults 0 0 +sysfs /sys sysfs noauto 0 0 diff --git a/doc/lxc.conf b/doc/lxc.conf new file mode 100644 index 000000000..58cb960cc --- /dev/null +++ b/doc/lxc.conf @@ -0,0 +1,36 @@ +# the fstab mount file +lxc.mount = ./fstab + +# the hostname to be set into the container +lxc.utsname = virtnode + +# The network has several of kind of configuration: +# +# * veth : the network will use the veth virtual device, the specified +# link must be a bridge +# * macvlan : the network will use the macvlan device, the specified link +# should be an existing interface, usually it is eth0 +# * phys : the network will use a physical network device, the specified +# link should be an existing interface +lxc.network.type = macvlan + +# specify the flags to be used for the network, actually only is allowed +# which mean the network should be set up when created. If the network is set +# up, the loopback is automatically set up too. +lxc.network.flags = up + +# specify the physical network device which will communicate with the +# outside world +lxc.network.link = eth0 + +# NIC ethernet mac address +lxc.network.hwaddr = 4a:49:43:49:79:bd + +# specify the ipv4 address of the container. Several lines are allowed and +# will mean several addresses will be assigned to the interface +lxc.network.ipv4 = 1.2.3.5/24 + +# specify the ipv6 address of the container. Several lines are allowed and +# will mean several addresses will be assigned to the interface +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 + diff --git a/etc/.cvsignore b/etc/.cvsignore new file mode 100644 index 000000000..6c3d2fe66 --- /dev/null +++ b/etc/.cvsignore @@ -0,0 +1,7 @@ +Makefile +Makefile.in +lxc-macvlan.conf +lxc-no-netns.conf +lxc-phys.conf +lxc-veth.conf + diff --git a/etc/Makefile.am b/etc/Makefile.am new file mode 100644 index 000000000..46695610b --- /dev/null +++ b/etc/Makefile.am @@ -0,0 +1,13 @@ +pkgsysconfdir = $(sysconfdir)/$(PACKAGE) +pkgsysconf_DATA = \ + lxc-macvlan.conf \ + lxc-no-netns.conf \ + lxc-phys.conf \ + lxc-veth.conf \ + lxc-complex-config +noinst_DATA = \ + lxc-macvlan.conf.in \ + lxc-no-netns.conf.in \ + lxc-phys.conf.in \ + lxc-veth.conf.in \ + lxc-complex-config.in diff --git a/etc/lxc-complex-config.in b/etc/lxc-complex-config.in new file mode 100644 index 000000000..f2e8ea31c --- /dev/null +++ b/etc/lxc-complex-config.in @@ -0,0 +1,23 @@ +# Container with network a complex network mixing macvlan, veth and +# physical network devices +lxc.utsname = complex +lxc.network.type = veth +lxc.network.flags = up +lxc.network.link = br0 +lxc.network.hwaddr = 4a:49:43:49:79:bf +lxc.network.ipv4 = 1.2.3.5/24 +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 + +lxc.network.type = macvlan +lxc.network.flags = up +lxc.network.link = eth0 +lxc.network.hwaddr = 4a:49:43:49:79:bd +lxc.network.ipv4 = 1.2.3.4/24 +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 + +lxc.network.type = phys +lxc.network.flags = up +lxc.network.link = dummy0 +lxc.network.hwaddr = 4a:49:43:49:79:ff +lxc.network.ipv4 = 1.2.3.6/24 +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 diff --git a/etc/lxc-macvlan.conf.in b/etc/lxc-macvlan.conf.in new file mode 100644 index 000000000..d42d4af4a --- /dev/null +++ b/etc/lxc-macvlan.conf.in @@ -0,0 +1,8 @@ +# Container with network virtualized using the macvlan device driver +lxc.utsname = alpha +lxc.network.type = macvlan +lxc.network.flags = up +lxc.network.link = eth0 +lxc.network.hwaddr = 4a:49:43:49:79:bd +lxc.network.ipv4 = 1.2.3.4/24 +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 diff --git a/etc/lxc-no-netns.conf.in b/etc/lxc-no-netns.conf.in new file mode 100644 index 000000000..2c21264e9 --- /dev/null +++ b/etc/lxc-no-netns.conf.in @@ -0,0 +1,2 @@ +# Container with non-virtualized network +lxc.utsname = delta diff --git a/etc/lxc-phys.conf.in b/etc/lxc-phys.conf.in new file mode 100644 index 000000000..7c33eab6a --- /dev/null +++ b/etc/lxc-phys.conf.in @@ -0,0 +1,9 @@ +# Container with network virtualized using a physical network device with name +# 'eth0' +lxc.utsname = gamma +lxc.network.type = phys +lxc.network.flags = up +lxc.network.link = eth0 +lxc.network.hwaddr = 4a:49:43:49:79:ff +lxc.network.ipv4 = 1.2.3.6/24 +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 diff --git a/etc/lxc-veth.conf.in b/etc/lxc-veth.conf.in new file mode 100644 index 000000000..0b1568f5e --- /dev/null +++ b/etc/lxc-veth.conf.in @@ -0,0 +1,9 @@ +# Container with network virtualized using a pre-configured bridge named br0 and +# veth pair virtual network devices +lxc.utsname = beta +lxc.network.type = veth +lxc.network.flags = up +lxc.network.link = br0 +lxc.network.hwaddr = 4a:49:43:49:79:bf +lxc.network.ipv4 = 1.2.3.5/24 +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 diff --git a/lxc.spec.in b/lxc.spec.in new file mode 100644 index 000000000..ff340d097 --- /dev/null +++ b/lxc.spec.in @@ -0,0 +1,99 @@ +# +# lxc: linux Container library +# +# (C) Copyright IBM Corp. 2007, 2008 +# +# Authors: +# Daniel Lezcano +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +%define _unpackaged_files_terminate_build 0 + +%define RELEASE 1 +%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE: %RELEASE} + +# +# Arguments that can be passed to the rpm builder: +# +# --define 'confargs ' (def. '') +# + +%{!?confargs: %{expand:%%define confargs ''}} + +# What kernel are we building for? +%{!?kernel: %{expand:%%define kernel %(uname -r)}} + +%define _prefix /usr + +Name: @PACKAGE@ +Version: @VERSION@ +Release: %{rel} +Packager: +URL: http://lxc.sourceforge.net +Summary: %name +Group: Applications/System +License: LGPL +Source: %name/%name-%version.tar.gz +BuildRoot: %_tmppath/%name-%version-root + +%description +%name is a set of command line to manage containers + +%package devel +Release: %{rel} +Summary: development library for %{name} +Group: Application/System + +%description devel +The %{name}-devel package contains header files and library needed for development +of containers + +%prep +%setup -q + +%build +%configure $args + +ncpus=`egrep -c "^cpu[0-9]+" /proc/stat || :` +make -j$ncpus + +%install +rm -rf %{buildroot} +%makeinstall + +%clean +rm -rf %{buildroot} + +%post + +%files +%defattr(-,root,root) +%{_sysconfdir}/%{name}/* +%{_bindir}/* + +%files devel +%defattr(-,root,root) +%{_includedir}/%{name}/* +%{_libdir}/*.a + +%changelog +* Sun Aug 3 2008 Daniel Lezcano +- Initial RPM release. + +# Local variables: +# mode: shell-script +# sh-shell: rpm +# end: diff --git a/src/.cvsignore b/src/.cvsignore new file mode 100644 index 000000000..2fe57d024 --- /dev/null +++ b/src/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +config.h +config.h.in +stamp-h1 diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 000000000..f762d9930 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = liblxc lxc diff --git a/src/liblxc/.cvsignore b/src/liblxc/.cvsignore new file mode 100644 index 000000000..9f881c8f7 --- /dev/null +++ b/src/liblxc/.cvsignore @@ -0,0 +1,4 @@ +Makefile +Makefile.in +liblxc.la +.deps diff --git a/src/liblxc/Makefile.am b/src/liblxc/Makefile.am new file mode 100644 index 000000000..46eb76e78 --- /dev/null +++ b/src/liblxc/Makefile.am @@ -0,0 +1,26 @@ +lib_LIBRARIES = liblxc.a +pkginclude_HEADERS = lxc.h +liblxc_a_SOURCES = \ + create.c \ + destroy.c \ + start.c \ + stop.c \ + execute.c \ + monitor.c \ + kill.c \ + state.c \ + freezer.c \ + cgroup.c cgroup.h \ + lxc.h \ + utils.h \ + lock.c lock.h \ + namespace.h \ + network.c network.h \ + conf.c conf.h \ + list.h \ + state.c state.h \ + log.c log.h \ + \ + nl.c nl.h \ + rtnl.c rtnl.h \ + genl.c genl.h diff --git a/src/liblxc/cgroup.c b/src/liblxc/cgroup.c new file mode 100644 index 000000000..29855a0df --- /dev/null +++ b/src/liblxc/cgroup.c @@ -0,0 +1,188 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MAXPRIOLEN 24 +#define MTAB "/etc/mtab" + +static int get_cgroup_mount(const char *mtab, char *mnt) +{ + struct mntent *mntent; + FILE *file = NULL; + int err = -1; + + file = setmntent(mtab, "r"); + if (!file) { + lxc_log_syserror("failed to open %s", mtab); + goto out; + } + + while ((mntent = getmntent(file))) { + if (strcmp(mntent->mnt_fsname, "cgroup")) + continue; + strcpy(mnt, mntent->mnt_dir); + err = 0; + break; + }; + + fclose(file); +out: + return err; +} + +int lxc_link_nsgroup(const char *name, pid_t pid) +{ + char *lxc, *nsgroup, cgroup[MAXPATHLEN]; + int ret; + + if (get_cgroup_mount(MTAB, cgroup)) { + lxc_log_info("cgroup is not mounted"); + return -1; + } + + asprintf(&lxc, LXCPATH "/%s/nsgroup", name); + asprintf(&nsgroup, "%s/%d", cgroup, pid); + + ret = symlink(nsgroup, lxc); + if (ret) + lxc_log_syserror("failed to create symlink %s->%s", + nsgroup, lxc); + free(lxc); + free(nsgroup); + return ret; +} + +int lxc_unlink_nsgroup(const char *name) +{ + char *nsgroup; + int ret; + + asprintf(&nsgroup, LXCPATH "/%s/nsgroup", name); + ret = unlink(nsgroup); + free(nsgroup); + + return ret; +} + +int lxc_set_priority(const char *name, int priority) +{ + int fd; + char *path = NULL, *prio = NULL; + + asprintf(&path, LXCPATH "/%s/nsgroup/cpu.shares", name); + + fd = open(path, O_WRONLY); + if (fd < 0) { + lxc_log_syserror("failed to open '%s'", path); + goto out; + } + + asprintf(&prio, "%d", priority); + + if (write(fd, prio, strlen(prio) + 1) < 0) { + lxc_log_syserror("failed to write to '%s'", path); + close(fd); + goto out; + } + + close(fd); +out: + free(path); + free(prio); + return 0; +} + +int lxc_get_priority(const char *name, int *priority) +{ + int fd, ret = -1; + char *path, prio[MAXPRIOLEN]; + + asprintf(&path, LXCPATH "/%s/nsgroup/cpu.shares", name); + + fd = open(path, O_RDONLY); + if (fd < 0) { + lxc_log_syserror("failed to open '%s'", path); + goto out; + } + + if (read(fd, prio, MAXPRIOLEN) < 0) { + lxc_log_syserror("failed to read from '%s'", path); + close(fd); + goto out; + } + + close(fd); + *priority = atoi(prio); + + ret = 0; +out: + free(path); + return 0; +} + +int lxc_set_memory(const char *name, size_t memmax) +{ + return 0; +} + +int lxc_get_memory(const char *name, size_t *memmax) +{ + return 0; +} + +int lxc_get_memstat(const char *name, struct lxc_mem_stat *memstat) +{ + return 0; +} + +int lxc_set_cpuset(const char *name, long *cpumask, int len, int shared) +{ + return 0; +} + +int lxc_get_cpuset(const char *name, long *cpumask, int len, int *shared) +{ + return 0; +} + +int lxc_get_cpu_usage(const char *name, long long *usage) +{ + return 0; +} diff --git a/src/liblxc/cgroup.h b/src/liblxc/cgroup.h new file mode 100644 index 000000000..8060cdf43 --- /dev/null +++ b/src/liblxc/cgroup.h @@ -0,0 +1,30 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _cgroup_h +#define _cgroup_h + +int lxc_get_cgroup_mount(const char *mtab, char *mnt); +int lxc_link_nsgroup(const char *name, pid_t pid); +int lxc_unlink_nsgroup(const char *name); + +#endif diff --git a/src/liblxc/conf.c b/src/liblxc/conf.c new file mode 100644 index 000000000..419a7e2e6 --- /dev/null +++ b/src/liblxc/conf.c @@ -0,0 +1,1250 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MAXHWLEN 18 +#define MAXINDEXLEN 20 +#define MAXLINELEN 128 + +typedef int (*instanciate_cb)(const char *dirname, + const char *file, pid_t pid); + +typedef int (*dir_cb)(const char *name, const char *dirname, + const char *file, void *data); + +typedef int (*file_cb)(void* buffer, void *data); + +struct netdev_conf { + const char *type; + instanciate_cb cb; + int count; +}; + +static int instanciate_veth(const char *, const char *, pid_t); +static int instanciate_macvlan(const char *, const char *, pid_t); +static int instanciate_phys(const char *, const char *, pid_t); + +static struct netdev_conf netdev_conf[] = { + { "veth", instanciate_veth, 0 }, + { "macvlan", instanciate_macvlan, 0, }, + { "phys", instanciate_phys, 0, }, +}; + +static int dir_filter(const struct dirent *dirent) +{ + if (!strcmp(dirent->d_name, ".") || + !strcmp(dirent->d_name, "..")) + return 0; + return 1; +} + +static int dir_for_each(const char *name, const char *dirname, + dir_cb callback, void *data) +{ + struct dirent **namelist; + int n; + + n = scandir(dirname, &namelist, dir_filter, alphasort); + if (n < 0) { + lxc_log_syserror("failed to scan %s directory", dirname); + return -1; + } + + while (n--) { + if (callback(name, dirname, namelist[n]->d_name, data)) { + lxc_log_error("callback failed"); + free(namelist[n]); + return -1; + } + free(namelist[n]); + } + + return 0; +} + +static int file_for_each_line(const char *file, file_cb callback, + void *buffer, size_t len, void* data) +{ + FILE *f; + int err = -1; + + f = fopen(file, "r"); + if (!f) { + lxc_log_syserror("failed to open %s", file); + return -1; + } + + while (fgets(buffer, len, f)) + if (callback(buffer, data)) + goto out; + err = 0; +out: + fclose(f); + return err; +} + +static int write_info(const char *path, const char *file, const char *info) +{ + int fd, err = -1; + char *f; + + asprintf(&f, "%s/%s", path, file); + fd = creat(f, 0755); + if (fd < 0) + goto out; + + if (write(fd, info, strlen(info)) < 0 || + write(fd, "\n", strlen("\n") + 1) < 0) + goto out_write; + err = 0; +out: + close(fd); + free(f); + return err; + +out_write: + unlink(f); + goto out; +} + +static int read_info(const char *path, const char *file, char *info, size_t len) +{ + int fd, ret = -1; + char *f, *token; + + asprintf(&f, "%s/%s", path, file); + fd = open(f, O_RDONLY); + if (fd < 0) { + if (errno == ENOENT) + ret = 1; + goto out; + } + + ret = read(fd, info, len); + if (ret < 0) + goto out; + + token = strstr(info, "\n"); + if (token) + *token = '\0'; + ret = 0; +out: + close(fd); + free(f); + return ret; +} + +static int delete_info(const char *path, const char *file) +{ + char *info; + int ret; + + asprintf(&info, "%s/%s", path, file); + ret = unlink(info); + free(info); + + return ret; +} + +static int configure_ip_address(const char *path, struct list *ip, int family) +{ + struct list *iterator; + char *file = NULL, *line = NULL; + char addr[INET6_ADDRSTRLEN]; + char bcast[INET_ADDRSTRLEN]; + int fd, err = -1; + + if (mkdir(path, 0755)) { + lxc_log_syserror("failed to create directory %s", path); + return -1; + } + + asprintf(&file, "%s/addresses", path); + fd = creat(file, 0755); + if (fd < 0) { + lxc_log_syserror("failed to create %s file", file); + goto err; + } + + if (family == AF_INET) { + struct inetdev *in; + + list_for_each(iterator, ip) { + + in = iterator->elem; + + if (!inet_ntop(family, &in->addr, addr, sizeof(addr))) { + lxc_log_syserror("failed to convert ipv4 address"); + goto err; + } + + if (!inet_ntop(family, &in->bcast, bcast, sizeof(bcast))) { + lxc_log_syserror("failed to convert ipv4 broadcast"); + goto err; + } + + + if (in->prefix) + asprintf(&line, "%s/%d %s\n", addr, + in->prefix, bcast); + else + asprintf(&line, "%s %s\n", addr, bcast); + + if (write(fd, line, strlen(line)) < 0) { + lxc_log_syserror("failed to write address info"); + goto err; + } + } + } else { + struct inet6dev *in6; + + list_for_each(iterator, ip) { + + in6 = iterator->elem; + + if (!inet_ntop(family, &in6->addr, addr, sizeof(addr))) { + lxc_log_syserror("failed to convert ipv4 address"); + goto err; + } + + asprintf(&line, "%s/%d\n", addr, + in6->prefix?in6->prefix:64); + + if (write(fd, line, strlen(line)) < 0) { + lxc_log_syserror("failed to write address info to %s", + file); + goto err; + } + } + } + + err = 0; +out: + free(file); + free(line); + close(fd); + return err; +err: + unlink(file); + rmdir(path); + goto out; +} + +static int configure_netdev(const char *path, struct netdev *netdev) +{ + int err = -1; + char dir[MAXPATHLEN]; + + if (mkdir(path, 0755)) { + lxc_log_syserror("failed to create %s directory", path); + return -1; + } + + if (netdev->ifname) { + if (write_info(path, "link", netdev->ifname)) + goto out_link; + } + + if (netdev->newname) { + if (write_info(path, "name", netdev->newname)) + goto out_newname; + } + + if (netdev->hwaddr) { + if (write_info(path, "hwaddr", netdev->hwaddr)) + goto out_up; + } + + if (netdev->flags & IFF_UP) { + if (write_info(path, "up", "")) + goto out_hwaddr; + } + + if (!list_empty(&netdev->ipv4)) { + snprintf(dir, MAXPATHLEN, "%s/ipv4", path); + if (configure_ip_address(dir, &netdev->ipv4, AF_INET)) + goto out_ipv4; + } + + if (!list_empty(&netdev->ipv6)) { + snprintf(dir, MAXPATHLEN, "%s/ipv6", path); + if (configure_ip_address(dir, &netdev->ipv6, AF_INET6)) + goto out_ipv6; + } + err = 0; +out: + return err; +out_ipv6: + delete_info(path, "ipv4"); +out_ipv4: + delete_info(path, "up"); +out_hwaddr: + delete_info(path, "hwaddr"); +out_up: + delete_info(path, "name"); +out_newname: + delete_info(path, "link"); +out_link: + rmdir(path); + goto out; +} + +static int configure_utsname(const char *name, struct utsname *utsname) +{ + char path[MAXPATHLEN]; + + if (!utsname) + return 0; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s", name); + if (write_info(path, "utsname", utsname->nodename)) { + lxc_log_error("failed to write the utsname info"); + return -1; + } + + return 0; +} + +static int configure_network(const char *name, struct list *network) +{ + struct list *iterator; + struct network *n; + char *networkpath = NULL, *path = NULL; + int err = -1; + + if (list_empty(network)) + return 0; + + asprintf(&networkpath, LXCPATH "/%s/network", name); + if (mkdir(networkpath, 0755)) { + lxc_log_syserror("failed to create %s directory", networkpath); + goto out; + } + + list_for_each(iterator, network) { + + n = iterator->elem; + + if (n->type < 0 || n->type > MAXCONFTYPE) { + lxc_log_error("invalid network configuration type %d", + n->type); + goto out; + } + + asprintf(&path, "%s/%s%d", networkpath, + netdev_conf[n->type].type, netdev_conf[n->type].count++); + + if (configure_netdev(path, list_first_elem(&n->netdev))) { + lxc_log_error("failed to configure network type %s", + netdev_conf[n->type].type); + goto out; + } + } + + err = 0; +out: + free(path); + free(networkpath); + return err; +} + +static int configure_cgroup(const char *name, struct cgroup *cgroup) +{ + if (!cgroup) + return 0; + return 0; +} + +static int configure_chroot(const char *name, const char *chroot) +{ + int ret; + char *path; + + if (!chroot) + return 0; + + asprintf(&path, LXCPATH "/%s/chroot", name); + ret = symlink(chroot, path); + free(path); + + return ret; +} + +static int configure_mount(const char *name, const char *fstab) +{ + char *path; + struct stat stat; + int infd, outfd; + void *src, *dst; + char c = '\0'; + int ret = -1; + + if (!fstab) + return 0; + + asprintf(&path, LXCPATH "/%s/fstab", name); + + outfd = open(path, O_RDWR|O_CREAT|O_EXCL, 0640); + if (outfd < 0) { + lxc_log_syserror("failed to creat '%s'", path); + goto out; + } + + infd = open(fstab, O_RDONLY); + if (infd < 0) { + lxc_log_syserror("failed to open '%s'", fstab); + goto out; + } + + if (fstat(infd, &stat)) { + lxc_log_syserror("failed to stat '%s'", fstab); + goto out; + } + + if (lseek(outfd, stat.st_size - 1, SEEK_SET) < 0) { + lxc_log_syserror("failed to seek dest file '%s'", path); + goto out; + } + + /* fixup length */ + if (write(outfd, &c, 1) < 0) { + lxc_log_syserror("failed to write to '%s'", path); + goto out; + } + + src = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, infd, 0L); + if (src == MAP_FAILED) { + lxc_log_syserror("failed to mmap '%s'", fstab); + goto out; + } + + dst = mmap(NULL, stat.st_size, PROT_WRITE, MAP_SHARED, outfd, 0L); + if (dst == MAP_FAILED) { + lxc_log_syserror("failed to mmap '%s'", path); + goto out; + } + + memcpy(dst, src, stat.st_size); + + munmap(src, stat.st_size); + munmap(dst, stat.st_size); + + ret = 0; +out: + free(path); + return ret; +} + +static int unconfigure_ip_addresses(const char *dirname) +{ + char path[MAXPATHLEN]; + + snprintf(path, MAXPATHLEN, "%s/ipv4", dirname); + delete_info(path, "addresses"); + rmdir(path); + + snprintf(path, MAXPATHLEN, "%s/ipv6", dirname); + delete_info(path, "addresses"); + rmdir(path); + + return 0; +} + +static int unconfigure_network_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + char *path; + + asprintf(&path, "%s/%s", dirname, file); + delete_info(path, "name"); + delete_info(path, "addr"); + delete_info(path, "link"); + delete_info(path, "hwaddr"); + delete_info(path, "up"); + unconfigure_ip_addresses(path); + rmdir(path); + free(path); + + return 0; +} + +static int unconfigure_network(const char *name) +{ + char *dirname; + + if (!conf_has_network(name)) + return 0; + + asprintf(&dirname, LXCPATH "/%s/network", name); + dir_for_each(name, dirname, unconfigure_network_cb, NULL); + rmdir(dirname); + free(dirname); + + return 0; +} + +static int unconfigure_cgroup(const char *name) +{ + return 0; +} + +static int unconfigure_chroot(const char *name) +{ + char *path; + + asprintf(&path, LXCPATH "/%s", name); + delete_info(path, "chroot"); + free(path); + + return 0; +} + +static int unconfigure_mount(const char *name) +{ + char *path; + + if (!conf_has_fstab(name)) + return 0; + + asprintf(&path, LXCPATH "/%s", name); + delete_info(path, "fstab"); + free(path); + + return 0; +} + +static int unconfigure_utsname(const char *name) +{ + char *path; + + if (!conf_has_utsname(name)) + return 0; + + asprintf(&path, LXCPATH "/%s", name); + delete_info(path, "utsname"); + free(path); + + return 0; +} + +static int setup_utsname(const char *name) +{ + int ret; + char *path; + struct utsname utsname; + + if (!conf_has_utsname(name)) + return 0; + + asprintf(&path, LXCPATH "/%s", name); + + ret = read_info(path, "utsname", utsname.nodename, + sizeof(utsname.nodename)); + if (ret < 0) { + lxc_log_syserror("failed to read utsname info"); + goto out; + } + + if (!ret && sethostname(utsname.nodename, strlen(utsname.nodename))) { + lxc_log_syserror("failed to set the hostname to '%s'", + utsname.nodename); + goto out; + } + + ret = 0; +out: + free(path); + return ret; +} + +static int setup_chroot(const char *name) +{ + char *path, chrt[MAXPATHLEN]; + int ret = -1; + + asprintf(&path, LXCPATH "/%s/chroot", name); + + if (readlink(path, chrt, MAXPATHLEN) > 0) { + if (chroot(chrt)) { + lxc_log_syserror("failed to set chroot %s", path); + goto out; + } + if (chdir(getenv("HOME")) && chdir("/")) { + lxc_log_syserror("failed to change to home directory"); + goto out; + } + } + + ret = 0; +out: + free(path); + return ret; +} + +static int setup_mount(const char *name) +{ + char *path; + struct mntent *mntent; + FILE *file; + int ret = -1; + + if (!conf_has_fstab(name)) + return 0; + + asprintf(&path, LXCPATH "/%s/fstab", name); + + file = setmntent(path, "r"); + if (!file) { + if (errno == ENOENT) + return 0; + lxc_log_syserror("failed to open '%s'", path); + goto out; + } + + while((mntent = getmntent(file))) { + if (mount(mntent->mnt_fsname, mntent->mnt_dir, + mntent->mnt_type, 0, NULL)) { + lxc_log_syserror("failed to mount '%s' on '%s'", + mntent->mnt_fsname, mntent->mnt_dir); + goto out; + } + } + ret = 0; +out: + free(path); + endmntent(file); + return ret; +} + +static int setup_ipv4_addr_cb(void *buffer, void *data) +{ + char *ifname = data; + char *cursor, *slash, *addr, *bcast = NULL, *prefix = NULL; + int p = 24; + + addr = buffer; + cursor = strstr(addr, " "); + if (cursor) { + *cursor = '\0'; + bcast = cursor + 1; + cursor = strstr(bcast, "\n"); + if (cursor) + *cursor = '\0'; + } + + slash = strstr(addr, "/"); + if (slash) { + *slash = '\0'; + prefix = slash + 1; + } + + if (prefix) + p = atoi(prefix); + + if (ip_addr_add(ifname, addr, p, bcast)) { + lxc_log_error("failed to set %s to addr %s/%d %s", ifname, + addr, p, bcast?bcast:""); + return -1; + } + + return 0; +} + +static int setup_ipv6_addr_cb(void *buffer, void *data) +{ + char *ifname = data; + char *cursor, *slash, *addr, *bcast = NULL, *prefix = NULL; + int p = 24; + + addr = buffer; + cursor = strstr(addr, " "); + if (cursor) { + *cursor = '\0'; + bcast = cursor + 1; + cursor = strstr(bcast, "\n"); + if (cursor) + *cursor = '\0'; + } + + slash = strstr(addr, "/"); + if (slash) { + *slash = '\0'; + prefix = slash + 1; + } + + if (prefix) + p = atoi(prefix); + + if (ip6_addr_add(ifname, addr, p, bcast)) { + lxc_log_error("failed to set %s to addr %s/%d %s", ifname, + addr, p, bcast?bcast:""); + return -1; + } + + return 0; +} + +static int setup_hw_addr(char *hwaddr, const char *ifname) +{ + struct sockaddr sockaddr; + struct ifreq ifr; + int ret, fd; + + if (lxc_convert_mac(hwaddr, &sockaddr)) { + fprintf(stderr, "conversion has failed\n"); + return -1; + } + + memcpy(ifr.ifr_name, ifname, IFNAMSIZ); + memcpy((char *) &ifr.ifr_hwaddr, (char *) &sockaddr, sizeof(sockaddr)); + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + perror("socket"); + return -1; + } + + ret = ioctl(fd, SIOCSIFHWADDR, &ifr); + close(fd); + if (ret) + perror("ioctl"); + + return ret; +} + +static int setup_ip_addr(const char *dirname, const char *ifname) +{ + char *path, line[MAXLINELEN]; + struct stat s; + int ret = 0; + + asprintf(&path, "%s/ipv4/addresses", dirname); + if (!stat(path, &s)) + ret = file_for_each_line(path, setup_ipv4_addr_cb, + line, MAXPATHLEN, (void*)ifname); + free(path); + + return ret; +} + +static int setup_ip6_addr(const char *dirname, const char *ifname) +{ + char *path, line[MAXLINELEN]; + struct stat s; + int ret = 0; + + asprintf(&path, "%s/ipv6/addresses", dirname); + if (!stat(path, &s)) + ret = file_for_each_line(path, setup_ipv6_addr_cb, + line, MAXPATHLEN, (void*)ifname); + free(path); + + return ret; +} + +static int setup_network_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + char *path; + char strindex[MAXINDEXLEN]; + char ifname[IFNAMSIZ]; + char newname[IFNAMSIZ]; + char hwaddr[MAXHWLEN]; + char *current_ifname = ifname; + int ifindex, ret = -1; + + asprintf(&path, "%s/%s", dirname, file); + + if (read_info(path, "ifindex", strindex, sizeof(strindex))) { + lxc_log_error("failed to read ifindex info"); + goto out; + } + + ifindex = atoi(strindex); + if (!ifindex) { + lxc_log_error("bad index %s", strindex); + goto out; + } + + if (!if_indextoname(ifindex, current_ifname)) { + lxc_log_error("no interface corresponding to index '%d'", + ifindex); + goto out; + } + + if (!read_info(path, "name", newname, sizeof(newname))) { + if (device_rename(ifname, newname)) { + lxc_log_error("failed to rename %s->%s", + ifname, newname); + goto out; + } + current_ifname = newname; + } + + if (!read_info(path, "hwaddr", hwaddr, sizeof(hwaddr))) { + if (setup_hw_addr(hwaddr, current_ifname)) { + lxc_log_error("failed to setup hw address for '%s'", + current_ifname); + goto out; + } + } + + if (setup_ip_addr(path, current_ifname)) { + lxc_log_error("failed to setup ip addresses for '%s'", + ifname); + goto out; + } + + if (setup_ip6_addr(path, current_ifname)) { + lxc_log_error("failed to setup ipv6 addresses for '%s'", + ifname); + goto out; + } + + if (!read_info(path, "up", strindex, sizeof(strindex))) { + if (device_up(current_ifname)) { + lxc_log_error("failed to set '%s' up", current_ifname); + goto out; + } + + /* the network is up, make the loopback up too */ + if (device_up("lo")) { + lxc_log_error("failed to set the loopback up"); + goto out; + } + } + + ret = 0; +out: + return ret; +} + +static int setup_network(const char *name) +{ + char *dirname; + int ret = -1; + + if (!conf_has_network(name)) + return 0; + + asprintf(&dirname, LXCPATH "/%s/network", name); + ret = dir_for_each(name, dirname, setup_network_cb, NULL); + free(dirname); + return ret; +} + +int conf_has(const char *name, const char *info) +{ + int ret; + char *path; + struct stat st; + + asprintf(&path, LXCPATH "/%s/%s", name, info); + + ret = stat(path, &st); + if (!ret) { + ret = 1; + goto out; + } + + if (errno == ENOENT) { + ret = 0; + goto out; + } + + lxc_log_syserror("failed to stat %s info", info); +out: + free(path); + return ret; +} + +int lxc_configure(const char *name, struct lxc_conf *conf) +{ + if (!conf) + return 0; + + if (configure_utsname(name, conf->utsname)) { + lxc_log_error("failed to configure the utsname"); + return -1; + } + + if (configure_network(name, &conf->networks)) { + lxc_log_error("failed to configure the network"); + return -1; + } + + if (configure_cgroup(name, conf->cgroup)) { + lxc_log_error("failed to configure the control group"); + return -1; + } + + if (configure_chroot(name, conf->chroot)) { + lxc_log_error("failed to configure the chroot"); + return -1; + } + + if (configure_mount(name, conf->fstab)) { + lxc_log_error("failed to configure the mount points"); + return -1; + } + + return 0; +} + +int lxc_unconfigure(const char *name) +{ + if (unconfigure_utsname(name)) + lxc_log_error("failed to cleanup utsname"); + + if (unconfigure_network(name)) + lxc_log_error("failed to cleanup the network"); + + if (unconfigure_cgroup(name)) + lxc_log_error("failed to cleanup cgroup"); + + if (unconfigure_chroot(name)) + lxc_log_error("failed to cleanup chroot"); + + if (unconfigure_mount(name)) + lxc_log_error("failed to cleanup mount"); + + return 0; +} + +static int instanciate_veth(const char *dirname, const char *file, pid_t pid) +{ + char *path = NULL, *strindex = NULL, *veth1 = NULL, *veth2 = NULL; + char bridge[IFNAMSIZ]; + int ifindex, ret = -1; + + asprintf(&veth1, "%s_%d", file, pid); + asprintf(&veth2, "%s~%d", file, pid); + asprintf(&path, "%s/%s", dirname, file); + + if (read_info(path, "link", bridge, IFNAMSIZ)) { + lxc_log_error("failed to read bridge info"); + goto out; + } + + if (lxc_configure_veth(veth1, veth2, bridge)) { + lxc_log_error("failed to create %s-%s/%s", veth1, veth2, bridge); + goto out; + } + + ifindex = if_nametoindex(veth2); + if (!ifindex) { + lxc_log_error("failed to retrieve the index for %s", veth2); + goto out; + } + + asprintf(&strindex, "%d", ifindex); + if (write_info(path, "ifindex", strindex)) { + lxc_log_error("failed to write interface index to %s", path); + goto out; + } + + if (!read_info(path, "up", strindex, sizeof(strindex))) { + if (device_up(veth1)) { + lxc_log_error("failed to set %s up", veth1); + goto out; + } + } + + ret = 0; +out: + free(path); + free(strindex); + free(veth1); + free(veth2); + return ret; +} +static int instanciate_macvlan(const char *dirname, const char *file, pid_t pid) +{ + char *path = NULL, *strindex = NULL, *peer = NULL; + char link[IFNAMSIZ]; + int ifindex, ret = -1; + + asprintf(&peer, "%s~%d", file, pid); + asprintf(&path, "%s/%s", dirname, file); + if (read_info(path, "link", link, IFNAMSIZ)) { + lxc_log_error("failed to read bridge info"); + goto out; + } + + if (lxc_configure_macvlan(link, peer)) { + lxc_log_error("failed to create macvlan interface %s", peer); + goto out; + } + + ifindex = if_nametoindex(peer); + if (!ifindex) { + lxc_log_error("failed to retrieve the index for %s", peer); + goto out; + } + + asprintf(&strindex, "%d", ifindex); + if (write_info(path, "ifindex", strindex)) { + lxc_log_error("failed to write interface index to %s", path); + goto out; + } + + ret = 0; +out: + free(path); + free(strindex); + free(peer); + return ret; +} + +static int instanciate_phys(const char *dirname, const char *file, pid_t pid) +{ + char *path = NULL, *strindex = NULL; + char link[IFNAMSIZ]; + int ifindex, ret = -1; + + asprintf(&path, "%s/%s", dirname, file); + if (read_info(path, "link", link, IFNAMSIZ)) { + lxc_log_error("failed to read link info"); + goto out; + } + + ifindex = if_nametoindex(link); + if (!ifindex) { + lxc_log_error("failed to retrieve the index for %s", link); + goto out; + } + + asprintf(&strindex, "%d", ifindex); + if (write_info(path, "ifindex", strindex)) { + lxc_log_error("failed to write interface index to %s", path); + goto out; + } + + ret = 0; +out: + free(path); + free(strindex); + return ret; +} + +static int instanciate_netdev_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + pid_t *pid = data; + + if (!strncmp("veth", file, strlen("veth"))) + return instanciate_veth(dirname, file, *pid); + else if (!strncmp("macvlan", file, strlen("macvlan"))) + return instanciate_macvlan(dirname, file, *pid); + else if (!strncmp("phys", file, strlen("phys"))) + return instanciate_phys(dirname, file, *pid); + + return -1; +} + +static int instanciate_netdev(const char *name, pid_t pid) +{ + char *dirname; + int ret; + + asprintf(&dirname, LXCPATH "/%s/network", name); + ret = dir_for_each(name, dirname, instanciate_netdev_cb, &pid); + free(dirname); + + return ret; +} + +static int move_netdev_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + char *path, ifname[IFNAMSIZ], strindex[MAXINDEXLEN]; + pid_t *pid = data; + int ifindex, ret = -1; + + asprintf(&path, "%s/%s", dirname, file); + if (read_info(path, "ifindex", strindex, MAXINDEXLEN) < 0) { + lxc_log_error("failed to read index to from %s", path); + goto out; + } + + ifindex = atoi(strindex); + if (!if_indextoname(ifindex, ifname)) { + lxc_log_error("interface with index %d does not exist", + ifindex); + goto out; + } + + if (device_move(ifname, *pid)) { + lxc_log_error("failed to move %s to %d", ifname, *pid); + goto out; + } + + ret = 0; +out: + free(path); + return ret; +} + +static int move_netdev(const char *name, pid_t pid) +{ + char *dirname; + int ret; + + asprintf(&dirname, LXCPATH "/%s/network", name); + ret = dir_for_each(name, dirname, move_netdev_cb, &pid); + free(dirname); + + return ret; +} + +int conf_create_network(const char *name, pid_t pid) +{ + if (instanciate_netdev(name, pid)) { + lxc_log_error("failed to instantiate the network devices"); + return -1; + } + + if (move_netdev(name, pid)) { + lxc_log_error("failed to move the netdev to the container"); + return -1; + } + + return 0; +} + +static int delete_netdev_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + char strindex[MAXINDEXLEN]; + char path[MAXPATHLEN]; + char ifname[IFNAMSIZ]; + int i, ifindex; + + snprintf(path, MAXPATHLEN, "%s/%s", dirname, file); + + if (read_info(path, "ifindex", strindex, MAXINDEXLEN)) { + lxc_log_error("failed to read ifindex info"); + return -1; + } + + ifindex = atoi(strindex); + if (!ifindex) { + lxc_log_error("bad index %s", strindex); + return -1; + } + + /* TODO : temporary code - needs wait on namespace */ + for (i = 0; i < 120; i++) { + if (if_indextoname(ifindex, ifname)) + break; + if (!i) + printf("waiting for interface #%d to come back\n", ifindex); + else + printf("."); fflush(stdout); + sleep(1); + } + + /* do not delete a physical network device */ + if (strncmp("phys", file, strlen("phys"))) + if (device_delete(ifname)) { + lxc_log_error("failed to remove the netdev %s", ifname); + } + + delete_info(path, "ifindex"); + + return 0; +} + +static int delete_netdev(const char *name) +{ + char *dirname; + int ret; + + asprintf(&dirname, LXCPATH "/%s/network", name); + ret = dir_for_each(name, dirname, delete_netdev_cb, NULL); + free(dirname); + + return ret; +} + +int conf_destroy_network(const char *name) +{ + if (delete_netdev(name)) { + lxc_log_error("failed to remove the network devices"); + return -1; + } + + return 0; +} + +int lxc_setup(const char *name) +{ + if (setup_utsname(name)) { + lxc_log_error("failed to setup the utsname for '%s'", name); + return -1; + } + + if (setup_network(name)) { + lxc_log_error("failed to setup the network for '%s'", name); + return -1; + } + + if (setup_mount(name)) { + lxc_log_error("failed to setup the mount points for '%s'", name); + return -1; + } + + if (setup_chroot(name)) { + lxc_log_error("failed to set chroot for '%s'", name); + return -1; + } + + return 0; +} diff --git a/src/liblxc/conf.h b/src/liblxc/conf.h new file mode 100644 index 000000000..9b5183fd0 --- /dev/null +++ b/src/liblxc/conf.h @@ -0,0 +1,144 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _conf_h +#define _conf_h + +enum { + VETH, + MACVLAN, + PHYS, + MAXCONFTYPE, +}; + +/* + * Defines the structure to configure an ipv4 address + * @address : ipv4 address + * @broadcast : ipv4 broadcast address + * @mask : network mask + */ +struct inetdev { + struct in_addr addr; + struct in_addr bcast; + int prefix; +}; + +struct route { + struct in_addr addr; +}; + +/* + * Defines the structure to configure an ipv6 address + * @flags : set the address up + * @address : ipv6 address + * @broadcast : ipv6 broadcast address + * @mask : network mask + */ +struct inet6dev { + struct in6_addr addr; + struct in6_addr bcast; + struct in6_addr acast; + int prefix; +}; + +struct route6 { + struct in6_addr addr; +}; +/* + * Defines a structure to configure a network device + * @ifname : network device name + * @flags : flag of the network device (IFF_UP, ... ) + * @ipv4 : a list of ipv4 addresses to be set on the network device + * @ipv6 : a list of ipv6 addresses to be set on the network device + */ +struct netdev { + int flags; + char *ifname; + char *newname; + char *hwaddr; + struct list ipv4; + struct list ipv6; + struct list route4; + struct list route6; +}; + +/* + * Defines the kind of the network to use + * @type : the type of the network virtualization + * @phys : phys configuration type + * @veth : veth configuration type + * @macvlan : macvlan configuration type + */ +struct network { + int type; + struct list netdev; +}; + +/* + * Defines a structure to configure the control data and path + */ +struct cgroup { + ; +}; + +/* + * Defines the global container configuration + * @chroot : the root directory to run the container + * @mount : the list of mount points + * @network : the network configuration + * @utsname : the container utsname + */ +struct lxc_conf { + char *chroot; + char *fstab; + struct utsname *utsname; + struct cgroup *cgroup; + struct list networks; +}; + +/* + * Configure the external resources for the container + */ +extern int lxc_configure(const char *name, struct lxc_conf *conf); + +/* + * Remove the resources created by the configuration + */ +extern int lxc_unconfigure(const char *name); + +extern int conf_create_network(const char *name, pid_t pid); + +extern int conf_destroy_network(const char *name); + +/* + * Configure the container from inside + */ +extern int lxc_setup(const char *name); + +extern int conf_has(const char *name, const char *info); + +#define conf_has_fstab(__name) conf_has(__name, "fstab") +#define conf_has_utsname(__name) conf_has(__name, "utsname") +#define conf_has_network(__name) conf_has(__name, "network") + + +#endif diff --git a/src/liblxc/create.c b/src/liblxc/create.c new file mode 100644 index 000000000..4c764c913 --- /dev/null +++ b/src/liblxc/create.c @@ -0,0 +1,153 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static int dir_filter(const struct dirent *dirent) +{ + if (!strcmp(dirent->d_name, ".") || + !strcmp(dirent->d_name, "..")) + return 0; + return 1; +} + +static int is_empty_directory(const char *dirname) +{ + struct dirent **namelist; + int n; + + n = scandir(dirname, &namelist, dir_filter, alphasort); + if (n < 0) + lxc_log_syserror("failed to scan %s directory", dirname); + return n == 0; +} + +static int create_lxc_directory(const char *dirname) +{ + char path[MAXPATHLEN]; + + if (mkdir(LXCPATH, 0755) && errno != EEXIST) { + lxc_log_syserror("failed to created %s directory", LXCPATH); + return -1; + } + + sprintf(path, LXCPATH "/%s", dirname); + + if (mkdir(path, 0755)) { + lxc_log_syserror("failed to created %s directory", path); + return -1; + } + + return 0; +} + +static int remove_lxc_directory(const char *dirname) +{ + char path[MAXPATHLEN]; + + sprintf(path, LXCPATH "/%s", dirname); + + if (rmdir(path)) { + lxc_log_syserror("failed to remove %s directory", path); + return -1; + } + + if (is_empty_directory(LXCPATH)) { + if (rmdir(LXCPATH)) { + lxc_log_syserror("failed to remove %s directory", LXCPATH); + return -1; + } + } + + return 0; +} + +int lxc_create(const char *name, struct lxc_conf *conf) +{ + int lock, err = -1; + + if (create_lxc_directory(name)) { + lxc_log_error("failed to create %s directory", name); + return -1; + } + + lock = lxc_get_lock(name); + if (!lock) { + lxc_log_error("'%s' is busy", name); + goto err; + } + + if (lock < 0) { + lxc_log_error("failed to acquire lock on '%s':%s", + name, strerror(-lock)); + goto err; + } + + if (mkstate(name)) { + lxc_log_error("failed to create the state file for %s", name); + goto err; + } + + if (lxc_setstate(name, STOPPED)) { + lxc_log_error("failed to set state for %s", name); + goto err_state; + } + + if (lxc_configure(name, conf)) { + lxc_log_error("failed to set configuration for %s", name); + goto err_state; + } + + err = 0; +out: + lxc_put_lock(lock); + return err; + +err_state: + lxc_unconfigure(name); + + if (rmstate(name)) + lxc_log_error("failed to remove state file for %s", name); +err: + if (remove_lxc_directory(name)) + lxc_log_error("failed to cleanup lxc directory for %s", name); + goto out; +} diff --git a/src/liblxc/destroy.c b/src/liblxc/destroy.c new file mode 100644 index 000000000..f8b4fc233 --- /dev/null +++ b/src/liblxc/destroy.c @@ -0,0 +1,123 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static int dir_filter(const struct dirent *dirent) +{ + if (!strcmp(dirent->d_name, ".") || + !strcmp(dirent->d_name, "..")) + return 0; + return 1; +} + +static int is_empty_directory(const char *dirname) +{ + struct dirent **namelist; + int n; + + n = scandir(dirname, &namelist, dir_filter, alphasort); + if (n < 0) + lxc_log_syserror("failed to scan %s directory", dirname); + return n == 0; +} + +static int remove_lxc_directory(const char *dirname) +{ + char path[MAXPATHLEN]; + + sprintf(path, LXCPATH "/%s", dirname); + + if (rmdir(path)) { + lxc_log_syserror("failed to remove %s directory", path); + return -1; + } + + if (is_empty_directory(LXCPATH)) { + if (rmdir(LXCPATH)) { + lxc_log_syserror("failed to remove %s directory", LXCPATH); + return -1; + } + } + + return 0; +} + +int lxc_destroy(const char *name) +{ + int ret = -1, lock; + + lock = lxc_get_lock(name); + if (!lock) { + lxc_log_error("'%s' is busy", name); + goto out; + } + + if (lock < 0) { + lxc_log_error("failed to acquire the lock for '%s':%s", + name, strerror(-lock)); + goto out; + } + + if (rmstate(name)) { + lxc_log_error("failed to remove state file for %s", name); + goto out_lock; + } + + if (lxc_unconfigure(name)) { + lxc_log_error("failed to cleanup %s", name); + goto out_lock; + } + + if (remove_lxc_directory(name)) { + lxc_log_syserror("failed to remove '%s'", name); + goto out_lock; + } + + ret = 0; + +out_lock: + lxc_put_lock(lock); +out: + return ret; +} diff --git a/src/liblxc/execute.c b/src/liblxc/execute.c new file mode 100644 index 000000000..79008ed6e --- /dev/null +++ b/src/liblxc/execute.c @@ -0,0 +1,278 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LXC_TTY_HANDLER(SIGINT); +LXC_TTY_HANDLER(SIGQUIT); + +int lxc_execute(const char *name, int argc, char *argv[], + lxc_callback_t preexec, void *data) +{ + char *init = NULL, *val = NULL, *vinit = "[vinit]"; + int fd, lock, sv[2], sync = 0, err = -1; + pid_t pid; + int clone_flags; + + lock = lxc_get_lock(name); + if (!lock) { + lxc_log_error("'%s' is busy", name); + return -1; + } + + if (lock < 0) { + lxc_log_error("failed to acquire lock on '%s':%s", + name, strerror(-lock)); + return -1; + } + + fcntl(lock, F_SETFD, FD_CLOEXEC); + + if (lxc_setstate(name, STARTING)) { + lxc_log_error("failed to set state %s", state2str(STARTING)); + goto out; + } + + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) { + lxc_log_syserror("failed to create communication socketpair"); + goto err; + } + + LXC_TTY_ADD_HANDLER(SIGINT); + LXC_TTY_ADD_HANDLER(SIGQUIT); + + clone_flags = CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS; + if (conf_has_utsname(name)) + clone_flags |= CLONE_NEWUTS; + if (conf_has_network(name)) + clone_flags |= CLONE_NEWNET; + + pid = fork_ns(clone_flags); + if (pid < 0) { + lxc_log_syserror("failed to fork into a new namespace"); + goto err_fork_ns; + } + + if (!pid) { + + pid = fork(); + if (pid < 0) { + lxc_log_syserror("failed to fork"); + return 1; + } + + if (!pid) { + close(sv[1]); + fcntl(sv[0], F_SETFD, FD_CLOEXEC); + + if (write(sv[0], &sync, sizeof(sync)) < 0) { + lxc_log_syserror("failed to write socket"); + return 1; + } + + if (read(sv[0], &sync, sizeof(sync)) < 0) { + lxc_log_syserror("failed to read socket"); + return 1; + } + + if (lxc_setup(name)) { + lxc_log_error("failed to setup the container"); + goto error; + } + if (mount("proc", "/proc", "proc", 0, NULL)) { + lxc_log_error("failed to mount '/proc'"); + goto error; + } + if (mount("sysfs", "/sys", "sysfs", 0, NULL)) { + lxc_log_syserror("failed to mount '/sys'"); + /* continue: non fatal error until sysfs not per + namespace */ + } + + if (preexec) + if (preexec(name, argc, argv, data)) { + lxc_log_error("preexec callback has failed"); + return -1; + } + + execvp(argv[0], argv); + error: + lxc_log_syserror("failed to exec %s", argv[0]); + if (write(sv[0], &sync, sizeof(sync)) < 0) + lxc_log_syserror("failed to write the socket"); + + return 1; + } + + setsid(); + close(0); + close(1); + close(2); + + if (prctl(PR_SET_NAME, vinit, 0, 0, 0)) + lxc_log_syserror("failed to set process name"); + + close(sv[0]); + close(sv[1]); + + for (;;) { + int status; + if (wait(&status) < 0) { + if (errno == ECHILD) + return 0; + if (errno == EINTR) + continue; + lxc_log_syserror("failed to wait child"); + return 1; + } + } + } + + close(sv[0]); + + if (read(sv[1], &sync, sizeof(sync)) < 0) { + lxc_log_syserror("failed to read the socket"); + goto err_pipe_read; + } + + if (clone_flags & CLONE_NEWNET && conf_create_network(name, pid)) { + lxc_log_error("failed to create the configured network"); + goto err_create_network; + } + + if (write(sv[1], &sync, sizeof(sync)) < 0) { + lxc_log_syserror("failed to write the socket"); + goto err_pipe_write; + } + + err = read(sv[1], &sync, sizeof(sync)); + if (err < 0) { + lxc_log_error("failed to read the socket"); + goto err_pipe_read2; + } + + if (err > 0) { + lxc_log_error("something went wrong with %d", pid); + /* TODO : check status etc ... */ + waitpid(pid, NULL, 0); + goto err_child_failed; + } + + asprintf(&init, LXCPATH "/%s/init", name); + fd = open(init, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); + if (fd < 0) { + lxc_log_syserror("failed to open %s", init); + goto err_open; + } + + asprintf(&val, "%d", pid); + if (write(fd, val, strlen(val)) < 0) { + lxc_log_syserror("failed to write init pid"); + goto err_write; + } + + if (lxc_link_nsgroup(name, pid)) + lxc_log_warning("cgroupfs not found: cgroup disabled"); + + if (lxc_setstate(name, RUNNING)) { + lxc_log_error("failed to set state to %s", state2str(RUNNING)); + goto err_state_failed; + } + +wait_again: + if (waitpid(pid, NULL, 0) < 0) { + if (errno == EINTR) + goto wait_again; + lxc_log_syserror("failed to wait the pid %d", pid); + goto err_waitpid_failed; + } + + if (lxc_setstate(name, STOPPING)) + lxc_log_error("failed to set state %s", state2str(STOPPING)); + + if (clone_flags & CLONE_NEWNET && conf_destroy_network(name)) + lxc_log_error("failed to destroy the network"); + + err = 0; +out: + if (lxc_setstate(name, STOPPED)) + lxc_log_error("failed to set state %s", state2str(STOPPED)); + + lxc_unlink_nsgroup(name); + unlink(init); + free(init); + free(val); + lxc_put_lock(lock); + + return err; + +err_write: + close(fd); + +err_state_failed: +err_child_failed: +err_pipe_read2: +err_pipe_write: + conf_destroy_network(name); +err_create_network: +err_pipe_read: +err_open: +err_waitpid_failed: + if (lxc_setstate(name, ABORTING)) + lxc_log_error("failed to set state %s", state2str(STOPPED)); + + kill(pid, SIGKILL); +err_fork_ns: + LXC_TTY_DEL_HANDLER(SIGQUIT); + LXC_TTY_DEL_HANDLER(SIGINT); + close(sv[0]); + close(sv[1]); +err: + goto out; +} diff --git a/src/liblxc/freezer.c b/src/liblxc/freezer.c new file mode 100644 index 000000000..d941a4580 --- /dev/null +++ b/src/liblxc/freezer.c @@ -0,0 +1,73 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int freeze_unfreeze(const char *name, int freeze) +{ + char *freezer, *f = freeze?"FROZEN":"RUNNING"; + int fd, ret = -1; + + asprintf(&freezer, LXCPATH "/%s/nsgroup/freezer.state", name); + + fd = open(freezer, O_WRONLY); + if (fd < 0) { + lxc_log_syserror("failed to open freezer for '%s'", name); + goto out; + } + + ret = write(fd, f, strlen(f) + 1) < 0; + close(fd); + if (ret) + lxc_log_syserror("failed to write to '%s'", freezer); +out: + free(freezer); + return ret; +} + +int lxc_freeze(const char *name) +{ + return freeze_unfreeze(name, 1); +} + +int lxc_unfreeze(const char *name) +{ + return freeze_unfreeze(name, 0); +} + diff --git a/src/liblxc/genl.c b/src/liblxc/genl.c new file mode 100644 index 000000000..3781be154 --- /dev/null +++ b/src/liblxc/genl.c @@ -0,0 +1,148 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int genetlink_resolve_family(const char *family) +{ + struct nl_handler handler; + struct nlattr *attr; + struct genlmsg *request, *reply; + struct genlmsghdr *genlmsghdr; + + int len, ret; + + request = genlmsg_alloc(GENLMSG_GOOD_SIZE); + if (!request) + return -ENOMEM; + + reply = genlmsg_alloc(GENLMSG_GOOD_SIZE); + if (!reply) { + genlmsg_free(request); + return -ENOMEM; + } + + request->nlmsghdr.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); + request->nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + request->nlmsghdr.nlmsg_type = GENL_ID_CTRL; + + genlmsghdr = NLMSG_DATA(&request->nlmsghdr); + genlmsghdr->cmd = CTRL_CMD_GETFAMILY; + + ret = netlink_open(&handler, NETLINK_GENERIC); + if (ret) + return ret; + + ret = nla_put_string((struct nlmsg *)&request->nlmsghdr, + CTRL_ATTR_FAMILY_NAME, family); + if (ret) + goto out; + + ret = netlink_transaction(&handler, (struct nlmsg *)&request->nlmsghdr, + (struct nlmsg *)&reply->nlmsghdr); + if (ret < 0) + goto out; + + genlmsghdr = NLMSG_DATA(&reply->nlmsghdr); + len = reply->nlmsghdr.nlmsg_len; + + ret = -ENOMSG; + if (reply->nlmsghdr.nlmsg_type != GENL_ID_CTRL) + goto out; + + if (genlmsghdr->cmd != CTRL_CMD_NEWFAMILY) + goto out; + + ret = -EMSGSIZE; + len -= NLMSG_LENGTH(GENL_HDRLEN); + if (len < 0) + goto out; + + attr = (struct nlattr *)GENLMSG_DATA(reply); + attr = (struct nlattr *)((char *)attr + NLA_ALIGN(attr->nla_len)); + + ret = -ENOMSG; + if (attr->nla_type != CTRL_ATTR_FAMILY_ID) + goto out; + + ret = *(__u16 *) NLA_DATA(attr); +out: + genlmsg_free(request); + genlmsg_free(reply); + netlink_close(&handler); + return ret; +} + +extern int genetlink_open(struct genl_handler *handler, const char *family) +{ + int ret; + handler->family = genetlink_resolve_family(family); + if (handler->family < 0) + return handler->family; + + ret = netlink_open(&handler->nlh, NETLINK_GENERIC); + + return ret; +} + +extern int genetlink_close(struct genl_handler *handler) +{ + return netlink_close(&handler->nlh); +} + +extern int genetlink_rcv(struct genl_handler *handler, struct genlmsg *genlmsg) +{ + return netlink_rcv(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr); +} + +extern int genetlink_send(struct genl_handler *handler, struct genlmsg *genlmsg) +{ + + return netlink_send(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr); +} + +extern int genetlink_transaction(struct genl_handler *handler, + struct genlmsg *request, struct genlmsg *answer) +{ + return netlink_transaction(&handler->nlh, (struct nlmsg *)&request->nlmsghdr, + (struct nlmsg *)&answer->nlmsghdr); +} + +extern struct genlmsg *genlmsg_alloc(size_t size) +{ + size_t len = NLMSG_LENGTH(GENL_HDRLEN) + size; + return (struct genlmsg *)nlmsg_alloc(len); +} + +extern void genlmsg_free(struct genlmsg *genlmsg) +{ + free(genlmsg); +} diff --git a/src/liblxc/genl.h b/src/liblxc/genl.h new file mode 100644 index 000000000..4800aacc2 --- /dev/null +++ b/src/liblxc/genl.h @@ -0,0 +1,121 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __genl_h +#define __genl_h + +/* + * Use this as a good size to allocate generic netlink messages + */ +#define GENLMSG_GOOD_SIZE NLMSG_GOOD_SIZE +#define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN)) + +/* + * struct genl_handler : the structure which store the netlink handler + * and the family number resulting of the auto-generating id family + * for the generic netlink protocol + * + * @nlh: the netlink socket handler + * @family: the generic netlink family assigned number + */ +struct genl_handler +{ + struct nl_handler nlh; + int family; +}; + +/* + * struct genlmsg : the struct containing the generic netlink message + * format + * + * @nlmsghdr: a netlink message header + * @genlmsghdr: a generic netlink message header pointer + * + */ +/* __attribute__ ((aligned(4))); */ +struct genlmsg { + struct nlmsghdr nlmsghdr; + struct genlmsghdr genlmsghdr; +}; + +static inline int genetlink_len(const struct genlmsg *genlmsg) +{ + return ((genlmsg->nlmsghdr.nlmsg_len) - GENL_HDRLEN - NLMSG_HDRLEN); +} + +/* + * genetlink_open : resolve family number id and open a generic netlink socket + * + * @handler: a struct genl_handler pointer + * @family: the family name of the generic netlink protocol + * + * Returns 0 on success, < 0 otherwise + */ +int genetlink_open(struct genl_handler *handler, const char *family); + +/* + * genetlink_close : close a generic netlink socket + * + * @handler: the handler of the socket to be closed + * + * Returns 0 on success, < 0 otherwise + */ +int genetlink_close(struct genl_handler *handler); + +/* + * genetlink_rcv : receive a generic netlink socket, it is up + * to the caller to manage the allocation of the generic netlink message + * + * @handler: the handler of the generic netlink socket + * @genlmsg: the pointer to a generic netlink message pre-allocated + * + * Returns 0 on success, < 0 otherwise + */ +int genetlink_rcv(struct genl_handler *handler, struct genlmsg *genlmsg); + +/* + * genetlink_send : send a generic netlink socket, it is up + * to the caller to manage the allocation of the generic netlink message + * + * @handler: the handler of the generic netlink socket + * @genlmsg: the pointer to a generic netlink message pre-allocated + * + * Returns 0 on success, < 0 otherwise + */ +int genetlink_send(struct genl_handler *handler, struct genlmsg *genlmsg); + +struct genlmsg *genlmsg_alloc(size_t size); + +void genlmsg_free(struct genlmsg *genlmsg); + +/* + * genetlink_transaction : send and receive a generic netlink message in one shot + * + * @handler: the handler of the generic netlink socket + * @request: a generic netlink message containing the request to be sent + * @answer: a pre-allocated generic netlink message to receive the response + * + * Returns 0 on success, < 0 otherwise + */ +int genetlink_transaction(struct genl_handler *handler, + struct genlmsg *request, struct genlmsg *answer); +#endif diff --git a/src/liblxc/kill.c b/src/liblxc/kill.c new file mode 100644 index 000000000..132b099e9 --- /dev/null +++ b/src/liblxc/kill.c @@ -0,0 +1,74 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +int lxc_kill(const char *name, int signum) +{ + char *freezer = NULL, *signal = NULL; + int fd = -1, ret = -1; + + if (signum < SIGHUP || signum > SIGRTMAX) { + lxc_log_error("bad signal value %d", signum); + goto out; + } + + asprintf(&freezer, LXCPATH "/%s/nsgroup/freezer.kill", name); + asprintf(&signal, "%d", signum); + + fd = open(freezer, O_WRONLY); + if (fd < 0) { + lxc_log_syserror("failed to open %s for %s", freezer, name); + goto out; + } + + if (write(fd, &signal, strlen(signal)) < 0) { + lxc_log_syserror("failed to write to %s", freezer); + goto out; + } + + ret = 0; +out: + close(fd); + free(freezer); + free(signal); + return ret; +} diff --git a/src/liblxc/list.c b/src/liblxc/list.c new file mode 100644 index 000000000..d588ae2e1 --- /dev/null +++ b/src/liblxc/list.c @@ -0,0 +1,23 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include diff --git a/src/liblxc/list.h b/src/liblxc/list.h new file mode 100644 index 000000000..00d0d167f --- /dev/null +++ b/src/liblxc/list.h @@ -0,0 +1,57 @@ +#ifndef _list_h +#define _list_h + +struct list { + void *elem; + struct list *next; + struct list *prev; +}; + +#define init_list(l) { .next = l, .prev = l, } + +#define list_for_each(__iterator, __list) \ + for (__iterator = (__list)->next; \ + __iterator != __list; \ + __iterator = __iterator->next) + +static inline void list_init(struct list *list) +{ + list->elem = NULL; + list->next = list->prev = list; +} + +static inline void list_add_elem(struct list *list, void *elem) +{ + list->elem = elem; +} + +static inline void *list_first_elem(struct list *list) +{ + return list->next->elem; +} + +static inline int list_empty(struct list *list) +{ + return list == list->next; +} + +static inline void list_add(struct list *list, struct list *new) +{ + struct list *next = list->next; + next->prev = new; + new->next = next; + new->prev = list; + list->next = new; +} + +static inline void list_del(struct list *list) +{ + struct list *next, *prev; + + next = list->next; + prev = list->prev; + next->prev = prev; + prev->next = next; +} + +#endif diff --git a/src/liblxc/lock.c b/src/liblxc/lock.c new file mode 100644 index 000000000..26b5c170b --- /dev/null +++ b/src/liblxc/lock.c @@ -0,0 +1,61 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include + +int lxc_get_lock(const char *name) +{ + char *lock; + int fd, ret; + + asprintf(&lock, LXCPATH "/%s", name); + fd = open(lock, O_RDONLY|O_DIRECTORY, S_IRUSR|S_IWUSR); + if (fd < 0) { + ret = -errno; + goto out; + } + + if (flock(fd, LOCK_EX|LOCK_NB)) { + ret = errno == EWOULDBLOCK ? 0 : -errno; + close(fd); + goto out; + } + + ret = fd; +out: + free(lock); + return ret; +} + +void lxc_put_lock(int lock) +{ + flock(lock, LOCK_UN); + close(lock); +} diff --git a/src/liblxc/lock.h b/src/liblxc/lock.h new file mode 100644 index 000000000..d22fd7e20 --- /dev/null +++ b/src/liblxc/lock.h @@ -0,0 +1,30 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _lock_h +#define _lock_h + +extern int lxc_get_lock(const char *name); + +extern int lxc_put_lock(int lock); + +#endif diff --git a/src/liblxc/log.c b/src/liblxc/log.c new file mode 100644 index 000000000..d95c4b8cc --- /dev/null +++ b/src/liblxc/log.c @@ -0,0 +1,9 @@ +#include +#include +#include + +#include + +#define MAXTIMELEN 47; +#define ERRNO_FORMAT "%d (%s)" + diff --git a/src/liblxc/log.h b/src/liblxc/log.h new file mode 100644 index 000000000..370060f51 --- /dev/null +++ b/src/liblxc/log.h @@ -0,0 +1,20 @@ +#ifndef _log_h +#define _log_h + +#define lxc_log(format, level, ...) do { \ + fprintf(stderr, "[%s] \t%s:%d - " format "\n", \ + level, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +#define lxc_log_error(format, ...) lxc_log(format, "error", ##__VA_ARGS__); +#define lxc_log_warning(format, ...) lxc_log(format, "warning", ##__VA_ARGS__); +#define lxc_log_info(format, ...) lxc_log(format, "info", ##__VA_ARGS__); +#define lxc_log_debug(format, ...) lxc_log(format, "debug", ##__VA_ARGS__); +#define lxc_log_trace(format, ...) lxc_log(format, "trace", ##__VA_ARGS__); +#define lxc_log_syserror(format, ...) do { \ + fprintf(stderr, "[SYSERROR][%s] \t%s:%d - " format "\n", \ + strerror(errno),__FUNCTION__, __LINE__, \ + ##__VA_ARGS__); \ + } while (0) + +#endif diff --git a/src/liblxc/lxc.h b/src/liblxc/lxc.h new file mode 100644 index 000000000..44709d30e --- /dev/null +++ b/src/liblxc/lxc.h @@ -0,0 +1,220 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __lxc_h +#define __lxc_h + +/** + Following code is for liblxc. + + liblxc/lxc.h will contain exports of liblxc + **/ + +#define LXCPATH "/var/lxc" +#define MAXPIDLEN 20 + +struct lxc_mem_stat; +struct lxc_conf; + +typedef enum { + STOPPED, STARTING, RUNNING, STOPPING, + ABORTING, FREEZING, FROZEN, MAX_STATE, +} lxc_state_t; + +typedef int (*lxc_callback_t)(const char *name, int argc, + char *argv[], void *data); + +/* + * Create the container object. Creates the /lxc/ directory + * and fills it with the files corresponding to the configuration + * structure passed as parameter. + * The first container will create the /lxc directory. + * @name : the name of the container + * @conf : the configuration data for the container + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_create(const char *name, struct lxc_conf *conf); + +/* + * Destroy the container object. Removes the files into the /lxc/ + * directory and removes the directory. + * The last container will remove the /lxc directory. + * @name : the name of the container to be detroyed + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_destroy(const char *name); + +/* + * Start the container previously created with lxc_create. + * @name : the name of the container + * @argc : the number of arguments of the command line + * @argv : an array of char * corresponding to the commande line + * @prestart : hooks will be called just before the command execs + * Returns 0 on sucess, < 0 otherwise + */ +extern int lxc_start(const char *name, int argc, char *argv[], + lxc_callback_t prestart, void *data); + +/* + * Create the container and start it directly, using the argc, argv + * parameter. This command is for application container. + * At the end of the exec'ed command, the container will + * automatically autodestroy. + * @name : the name of the container + * @conf : the configuration data + * @argc : the number of arguments of the command line + * @argv : an array of char * corresponding to the commande line + * @preexec : hooks will be called just before the command execs + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_execute(const char *name, int argc, char *argv[], + lxc_callback_t preexec, void *data); + +/* + * Stop the container previously started with lxc_start or lxc_exec + * @name : the name of the container + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_stop(const char *name); + +/* + * Monitor the container, each time the state of the container + * is changed, a state data is send through a file descriptor passed to + * the function with output_fd. + * The function will block until the container is destroyed. + * @name : the name of the contaier + * @output_fd : the file descriptor where to send the states + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_monitor(const char *name, int output_fd); + +/* + * Show the console of the container. + * @name : the name of container + * Returns 0 on sucess, < 0 otherwise + */ +extern int lxc_console(const char *name); + +/* + * Freeze all the tasks running inside the container + * @name : the container name + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_freeze(const char *name); + +/* + * Unfreeze all previously frozen tasks. + * @name : the name of the container + * Return 0 on sucess, < 0 otherwise + */ +extern int lxc_unfreeze(const char *name); + +/* + * Retrieve the container state + * @name : the name of the container + * Returns the state of the container on success, < 0 otherwise + */ +extern lxc_state_t lxc_state(const char *name); + +/* + * Send a signal to all processes of the container. This is the same + * behavior of the well-known 'killpg' command except it is related + * to all tasks belonging to a container. + * @name : the name of the container + * @signum : the signal number to be sent + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_kill(const char *name, int signum); + +/* + * Change the priority of the container + * @name : the name of the container + * @priority : an integer representing the desired priority + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_cgroup_set_priority(const char *name, int priority); + +/* + * Retrieve the priority of the container + * @name : the name of the container + * @priority : a pointer to an int where the priority will be stored + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_cgroup_get_priority(const char *name, int *priority); + +/* + * Set the maximum memory usable by the container + * @name : the name of the container + * @memmax : the maximum usable memory in bytes + * Returns 0 on sucess, < 0 otherwise + */ +extern int lxc_cgroup_set_memory(const char *name, size_t memmax); + +/* + * Get the maximum memory usable by the container + * @name : the name of the container + * @memmax : a pointer to a size_t where the value will be stored + * Returns 0 on sucess, < 0 otherwise + */ +extern int lxc_cgroup_get_memory(const char *name, size_t *memmax); + +/* + * Get the memory statistics of the container + * @name : the name of the container + * @memstat : a pointer to a structure defining the memory statistic + * Returns 0 on sucess, < 0 otherwise + */ +extern int lxc_cgroup_get_memstat(const char *name, + struct lxc_mem_stat *memstat); + +/* + * Set the cpuset for the container + * @name : the name of the container + * @cpumask : a bitmask representing the cpu maps + * @len : the len of the bitmask + * @shared : a boolean specifying if the cpu could be shared with + * processes not belonging to the container + * Returns 0 on sucess, < 0 otherwise + */ +extern int lxc_cgroup_set_cpuset(const char *name, long *cpumask, + int len, int shared); + +/* + * Get the actual cpuset for the container + * @cpumask : a bitmask representing the cpu maps + * @len : the len of the bitmask + * @shared : a boolean specifying if the cpu is shared with + * processes not belonging to the container + * Returns 0 on sucess, < 0 otherwise + */ +extern int lxc_cgroup_get_cpuset(const char *name, long *cpumask, + int len, int *shared); + +/* + * Get the cpu usage of the container + * @name : the name of the container + * @usage : a value to be filled with the current container cpu usage + * Returns 0 on sucess, < 0 otherwise + */ +extern int lxc_cgroup_get_cpu_usage(const char *name, long long *usage); + +#endif diff --git a/src/liblxc/monitor.c b/src/liblxc/monitor.c new file mode 100644 index 000000000..0670c1c53 --- /dev/null +++ b/src/liblxc/monitor.c @@ -0,0 +1,97 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +int lxc_monitor(const char *name, int output_fd) +{ + char path[MAXPATHLEN]; + int err = -1, nfd, wfd, state; + + nfd = inotify_init(); + if (nfd < 0) { + lxc_log_syserror("failed to initialize inotify"); + return -1; + } + + snprintf(path, MAXPATHLEN, LXCPATH "/%s/state", name); + + wfd = inotify_add_watch(nfd, path, IN_DELETE_SELF|IN_CLOSE_WRITE); + if (wfd < 0) { + lxc_log_syserror("failed to add a watch on %s", path); + goto out; + } + + for(;;) { + struct inotify_event evt; + + if (read(nfd, &evt, sizeof(evt)) < 0) { + lxc_log_syserror("failed to read inotify event"); + goto out; + } + + if (evt.mask & IN_CLOSE_WRITE) { + + state = lxc_getstate(name); + if (state < 0) { + lxc_log_error("failed to get the state for %s", + name); + goto out; + } + + if (write(output_fd, &state, sizeof(state)) < 0) { + lxc_log_syserror("failed to send state to %d", + output_fd); + goto out; + } + continue; + } + + if (evt.mask & IN_DELETE_SELF) { + close(output_fd); + err = 0; + goto out; + } + + lxc_log_error("unknown evt for inotity (%d)", evt.mask); + goto out; + } + +out: + inotify_rm_watch(nfd, wfd); + close(nfd); + return err; +} diff --git a/src/liblxc/namespace.h b/src/liblxc/namespace.h new file mode 100644 index 000000000..405936864 --- /dev/null +++ b/src/liblxc/namespace.h @@ -0,0 +1,71 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __namespace_h +#define __namespace_h + +#include +#ifndef CLONE_FS +# define CLONE_FS 0x00000200 +#endif +#ifndef CLONE_NEWNS +# define CLONE_NEWNS 0x00020000 +#endif +#ifndef CLONE_NEWUTS +# define CLONE_NEWUTS 0x04000000 +#endif +#ifndef CLONE_NEWIPC +# define CLONE_NEWIPC 0x08000000 +#endif +#ifndef CLONE_NEWUSER +# define CLONE_NEWUSER 0x10000000 +#endif +#ifndef CLONE_NEWPID +# define CLONE_NEWPID 0x20000000 +#endif +#ifndef CLONE_NEWNET +# define CLONE_NEWNET 0x40000000 +#endif +#ifndef __NR_unshare +# ifdef __i386__ +# define __NR_unshare 310 +# elif __x86_64__ +# define __NR_unshare 272 +# elif __ia64__ +# define __NR_unshare 1296 +# elif __s390__ +# define __NR_unshare 303 +# elif __powerpc__ +# define __NR_unshare 282 +#else +# error "unsupported architecture" +# endif +#endif +#if __i386__ || __x86_64__ || __s390__ || __powerpc__ +# define fork_ns(flags) syscall(SYS_clone, flags|SIGCHLD, NULL); +#elif __ia64__ +# define fork_ns(flags) syscall(SYS_clone2, flags|SIGCHLD, NULL); +#else +# error "unsupported architecture" +#endif +#define unshare_ns(flags) syscall(__NR_unshare, flags, NULL); +#endif diff --git a/src/liblxc/network.c b/src/liblxc/network.c new file mode 100644 index 000000000..6e1048171 --- /dev/null +++ b/src/liblxc/network.c @@ -0,0 +1,727 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _GNU_SOURCE +#include +#undef _GNU_SOURCe +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef IFLA_LINKMODE +# define IFLA_LINKMODE 17 +#endif + +#ifndef IFLA_LINKINFO +# define IFLA_LINKINFO 18 +#endif + +#ifndef IFLA_NET_NS_PID +# define IFLA_NET_NS_PID 19 +#endif + +#ifndef IFLA_INFO_KIND +# define IFLA_INFO_KIND 1 +#endif + +#ifndef IFLA_INFO_DATA +# define IFLA_INFO_DATA 2 +#endif + +#ifndef VETH_INFO_PEER +# define VETH_INFO_PEER 1 +#endif + +struct link_req { + struct nlmsg nlmsg; + struct ifinfomsg ifinfomsg; +}; + +struct ip_req { + struct nlmsg nlmsg; + struct ifaddrmsg ifa; +}; + +int device_move(const char *name, pid_t pid) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL; + struct link_req *link_req; + int index, len, err = -1; + + if (netlink_open(&nlh, NETLINK_ROUTE)) + return -1; + + len = strlen(name); + if (len == 1 || len > IFNAMSIZ) + goto out; + + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + index = if_nametoindex(name); + if (!index) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + link_req->ifinfomsg.ifi_index = index; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; + nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK; + + if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid)) + goto out; + + if (nla_put_string(nlmsg, IFLA_IFNAME, name)) + goto out; + + if (netlink_transaction(&nlh, nlmsg, nlmsg)) + goto out; + + err = 0; +out: + netlink_close(&nlh); + nlmsg_free(nlmsg); + return err; +} + +extern int device_delete(const char *name) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct link_req *link_req; + int index, len, err = -1; + + if (netlink_open(&nlh, NETLINK_ROUTE)) + return -1; + + len = strlen(name); + if (len == 1 || len > IFNAMSIZ) + goto out; + + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + index = if_nametoindex(name); + if (!index) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + link_req->ifinfomsg.ifi_index = index; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST; + nlmsg->nlmsghdr.nlmsg_type = RTM_DELLINK; + + if (nla_put_string(nlmsg, IFLA_IFNAME, name)) + goto out; + + if (netlink_transaction(&nlh, nlmsg, answer)) + goto out; + + err = 0; +out: + netlink_close(&nlh); + nlmsg_free(answer); + nlmsg_free(nlmsg); + return err; +} + +static int device_set_flag(const char *name, int flag) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct link_req *link_req; + int index, len, err = -1; + + if (netlink_open(&nlh, NETLINK_ROUTE)) + return -1; + + len = strlen(name); + if (len == 1 || len > IFNAMSIZ) + goto out; + + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + index = if_nametoindex(name); + if (!index) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + link_req->ifinfomsg.ifi_index = index; + link_req->ifinfomsg.ifi_change |= IFF_UP; + link_req->ifinfomsg.ifi_flags |= flag; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; + nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK; + + err = netlink_transaction(&nlh, nlmsg, answer); + if (err < 0) + goto out; + + err = 0; +out: + netlink_close(&nlh); + nlmsg_free(nlmsg); + nlmsg_free(answer); + return err; +} + +int device_up(const char *name) +{ + return device_set_flag(name, IFF_UP); +} + +int device_down(const char *name) +{ + return device_set_flag(name, 0); +} + +int device_rename(const char *oldname, const char *newname) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct link_req *link_req; + int index, len, err = -1; + + if (netlink_open(&nlh, NETLINK_ROUTE)) + return -1; + + len = strlen(oldname); + if (len == 1 || len > IFNAMSIZ) + goto out; + + len = strlen(newname); + if (len == 1 || len > IFNAMSIZ) + goto out; + + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + index = if_nametoindex(oldname); + if (!index) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + link_req->ifinfomsg.ifi_index = index; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST; + nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK; + + if (nla_put_string(nlmsg, IFLA_IFNAME, newname)) + goto out; + + if (netlink_transaction(&nlh, nlmsg, answer)) + goto out; + + err = 0; +out: + netlink_close(&nlh); + nlmsg_free(answer); + nlmsg_free(nlmsg); + return err; +} + +int veth_create(const char *name1, const char *name2) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct link_req *link_req; + struct rtattr *nest1, *nest2, *nest3; + int len, err = -1; + + if (netlink_open(&nlh, NETLINK_ROUTE)) + return -1; + + len = strlen(name1); + if (len == 1 || len > IFNAMSIZ) + goto out; + + len = strlen(name2); + if (len == 1 || len > IFNAMSIZ) + goto out; + + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = + NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK; + nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK; + + nest1 = nla_begin_nested(nlmsg, IFLA_LINKINFO); + if (!nest1) + goto out; + + if (nla_put_string(nlmsg, IFLA_INFO_KIND, "veth")) + goto out; + + nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA); + if (!nest2) + goto out; + + nest3 = nla_begin_nested(nlmsg, VETH_INFO_PEER); + if (!nest3) + goto out; + + nlmsg->nlmsghdr.nlmsg_len += sizeof(struct ifinfomsg); + + if (nla_put_string(nlmsg, IFLA_IFNAME, name2)) + goto out; + + nla_end_nested(nlmsg, nest3); + + nla_end_nested(nlmsg, nest2); + + nla_end_nested(nlmsg, nest1); + + if (nla_put_string(nlmsg, IFLA_IFNAME, name1)) + goto out; + + if (netlink_transaction(&nlh, nlmsg, answer)) + goto out; + + err = 0; +out: + netlink_close(&nlh); + nlmsg_free(answer); + nlmsg_free(nlmsg); + return err; +} + +int macvlan_create(const char *master, const char *name) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct link_req *link_req; + struct rtattr *nest; + int index, len, err = -1; + + if (netlink_open(&nlh, NETLINK_ROUTE)) + return -1; + + len = strlen(master); + if (len == 1 || len > IFNAMSIZ) + goto out; + + len = strlen(name); + if (len == 1 || len > IFNAMSIZ) + goto out; + + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + index = if_nametoindex(master); + if (!index) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = + NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK; + nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK; + + nest = nla_begin_nested(nlmsg, IFLA_LINKINFO); + if (!nest) + goto out; + + if (nla_put_string(nlmsg, IFLA_INFO_KIND, "macvlan")) + goto out; + + nla_end_nested(nlmsg, nest); + + if (nla_put_u32(nlmsg, IFLA_LINK, index)) + goto out; + + if (nla_put_string(nlmsg, IFLA_IFNAME, name)) + goto out; + + if (netlink_transaction(&nlh, nlmsg, answer)) + goto out; + + err = 0; +out: + netlink_close(&nlh); + nlmsg_free(answer); + nlmsg_free(nlmsg); + return err; +} + +static int proc_sys_net_write(const char *path, const char *value) +{ + int fd, err = 0; + + fd = open(path, O_WRONLY); + if (fd < 0) + return -errno; + + if (write(fd, value, strlen(value)) < 0) + err = -errno; + + close(fd); + return err; +} + +static int ip_forward_set(const char *ifname, int family, int flag) +{ + char *path; + int ret; + + if (family != AF_INET && family != AF_INET6) + return -1; + + asprintf(&path, "/proc/sys/net/%s/conf/%s/forwarding", + family == AF_INET?"ipv4":"ipv6" , ifname); + + ret = proc_sys_net_write(path, flag?"1":"0"); + free(path); + + return ret; +} + +int ip_forward_on(const char *ifname, int family) +{ + return ip_forward_set(ifname, family, 1); +} + +int ip_forward_off(const char *ifname, int family) +{ + return ip_forward_set(ifname, family, 0); +} + +static int neigh_proxy_set(const char *ifname, int family, int flag) +{ + char path[MAXPATHLEN]; + + if (family != AF_INET && family != AF_INET6) + return -1; + + sprintf(path, "/proc/sys/net/%s/conf/%s/%s", + family == AF_INET?"ipv4":"ipv6" , ifname, + family == AF_INET?"proxy_arp":"proxy_ndp"); + + return proc_sys_net_write(path, flag?"1":"0"); +} + +int neigh_proxy_on(const char *name, int family) +{ + return neigh_proxy_set(name, family, 1); +} + +int neigh_proxy_off(const char *name, int family) +{ + return neigh_proxy_set(name, family, 0); +} + +int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr) +{ + unsigned char *data; + char c; + int i = 0; + unsigned val; + + sockaddr->sa_family = ARPHRD_ETHER; + data = (unsigned char *)sockaddr->sa_data; + + while ((*macaddr != '\0') && (i < ETH_ALEN)) { + val = 0; + c = *macaddr++; + if (isdigit(c)) + val = c - '0'; + else if (c >= 'a' && c <= 'f') + val = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val = c - 'A' + 10; + else { + return -1; + } + val <<= 4; + c = *macaddr; + if (isdigit(c)) + val |= c - '0'; + else if (c >= 'a' && c <= 'f') + val |= c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val |= c - 'A' + 10; + else if (c == ':' || c == 0) + val >>= 4; + else { + return -1; + } + if (c != 0) + macaddr++; + *data++ = (unsigned char) (val & 0377); + i++; + + if (*macaddr == ':') + macaddr++; + } + + return 0; +} + +int ip_addr_add(const char *ifname, const char *addr, + int prefix, const char *bcast) +{ + struct nl_handler nlh; + struct in_addr in_addr; +/* struct in_addr in_bcast; */ + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct ip_req *ip_req; + int ifindex, err = -1; + + if (netlink_open(&nlh, NETLINK_ROUTE)) + return -1; + + if (inet_pton(AF_INET, addr, (void *)&in_addr) < 0) + goto out; + +/* if (inet_pton(AF_INET, bcast, (void *)&in_bcast) < 0) */ +/* goto out; */ + + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + ifindex = if_nametoindex(ifname); + if (!ifindex) + goto out; + + ip_req = (struct ip_req *)nlmsg; + ip_req->nlmsg.nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + ip_req->nlmsg.nlmsghdr.nlmsg_flags = + NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; + ip_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWADDR; + ip_req->ifa.ifa_prefixlen = prefix; + ip_req->ifa.ifa_index = ifindex; + ip_req->ifa.ifa_family = AF_INET; + ip_req->ifa.ifa_scope = 0; + + if (nla_put_buffer(nlmsg, IFA_LOCAL, &in_addr, sizeof(in_addr))) + goto out; + + if (nla_put_buffer(nlmsg, IFA_ADDRESS, &in_addr, sizeof(in_addr))) + goto out; + +/* if (in_bcast.s_addr != INADDR_ANY) */ +/* if (nla_put_buffer(nlmsg, IFA_BROADCAST, &in_bcast, */ +/* sizeof(in_bcast))) */ +/* goto out; */ + + if (netlink_transaction(&nlh, nlmsg, answer)) + goto out; + + err = 0; +out: + netlink_close(&nlh); + nlmsg_free(answer); + nlmsg_free(nlmsg); + return err; +} + +int ip6_addr_add(const char *ifname, const char *addr, + int prefix, const char *bcast) +{ + struct nl_handler nlh; + struct in6_addr in6_addr; +/* struct in6_addr in6_bcast; */ + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct ip_req *ip_req; + int ifindex, err = -1; + + if (netlink_open(&nlh, NETLINK_ROUTE)) + return -1; + + if (inet_pton(AF_INET6, addr, (void *)&in6_addr) < 0) + goto out; + + +/* if (inet_pton(AF_INET6, bcast, (void *)&in6_bcast) < 0) */ +/* goto out; */ + + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + ifindex = if_nametoindex(ifname); + if (!ifindex) + goto out; + + ip_req = (struct ip_req *)nlmsg; + ip_req->nlmsg.nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + ip_req->nlmsg.nlmsghdr.nlmsg_flags = + NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; + ip_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWADDR; + ip_req->ifa.ifa_prefixlen = prefix; + ip_req->ifa.ifa_index = ifindex; + ip_req->ifa.ifa_family = AF_INET6; + ip_req->ifa.ifa_scope = 0; + + if (nla_put_buffer(nlmsg, IFA_LOCAL, &in6_addr, sizeof(in6_addr))) + goto out; + + if (nla_put_buffer(nlmsg, IFA_ADDRESS, &in6_addr, sizeof(in6_addr))) + goto out; + +/* if (in6_bcast.s6_addr != in6addr_any.s6_addr) */ +/* if (nla_put_buffer(nlmsg, IFA_BROADCAST, &in6_bcast, */ +/* sizeof(in6_bcast))) */ +/* goto out; */ + + if (netlink_transaction(&nlh, nlmsg, answer)) + goto out; + + err = 0; +out: + netlink_close(&nlh); + nlmsg_free(answer); + nlmsg_free(nlmsg); + return err; +} + +static int bridge_add_del_interface(const char *bridge, + const char *ifname, int detach) +{ + int fd, index, err; + struct ifreq ifr; + + if (strlen(ifname) > IFNAMSIZ) + return -1; + + index = if_nametoindex(ifname); + if (!index) + return -1; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) + return -1; + + strncpy(ifr.ifr_name, bridge, IFNAMSIZ); + ifr.ifr_ifindex = index; + err = ioctl(fd, detach?SIOCBRDELIF:SIOCBRADDIF, &ifr); + close(fd); + + return err; +} + +int bridge_attach(const char *bridge, const char *ifname) +{ + return bridge_add_del_interface(bridge, ifname, 0); +} + +int bridge_detach(const char *bridge, const char *ifname) +{ + return bridge_add_del_interface(bridge, ifname, 1); +} + +int lxc_configure_veth(const char *veth1, const char *veth2, const char *bridge) +{ + int err = -1; + if (veth_create(veth1, veth2)) { + fprintf(stderr, "failed to create veth interfaces %s/%s\n", + veth1, veth2); + return -1; + } + + if (bridge_attach(bridge, veth1)) { + fprintf(stderr, "failed to attach %s to %s\n", + veth1, bridge); + goto err; + } + + err = 0; +out: + return err; +err: + device_delete(veth1); + goto out; +} + +int lxc_configure_macvlan(const char *link, const char *peer) +{ + if (macvlan_create(link, peer)) { + fprintf(stderr, "failed to create %s", peer); + return -1; + } + return 0; +} diff --git a/src/liblxc/network.h b/src/liblxc/network.h new file mode 100644 index 000000000..223276ef7 --- /dev/null +++ b/src/liblxc/network.h @@ -0,0 +1,126 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _network_h +#define _network_h + +/* + * Create a macvlan network device + */ +extern int lxc_configure_macvlan(const char *link, const char *peer); + +/* + * Create a veth pair virtual device + */ +extern int lxc_configure_veth(const char *veth1, const char *veth2, + const char *bridge); + +/* + * Convert a string mac address to a socket structure + */ +extern int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr); + +/* + * Move a device between namespaces + */ +extern int device_move(const char *name, pid_t pid); + +/* + * Delete a network device + */ +extern int device_delete(const char *name); + +/* + * Set the device network up + */ +extern int device_up(const char *name); + +/* + * Set the device network down + */ +extern int device_down(const char *name); + +/* + * Change the device name + */ +extern int device_rename(const char *oldname, const char *newname); + +/* + * Create a veth network device + */ +extern int veth_create(const char *name1, const char *name2); + +/* + * Create a macvlan network device + */ +extern int macvlan_create(const char *master, const char *name); + +/* + * Activate forwarding + */ +extern int ip_forward_on(const char *name, int family); + +/* + * Disable forwarding + */ +extern int ip_forward_off(const char *name, int family); + +/* + * Set ip address + */ +extern int ip_addr_add(const char *ifname, const char *addr, + int prefix, const char *bcast); + +extern int ip6_addr_add(const char *ifname, const char *addr, + int prefix, const char *bcast); + +/* + * Attach an interface to the bridge + */ +extern int bridge_attach(const char *bridge, const char *ifname); + +/* + * Detach an interface from the bridge + */ +extern int bridge_detach(const char *bridge, const char *ifname); + +/* + * Create default gateway + */ +extern int route_create_default(const char *addr, const char *ifname, int gateway); + +/* + * Delete default gateway + */ +extern int route_delete_default(const char *addr, const char *ifname, int gateway); + +/* + * Activate neighbor proxying + */ +extern int neigh_proxy_on(const char *name, int family); + +/* + * Disable neighbor proxying + */ +extern int neigh_proxy_off(const char *name, int family); + +#endif diff --git a/src/liblxc/nl.c b/src/liblxc/nl.c new file mode 100644 index 000000000..261ffb527 --- /dev/null +++ b/src/liblxc/nl.c @@ -0,0 +1,260 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) + +extern size_t nlmsg_len(const struct nlmsg *nlmsg) +{ + return nlmsg->nlmsghdr.nlmsg_len - NLMSG_HDRLEN; +} + +extern void *nlmsg_data(struct nlmsg *nlmsg) +{ + char *data = ((char *)nlmsg) + NLMSG_ALIGN(sizeof(struct nlmsghdr)); + if (!nlmsg_len(nlmsg)) + return NULL; + return data; +} + +static int nla_put(struct nlmsg *nlmsg, int attr, + const void *data, size_t len) +{ + struct rtattr *rta; + size_t rtalen = RTA_LENGTH(len); + + rta = NLMSG_TAIL(&nlmsg->nlmsghdr); + rta->rta_type = attr; + rta->rta_len = rtalen; + memcpy(RTA_DATA(rta), data, len); + nlmsg->nlmsghdr.nlmsg_len = + NLMSG_ALIGN(nlmsg->nlmsghdr.nlmsg_len) + RTA_ALIGN(rtalen); + return 0; +} + +extern int nla_put_buffer(struct nlmsg *nlmsg, int attr, + const void *data, size_t size) +{ + return nla_put(nlmsg, attr, data, size); +} + +extern int nla_put_string(struct nlmsg *nlmsg, int attr, const char *string) +{ + return nla_put(nlmsg, attr, string, strlen(string) + 1); +} + +extern int nla_put_u32(struct nlmsg *nlmsg, int attr, int value) +{ + return nla_put(nlmsg, attr, &value, sizeof(value)); +} + +extern int nla_put_attr(struct nlmsg *nlmsg, int attr) +{ + return nla_put(nlmsg, attr, NULL, 0); +} + +struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr) +{ + struct rtattr *rtattr = NLMSG_TAIL(&nlmsg->nlmsghdr); + + if (nla_put_attr(nlmsg, attr)) + return NULL; + + return rtattr; +} + +void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr) +{ + attr->rta_len = (void *)NLMSG_TAIL(&nlmsg->nlmsghdr) - (void *)attr; +} + +extern struct nlmsg *nlmsg_alloc(size_t size) +{ + struct nlmsg *nlmsg; + size_t len = NLMSG_ALIGN(size) + NLMSG_ALIGN(sizeof(struct nlmsghdr *)); + + nlmsg = (struct nlmsg *)malloc(len); + if (!nlmsg) + return NULL; + + memset(nlmsg, 0, len); + nlmsg->nlmsghdr.nlmsg_len = NLMSG_ALIGN(size); + + return nlmsg; +} + +extern void nlmsg_free(struct nlmsg *nlmsg) +{ + free(nlmsg); +} + +extern int netlink_rcv(struct nl_handler *handler, struct nlmsg *answer) +{ + int ret; + struct sockaddr_nl nladdr; + struct iovec iov = { + .iov_base = answer, + .iov_len = answer->nlmsghdr.nlmsg_len, + }; + + struct msghdr msg = { + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + + memset(&nladdr, 0, sizeof(nladdr)); + nladdr.nl_family = AF_NETLINK; + nladdr.nl_pid = 0; + nladdr.nl_groups = 0; + +again: + ret = recvmsg(handler->fd, &msg, 0); + if (ret < 0) { + if (errno == EINTR) + goto again; + return -errno; + } + + if (!ret) + return 0; + + if (msg.msg_flags & MSG_TRUNC) + return -EMSGSIZE; + + return ret; +} + +extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg) +{ + struct sockaddr_nl nladdr; + struct iovec iov = { + .iov_base = (void*)nlmsg, + .iov_len = nlmsg->nlmsghdr.nlmsg_len, + }; + struct msghdr msg = { + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + int ret; + + memset(&nladdr, 0, sizeof(nladdr)); + nladdr.nl_family = AF_NETLINK; + nladdr.nl_pid = 0; + nladdr.nl_groups = 0; + + ret = sendmsg(handler->fd, &msg, 0); + if (ret < 0) { + return -errno; + } + + return ret; +} + +extern int netlink_transaction(struct nl_handler *handler, + struct nlmsg *request, struct nlmsg *answer) +{ + + int ret; + + ret = netlink_send(handler, request); + if (ret < 0) + return ret; + + ret = netlink_rcv(handler, answer); + if (ret < 0) + return ret; + + if (answer->nlmsghdr.nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(answer); + errno = -err->error; + return -errno; + } + + return 0; +} + +extern int netlink_open(struct nl_handler *handler, int protocol) +{ + socklen_t socklen; + int sndbuf = 32768; + int rcvbuf = 32768; + + memset(handler, 0, sizeof(*handler)); + + handler->fd = socket(AF_NETLINK, SOCK_RAW, protocol); + if (handler->fd < 0) + return -errno; + + if (setsockopt(handler->fd, SOL_SOCKET, SO_SNDBUF, + &sndbuf, sizeof(sndbuf)) < 0) + return -errno; + + if (setsockopt(handler->fd, SOL_SOCKET, SO_RCVBUF, + &rcvbuf,sizeof(rcvbuf)) < 0) + return -errno; + + memset(&handler->local, 0, sizeof(handler->local)); + handler->local.nl_family = AF_NETLINK; + handler->local.nl_groups = 0; + + if (bind(handler->fd, (struct sockaddr*)&handler->local, + sizeof(handler->local)) < 0) + return -errno; + + socklen = sizeof(handler->local); + if (getsockname(handler->fd, (struct sockaddr*)&handler->local, + &socklen) < 0) + return -errno; + + if (socklen != sizeof(handler->local)) + return -EINVAL; + + if (handler->local.nl_family != AF_NETLINK) + return -EINVAL; + + handler->seq = time(NULL); + + return 0; +} + +extern int netlink_close(struct nl_handler *handler) +{ + close(handler->fd); + handler->fd = -1; + return 0; +} + diff --git a/src/liblxc/nl.h b/src/liblxc/nl.h new file mode 100644 index 000000000..2f760de2c --- /dev/null +++ b/src/liblxc/nl.h @@ -0,0 +1,228 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __nl_h +#define __nl_h + +/* + * Use this as a good size to allocate generic netlink messages + */ +#ifndef PAGE_SIZE +#define PAGE_SIZE 4096 +#endif +#define NLMSG_GOOD_SIZE (2*PAGE_SIZE) +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) +#define NLA_DATA(na) ((void *)((char*)(na) + NLA_HDRLEN)) +#define NLA_NEXT_ATTR(attr) ((void *)((char *)attr) + NLA_ALIGN(attr->nla_len)) + +/* + * struct nl_handler : the handler for netlink sockets, this structure + * is used all along the netlink socket life cycle to specify the + * netlink socket to be used. + * + * @fd: the file descriptor of the netlink socket + * @seq: the sequence number of the netlink messages + * @local: the bind address + * @peer: the peer address + */ +struct nl_handler { + int fd; + int seq; + struct sockaddr_nl local; + struct sockaddr_nl peer; +}; + +/* + * struct nlmsg : the netlink message structure, it consists just + * on a definition for a nlmsghdr. This message is to be used to + * be allocated with netlink_alloc. + * @nlmsghdr : a pointer to a netlink message header, this field + * _must_ be always the first field of this structure + */ +struct nlmsg { + struct nlmsghdr nlmsghdr; +}; + +/* + * netlink_open : open a netlink socket, the function will + * fill the handler with the right value + * + * @handler: a netlink handler to be used all along the netlink + * socket life cycle + * @protocol: specify the protocol to be used when opening the + * netlink socket + * + * Return 0 on success, < 0 otherwise + */ +int netlink_open(struct nl_handler *handler, int protocol); + +/* + * netlink_close : close a netlink socket, after this call, + * the handler is no longer valid + * + * @handler: a handler to the netlink socket + * + * Returns 0 on success, < 0 otherwise + */ +int netlink_close(struct nl_handler *handler); + +/* + * netlink_rcv : receive a netlink message from the kernel. + * It is up to the caller to manage the allocation of the + * netlink message + * + * @handler: a handler to the netlink socket + * @nlmsg: a netlink message + * + * Returns 0 on success, < 0 otherwise + */ +int netlink_rcv(struct nl_handler *handler, struct nlmsg *nlmsg); + +/* + * netlink_send: send a netlink message to the kernel. It is up + * to the caller to manage the allocate of the netlink message + * + * @handler: a handler to the netlink socket + * @nlmsg: a netlink message + * + * Returns 0 on success, < 0 otherwise + */ +int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg); + +/* + * netlink_transaction: send a request to the kernel and read the response. + * This is useful for transactional protocol. It is up to the caller + * to manage the allocation of the netlink message. + * + * @handler: a handler to a opened netlink socket + * @request: a netlink message pointer containing the request + * @answer: a netlink message pointer to receive the result + * + * Returns 0 on success, < 0 otherwise + */ +int netlink_transaction(struct nl_handler *handler, + struct nlmsg *request, struct nlmsg *anwser); + +/* + * nla_put_string: copy a null terminated string to a netlink message + * attribute + * + * @nlmsg: the netlink message to be filled + * @attr: the attribute name of the string + * @string: a null terminated string to be copied to the netlink message + * + * Returns 0 on success, < 0 otherwise + */ +int nla_put_string(struct nlmsg *nlmsg, int attr, const char *string); + +/* + * nla_put_buffer: copy a buffer with a specified size to a netlink + * message attribute + * + * @nlmsg: the netlink message to be filled + * @attr: the attribute name of the string + * @data: a pointer to a buffer + * @size: the size of the buffer + * + * Returns 0 on success, < 0 otherwise + */ +int nla_put_buffer(struct nlmsg *nlmsg, int attr, + const void *data, size_t size); + +/* + * nla_put_u32: copy an integer to a netlink message attribute + * + * @nlmsg: the netlink message to be filled + * @attr: the attribute name of the integer + * @string: an integer to be copied to the netlink message + * + * Returns 0 on success, < 0 otherwise + */ +int nla_put_u32(struct nlmsg *nlmsg, int attr, int value); + +/* + * nla_put_attr: add an attribute name to a netlink + * + * @nlmsg: the netlink message to be filled + * @attr: the attribute name of the integer + * + * Returns 0 on success, < 0 otherwise + */ +int nla_put_attr(struct nlmsg *nlmsg, int attr); + +/* + * nla_begin_nested: begin the nesting attribute + * + * @nlmsg: the netlink message to be filled + * @attr: the netsted attribute name + * + * Returns current nested pointer to be reused + * to nla_end_nested. + */ +struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr); + +/* + * nla_end_nested: end the nesting attribute + * + * @nlmsg: the netlink message + * @nested: the nested pointer + * + * Returns the current + */ +void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr); + +/* + * nlmsg_allocate : allocate a netlink message. The netlink format message + * is a header, a padding, a payload and a padding again. + * When a netlink message is allocated, the size specify the + * payload we want. So the real size of the allocated message + * is sizeof(header) + sizeof(padding) + payloadsize + sizeof(padding), + * in other words, the function will allocate more than specified. When + * the buffer is allocated, the content is zeroed. + * The function will also fill the field nlmsg_len with computed size. + * If the allocation must be for the specified size, just use malloc. + * + * @size: the size of the payload to be allocated + * + * Returns a pointer to the newly allocated netlink message, NULL otherwise + */ +struct nlmsg *nlmsg_alloc(size_t size); + +/* + * nlmsg_free : free a previously allocate message + * + * @nlmsg: the netlink message to be freed + */ +void nlmsg_free(struct nlmsg *nlmsg); + +/* + * nlmsg_data : returns a pointer to the data contained in the netlink message + * + * @nlmsg : the netlink message to get the data + * + * Returns a pointer to the netlink data or NULL if there is no data + */ +void *nlmsg_data(struct nlmsg *nlmsg); + + +#endif diff --git a/src/liblxc/rtnl.c b/src/liblxc/rtnl.c new file mode 100644 index 000000000..bc2354287 --- /dev/null +++ b/src/liblxc/rtnl.c @@ -0,0 +1,72 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int rtnetlink_open(struct rtnl_handler *handler) +{ + return netlink_open(&handler->nlh, NETLINK_ROUTE); +} + +extern int rtnetlink_close(struct rtnl_handler *handler) +{ + return netlink_close(&handler->nlh); +} + +extern int rtnetlink_rcv(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg) +{ + return netlink_rcv(&handler->nlh, (struct nlmsg *)&rtnlmsg->nlmsghdr); +} + +extern int rtnetlink_send(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg) +{ + + return netlink_send(&handler->nlh, (struct nlmsg *)&rtnlmsg->nlmsghdr); +} + +extern int rtnetlink_transaction(struct rtnl_handler *handler, + struct rtnlmsg *request, struct rtnlmsg *answer) +{ + return netlink_transaction(&handler->nlh, (struct nlmsg *)&request->nlmsghdr, + (struct nlmsg *)&answer->nlmsghdr); +} + +extern struct rtnlmsg *rtnlmsg_alloc(size_t size) +{ +/* size_t len = NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct rtnlmsghdr))) + size; */ +/* return (struct rtnlmsg *)nlmsg_alloc(len); */ + return NULL; +} + +extern void rtnlmsg_free(struct rtnlmsg *rtnlmsg) +{ + free(rtnlmsg); +} diff --git a/src/liblxc/rtnl.h b/src/liblxc/rtnl.h new file mode 100644 index 000000000..63aca0ad8 --- /dev/null +++ b/src/liblxc/rtnl.h @@ -0,0 +1,110 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __genl_h +#define __genl_h + +/* + * Use this as a good size to allocate route netlink messages + */ +#define RTNLMSG_GOOD_SIZE NLMSG_GOOD_SIZE +#define RTNLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + RTNL_HDRLEN)) + +/* + * struct genl_handler : the structure which store the netlink handler + * and the family number + * + * @nlh: the netlink socket handler + */ +struct rtnl_handler +{ + struct nl_handler nlh; +}; + +/* + * struct rtnlmsg : the struct containing the route netlink message + * format + * + * @nlmsghdr: a netlink message header + * @rtnlmsghdr: a route netlink message header pointer + * + */ +struct rtnlmsg { + struct nlmsghdr nlmsghdr; +}; + +/* + * rtnetlink_open : open a route netlink socket + * + * @handler: a struct rtnl_handler pointer + * + * Returns 0 on success, < 0 otherwise + */ +int rtnetlink_open(struct rtnl_handler *handler); + +/* + * genetlink_close : close a route netlink socket + * + * @handler: the handler of the socket to be closed + * + * Returns 0 on success, < 0 otherwise + */ +int rtnetlink_close(struct rtnl_handler *handler); + +/* + * rtnetlink_rcv : receive a route netlink socket, it is up + * to the caller to manage the allocation of the route netlink message + * + * @handler: the handler of the route netlink socket + * @rtnlmsg: the pointer to a route netlink message pre-allocated + * + * Returns 0 on success, < 0 otherwise + */ +int rtnetlink_rcv(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg); + +/* + * rtnetlink_send : send a route netlink socket, it is up + * to the caller to manage the allocation of the route netlink message + * + * @handler: the handler of the route netlink socket + * @rtnlmsg: the pointer to a netlink message pre-allocated + * + * Returns 0 on success, < 0 otherwise + */ +int rtnetlink_send(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg); + +struct genlmsg *genlmsg_alloc(size_t size); + +void rtnlmsg_free(struct rtnlmsg *rtnlmsg); + +/* + * rtnetlink_transaction : send and receive a route netlink message in one shot + * + * @handler: the handler of the route netlink socket + * @request: a route netlink message containing the request to be sent + * @answer: a pre-allocated route netlink message to receive the response + * + * Returns 0 on success, < 0 otherwise + */ +int rtnetlink_transaction(struct rtnl_handler *handler, + struct rtnlmsg *request, struct rtnlmsg *answer); +#endif diff --git a/src/liblxc/start.c b/src/liblxc/start.c new file mode 100644 index 000000000..19b9b8c11 --- /dev/null +++ b/src/liblxc/start.c @@ -0,0 +1,261 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LXC_TTY_HANDLER(SIGINT); +LXC_TTY_HANDLER(SIGQUIT); + +int lxc_start(const char *name, int argc, char *argv[], + lxc_callback_t prestart, void *data) +{ + char *init = NULL, *val = NULL; + int fd, lock, sv[2], sync = 0, err = -1; + pid_t pid; + int clone_flags; + + lock = lxc_get_lock(name); + if (!lock) { + lxc_log_error("'%s' is busy", name); + return -1; + } + + if (lock < 0) { + lxc_log_error("failed to acquire lock on '%s':%s", + name, strerror(-lock)); + return -1; + } + + fcntl(lock, F_SETFD, FD_CLOEXEC); + + /* Begin the set the state to STARTING*/ + if (lxc_setstate(name, STARTING)) { + lxc_log_error("failed to set state %s", state2str(STARTING)); + goto out; + } + + /* Synchro socketpair */ + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) { + lxc_log_syserror("failed to create communication socketpair"); + goto err; + } + + /* Avoid signals from terminal */ + LXC_TTY_ADD_HANDLER(SIGINT); + LXC_TTY_ADD_HANDLER(SIGQUIT); + + clone_flags = CLONE_NEWPID|CLONE_NEWIPC; + if (conf_has_fstab(name)) + clone_flags |= CLONE_NEWNS; + if (conf_has_utsname(name)) + clone_flags |= CLONE_NEWUTS; + if (conf_has_network(name)) + clone_flags |= CLONE_NEWNET; + + /* Create a process in a new set of namespaces */ + pid = fork_ns(clone_flags); + if (pid < 0) { + lxc_log_syserror("failed to fork into a new namespace"); + goto err_fork_ns; + } + + if (!pid) { + + close(sv[1]); + + /* Be sure we don't inherit this after the exec */ + fcntl(sv[0], F_SETFD, FD_CLOEXEC); + + /* Tell our father he can begin to configure the container */ + if (write(sv[0], &sync, sizeof(sync)) < 0) { + lxc_log_syserror("failed to write socket"); + return 1; + } + + /* Wait for the father to finish the configuration */ + if (read(sv[0], &sync, sizeof(sync)) < 0) { + lxc_log_syserror("failed to read socket"); + return 1; + } + + /* Setup the container, ip, names, utsname, ... */ + if (lxc_setup(name)) { + lxc_log_error("failed to setup the container"); + if (write(sv[0], &sync, sizeof(sync)) < 0) + lxc_log_syserror("failed to write the socket"); + return -1; + } + + /* If a callback has been passed, call it before doing exec */ + if (prestart) + if (prestart(name, argc, argv, data)) { + lxc_log_error("prestart callback has failed"); + return -1; + } + + execvp(argv[0], argv); + lxc_log_syserror("failed to exec %s", argv[0]); + + /* If the exec fails, tell that to our father */ + if (write(sv[0], &sync, sizeof(sync)) < 0) + lxc_log_syserror("failed to write the socket"); + + return 1; + } + + close(sv[0]); + + /* Wait for the child to be ready */ + if (read(sv[1], &sync, sizeof(sync)) < 0) { + lxc_log_syserror("failed to read the socket"); + goto err_pipe_read; + } + + /* Create the network configuration */ + if (clone_flags & CLONE_NEWNET && conf_create_network(name, pid)) { + lxc_log_error("failed to create the configured network"); + goto err_create_network; + } + + /* Tell the child to continue its initialization */ + if (write(sv[1], &sync, sizeof(sync)) < 0) { + lxc_log_syserror("failed to write the socket"); + goto err_pipe_write; + } + + /* Wait for the child to exec or returning an error */ + err = read(sv[1], &sync, sizeof(sync)); + if (err < 0) { + lxc_log_error("failed to read the socket"); + goto err_pipe_read2; + } + + if (err > 0) { + lxc_log_error("something went wrong with %d", pid); + /* TODO : check status etc ... */ + waitpid(pid, NULL, 0); + goto err_child_failed; + } + + asprintf(&val, "%d\n", pid); + asprintf(&init, LXCPATH "/%s/init", name); + fd = open(init, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); + if (fd < 0) { + lxc_log_syserror("failed to open '%s'", init); + goto err_write; + } + + if (write(fd, val, strlen(val)) < 0) { + lxc_log_syserror("failed to write the init pid"); + goto err_write; + } + + close(fd); + + if (lxc_link_nsgroup(name, pid)) + lxc_log_warning("cgroupfs not found: cgroup disabled"); + + if (lxc_setstate(name, RUNNING)) { + lxc_log_error("failed to set state to %s", state2str(RUNNING)); + goto err_state_failed; + } + +wait_again: + if (waitpid(pid, NULL, 0) < 0) { + if (errno == EINTR) + goto wait_again; + lxc_log_syserror("failed to wait the pid %d", pid); + goto err_waitpid_failed; + } + + if (lxc_setstate(name, STOPPING)) + lxc_log_error("failed to set state %s", state2str(STOPPING)); + + if (clone_flags & CLONE_NEWNET && conf_destroy_network(name)) + lxc_log_error("failed to destroy the network"); + + err = 0; +out: + if (lxc_setstate(name, STOPPED)) + lxc_log_error("failed to set state %s", state2str(STOPPED)); + + lxc_unlink_nsgroup(name); + unlink(init); + free(init); + free(val); + lxc_put_lock(lock); + + return err; + +err_write: + close(fd); + +err_state_failed: +err_child_failed: +err_pipe_read2: +err_pipe_write: + if (clone_flags & CLONE_NEWNET) + conf_destroy_network(name); +err_create_network: +err_pipe_read: +err_waitpid_failed: + if (lxc_setstate(name, ABORTING)) + lxc_log_error("failed to set state %s", state2str(STOPPED)); + + kill(pid, SIGKILL); +err_fork_ns: + LXC_TTY_DEL_HANDLER(SIGQUIT); + LXC_TTY_DEL_HANDLER(SIGINT); + close(sv[0]); + close(sv[1]); +err: + goto out; +} diff --git a/src/liblxc/state.c b/src/liblxc/state.c new file mode 100644 index 000000000..81dbd2bea --- /dev/null +++ b/src/liblxc/state.c @@ -0,0 +1,193 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static char *strstate[] = { + "STOPPED", "STARTING", "RUNNING", "STOPPING", + "ABORTING", "FREEZING", "FROZEN", +}; + +const char *state2str(lxc_state_t state) +{ + if (state < STOPPED || state > MAX_STATE - 1) + return NULL; + return strstate[state]; +} + +lxc_state_t str2state(const char *state) +{ + int i, len; + len = sizeof(strstate)/sizeof(strstate[0]); + for (i = 0; i < len; i++) + if (!strcmp(strstate[i], state)) + return i; + return -1; +} + +int lxc_setstate(const char *name, lxc_state_t state) +{ + int fd, err; + char file[MAXPATHLEN]; + const char *str = state2str(state); + + if (!str) + return -1; + + snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name); + + fd = open(file, O_WRONLY); + if (fd < 0) { + lxc_log_syserror("failed to open %s file", file); + return -1; + } + + if (flock(fd, LOCK_EX)) { + lxc_log_syserror("failed to take the lock to %s", file); + goto out; + } + + if (ftruncate(fd, 0)) { + lxc_log_syserror("failed to truncate the file %s", file); + goto out; + } + + if (write(fd, str, strlen(str)) < 0) { + lxc_log_syserror("failed to write state to %s", file); + goto out; + } + + err = 0; +out: + close(fd); + + /* let the event to be propagated, crappy but that works, + * otherwise the events will be folded into only one event, + * and I want to have them to be one by one in order + * to follow the different states of the container. + */ + usleep(200000); + + return -err; +} + +int mkstate(const char *name) +{ + int fd; + char file[MAXPATHLEN]; + + snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name); + fd = creat(file, S_IRUSR|S_IWUSR); + if (fd < 0) { + lxc_log_syserror("failed to create file %s", file); + return -1; + } + close(fd); + return 0; +} + +int rmstate(const char *name) +{ + char file[MAXPATHLEN]; + snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name); + unlink(file); + return 0; +} + +lxc_state_t lxc_getstate(const char *name) +{ + int fd, err; + char file[MAXPATHLEN]; + + snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name); + + fd = open(file, O_RDONLY); + if (fd < 0) { + lxc_log_syserror("failed to open %s", file); + return -1; + } + + if (flock(fd, LOCK_SH)) { + lxc_log_syserror("failed to take the lock to %s", file); + close(fd); + return -1; + } + + err = read(fd, file, strlen(file)); + if (err < 0) { + lxc_log_syserror("failed to read file %s", file); + close(fd); + return -1; + } + file[err] = '\0'; + + close(fd); + return str2state(file); +} + +static int freezer_state(const char *name) +{ + char freezer[MAXPATHLEN]; + char status[MAXPATHLEN]; + FILE *file; + int err; + + snprintf(freezer, MAXPATHLEN, + LXCPATH "/%s/freezer.freeze", name); + + file = fopen(freezer, "r"); + if (file < 0) { + lxc_log_syserror("failed to open %s", freezer); + return -1; + } + + err = fscanf(file, "%s", status); + fclose(file); + + if (err == EOF) { + lxc_log_syserror("failed to read %s", freezer); + return -1; + } + + return str2state(status); +} + +lxc_state_t lxc_state(const char *name) +{ + int state = freezer_state(name); + if (state != FROZEN && state != FREEZING) + state = lxc_getstate(name); + return state; +} diff --git a/src/liblxc/state.h b/src/liblxc/state.h new file mode 100644 index 000000000..b5242a641 --- /dev/null +++ b/src/liblxc/state.h @@ -0,0 +1,33 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _state_h +#define _state_h + +extern const char *state2str(lxc_state_t state); +extern lxc_state_t str2state(const char *state); +extern int mkstate(const char *name); +extern int rmstate(const char *name); +extern int lxc_setstate(const char *name, lxc_state_t state); +extern lxc_state_t lxc_getstate(const char *name); + +#endif diff --git a/src/liblxc/stop.c b/src/liblxc/stop.c new file mode 100644 index 000000000..74372acd6 --- /dev/null +++ b/src/liblxc/stop.c @@ -0,0 +1,95 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +int lxc_stop(const char *name) +{ + char *init; + char val[MAXPIDLEN]; + int fd, lock, ret = -1; + size_t pid; + + lock = lxc_get_lock(name); + if (lock > 0) { + lxc_log_error("'%s' is not running", name); + lxc_put_lock(lock); + return -1; + } + + if (lock < 0) { + lxc_log_error("failed to acquire the lock on '%s':%s", + name, strerror(-lock)); + return -1; + } + + asprintf(&init, LXCPATH "/%s/init", name); + fd = open(init, O_RDONLY); + if (fd < 0) { + lxc_log_syserror("failed to open init file for %s", name); + goto out_free; + } + + if (read(fd, val, sizeof(val)) < 0) { + lxc_log_syserror("failed to read %s", init); + goto out_close; + } + + pid = atoi(val); + + if (kill(pid, SIGKILL)) { + lxc_log_syserror("failed to kill %zd", pid); + goto out_close; + } + + if (unlink(init)) { + lxc_log_syserror("failed to unlink %s", init); + goto out_close; + } + + ret = 0; + +out_close: + close(fd); +out_free: + free(init); + return ret; +} diff --git a/src/liblxc/utils.h b/src/liblxc/utils.h new file mode 100644 index 000000000..5fc3946fb --- /dev/null +++ b/src/liblxc/utils.h @@ -0,0 +1,51 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _utils_h +#define _utils_h + +#define LXC_TTY_HANDLER(s) \ + static struct sigaction lxc_tty_sa_##s; \ + static void tty_##s##_handler(int sig, siginfo_t *info, void *ctx) \ + { \ + if (lxc_tty_sa_##s.sa_handler == SIG_DFL || \ + lxc_tty_sa_##s.sa_handler == SIG_IGN) \ + return; \ + (*lxc_tty_sa_##s.sa_sigaction)(sig, info, ctx); \ + } + +#define LXC_TTY_ADD_HANDLER(s) \ + do { \ + struct sigaction sa; \ + sa.sa_sigaction = tty_##s##_handler; \ + sa.sa_flags = SA_SIGINFO; \ + sigfillset(&sa.sa_mask); \ + /* No error expected with sigaction. */ \ + sigaction(s, &sa, &lxc_tty_sa_##s); \ + } while (0) + +#define LXC_TTY_DEL_HANDLER(s) \ + do { \ + sigaction(s, &lxc_tty_sa_##s, NULL); \ + } while (0) + +#endif diff --git a/src/lxc/.cvsignore b/src/lxc/.cvsignore new file mode 100644 index 000000000..62a975b4c --- /dev/null +++ b/src/lxc/.cvsignore @@ -0,0 +1,15 @@ +.deps +Makefile +Makefile.in +lxc-console +lxc-create +lxc-destroy +lxc-execute +lxc-freeze +lxc-kill +lxc-monitor +lxc-start +lxc-state +lxc-stop +lxc-unfreeze +lxc-ps diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am new file mode 100644 index 000000000..b88040fdd --- /dev/null +++ b/src/lxc/Makefile.am @@ -0,0 +1,61 @@ +INCLUDES= -I$(top_srcdir)/src/liblxc + +bin_SCRIPTS = \ + lxc-ps + +bin_PROGRAMS = \ + lxc-create \ + lxc-destroy \ + lxc-stop \ + lxc-start \ + lxc-execute \ + lxc-monitor \ + lxc-console \ + lxc-state \ + lxc-kill \ + lxc-freeze \ + lxc-unfreeze + +lxc_create_SOURCES = lxc_create.c config.c config.h +lxc_create_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_destroy_SOURCES = lxc_destroy.c +lxc_destroy_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_start_SOURCES = lxc_start.c +lxc_start_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_stop_SOURCES = lxc_stop.c +lxc_stop_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_execute_SOURCES = lxc_execute.c config.c +lxc_execute_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_monitor_SOURCES = lxc_monitor.c +lxc_monitor_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_console_SOURCES = lxc_console.c +lxc_console_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_state_SOURCES = lxc_state.c +lxc_state_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_kill_SOURCES = lxc_kill.c +lxc_kill_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_freeze_SOURCES = lxc_freeze.c +lxc_freeze_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_unfreeze_SOURCES = lxc_unfreeze.c +lxc_unfreeze_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a diff --git a/src/lxc/config.c b/src/lxc/config.c new file mode 100644 index 000000000..16c53f4f3 --- /dev/null +++ b/src/lxc/config.c @@ -0,0 +1,550 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +typedef int (*file_cb)(char* buffer, void *data); +typedef int (*config_cb)(char *value, struct lxc_conf *lxc_conf); + +static int config_mount(char *, struct lxc_conf *); +static int config_chroot(char *, struct lxc_conf *); +static int config_utsname(char *, struct lxc_conf *); +static int config_network_type(char *, struct lxc_conf *); +static int config_network_flags(char *, struct lxc_conf *); +static int config_network_link(char *, struct lxc_conf *); +static int config_network_name(char *, struct lxc_conf *); +static int config_network_hwaddr(char *, struct lxc_conf *); +static int config_network_ipv4(char *, struct lxc_conf *); +static int config_network_ipv6(char *, struct lxc_conf *); + +struct config { + char *name; + int type; + config_cb cb; +}; + +enum { MOUNT, CHROOT, UTSNAME, NETTYPE, NETFLAGS, NETLINK, + NETNAME, NETHWADDR, NETIPV4, NETIPV6 }; + +struct config config[] = { + { "lxc.mount", MOUNT, config_mount }, + { "lxc.chroot", CHROOT, config_chroot }, + { "lxc.utsname", UTSNAME, config_utsname }, + { "lxc.network.type", NETTYPE, config_network_type }, + { "lxc.network.flags", NETFLAGS, config_network_flags }, + { "lxc.network.link", NETLINK, config_network_link }, + { "lxc.network.name", NETNAME, config_network_name }, + { "lxc.network.hwaddr", NETHWADDR, config_network_hwaddr }, + { "lxc.network.ipv4", NETIPV4, config_network_ipv4 }, + { "lxc.network.ipv6", NETIPV6, config_network_ipv6 }, +}; + +static const size_t config_size = sizeof(config)/sizeof(struct config); + +static struct config *getconfig(const char *key) +{ + int i; + + for (i = 0; i < config_size; i++) + if (!strncmp(config[i].name, key, + strlen(config[i].name))) + return &config[i]; + return NULL; +} + +static int is_line_empty(char *line) +{ + int i; + size_t len = strlen(line); + + for (i = 0; i < len; i++) + if (line[i] != ' ' && line[i] != '\t' && + line[i] != '\n' && line[i] != '\r' && + line[i] != '\f' && line[i] != '\0') + return 0; + return 1; +} + +static int char_left_gc(char *buffer, size_t len) +{ + int i; + for (i = 0; i < len; i++) { + if (buffer[i] == ' ' || + buffer[i] == '\t') + continue; + return i; + } + return 0; +} + +static int char_right_gc(char *buffer, size_t len) +{ + int i; + for (i = len - 1; i >= 0; i--) { + if (buffer[i] == ' ' || + buffer[i] == '\t' || + buffer[i] == '\n' || + buffer[i] == '\0') + continue; + return i + 1; + } + return 0; +} + +static int config_network_type(char *value, struct lxc_conf *lxc_conf) +{ + struct list *networks = &lxc_conf->networks; + struct network *network; + struct netdev *netdev; + struct list *list; + struct list *ndlist; + + network = malloc(sizeof(*network)); + if (!network) { + lxc_log_syserror("failed to allocate memory"); + return -1; + } + + list_init(&network->netdev); + + netdev = malloc(sizeof(*netdev)); + if (!netdev) { + lxc_log_syserror("failed to allocate memory"); + return -1; + } + + list_init(&netdev->ipv4); + list_init(&netdev->ipv6); + list_init(&netdev->route4); + list_init(&netdev->route6); + + ndlist = malloc(sizeof(*ndlist)); + if (!ndlist) { + lxc_log_syserror("failed to allocate memory"); + return -1; + } + + ndlist->elem = netdev; + + list_add(&network->netdev, ndlist); + + list = malloc(sizeof(*list)); + if (!list) { + lxc_log_syserror("failed to allocate memory"); + return -1; + } + + list_init(list); + list->elem = network; + + list_add(networks, list); + + if (!strcmp(value, "veth")) + network->type = VETH; + else if (!strcmp(value, "macvlan")) + network->type = MACVLAN; + else if (!strcmp(value, "phys")) + network->type = PHYS; + else { + lxc_log_error("invalid network type %s", value); + return -1; + } + return 0; +} + +static int config_network_flags(char *value, struct lxc_conf *lxc_conf) +{ + struct list *networks = &lxc_conf->networks; + struct network *network; + struct netdev *netdev; + + if (list_empty(networks)) { + lxc_log_error("network is not created for '%s' option", value); + return -1; + } + + network = list_first_elem(networks); + if (!network) { + lxc_log_error("no network defined for '%s' option", value); + return -1; + } + + netdev = list_first_elem(&network->netdev); + netdev->flags |= IFF_UP; + return 0; +} + +static int config_network_link(char *value, struct lxc_conf *lxc_conf) +{ + struct list *networks = &lxc_conf->networks; + struct network *network; + struct netdev *netdev; + + if (list_empty(networks)) { + lxc_log_error("network is not created for %s", value); + return -1; + } + + network = list_first_elem(networks); + if (!network) { + lxc_log_error("no network defined for %s", value); + return -1; + } + + if (strlen(value) > IFNAMSIZ) { + lxc_log_error("invalid interface name: %s", value); + return -1; + } + + netdev = list_first_elem(&network->netdev); + netdev->ifname = strdup(value); + return 0; +} + +static int config_network_name(char *value, struct lxc_conf *lxc_conf) +{ + struct list *networks = &lxc_conf->networks; + struct network *network; + struct netdev *netdev; + + if (list_empty(networks)) { + lxc_log_error("network is not created for %s", value); + return -1; + } + + network = list_first_elem(networks); + if (!network) { + lxc_log_error("no network defined for %s", value); + return -1; + } + + if (strlen(value) > IFNAMSIZ) { + lxc_log_error("invalid interface name: %s", value); + return -1; + } + + netdev = list_first_elem(&network->netdev); + netdev->newname = strdup(value); + return 0; +} + +static int config_network_hwaddr(char *value, struct lxc_conf *lxc_conf) +{ + struct list *networks = &lxc_conf->networks; + struct network *network; + struct netdev *netdev; + + if (list_empty(networks)) { + lxc_log_error("network is not created for %s", value); + return -1; + } + + network = list_first_elem(networks); + if (!network) { + lxc_log_error("no network defined for %s", value); + return -1; + } + + netdev = list_first_elem(&network->netdev); + netdev->hwaddr = strdup(value); + return 0; +} + +static int config_network_ipv4(char *value, struct lxc_conf *lxc_conf) +{ + struct list *networks = &lxc_conf->networks; + struct network *network; + struct inetdev *inetdev; + struct netdev *netdev; + struct list *list; + char *cursor, *slash, *addr = NULL, *bcast = NULL, *prefix = NULL; + + if (list_empty(networks)) { + lxc_log_error("network is not created for '%s'", value); + return -1; + } + + network = list_first_elem(networks); + if (!network) { + lxc_log_error("no network defined for '%s'", value); + return -1; + } + + netdev = list_first_elem(&network->netdev); + if (!netdev) { + lxc_log_error("no netdev defined for '%s'", value); + } + + inetdev = malloc(sizeof(*inetdev)); + if (!inetdev) { + lxc_log_syserror("failed to allocate ipv4 address"); + return -1; + } + memset(inetdev, 0, sizeof(*inetdev)); + + list = malloc(sizeof(*list)); + if (!list) { + lxc_log_syserror("failed to allocate memory"); + return -1; + } + + list_init(list); + list->elem = inetdev; + + addr = value; + + cursor = strstr(addr, " "); + if (cursor) { + *cursor = '\0'; + bcast = cursor + 1; + } + + slash = strstr(addr, "/"); + if (slash) { + *slash = '\0'; + prefix = slash + 1; + } + + if (!addr) { + lxc_log_error("no address specified"); + return -1; + } + + if (!inet_pton(AF_INET, addr, &inetdev->addr)) { + lxc_log_syserror("invalid ipv4 address: %s", value); + return -1; + } + + if (bcast) + if (!inet_pton(AF_INET, bcast, &inetdev->bcast)) { + lxc_log_syserror("invalid ipv4 address: %s", value); + return -1; + } + + if (prefix) + inetdev->prefix = atoi(prefix); + + list_add(&netdev->ipv4, list); + + return 0; +} + +static int config_network_ipv6(char *value, struct lxc_conf *lxc_conf) +{ + struct list *networks = &lxc_conf->networks; + struct network *network; + struct netdev *netdev; + struct inet6dev *inet6dev; + struct list *list; + char *slash; + char *netmask; + + if (list_empty(networks)) { + lxc_log_error("network is not created for %s", value); + return -1; + } + + network = list_first_elem(networks); + if (!network) { + lxc_log_error("no network defined for %s", value); + return -1; + } + + inet6dev = malloc(sizeof(*inet6dev)); + if (!inet6dev) { + lxc_log_syserror("failed to allocate ipv6 address"); + return -1; + } + memset(inet6dev, 0, sizeof(*inet6dev)); + + list = malloc(sizeof(*list)); + if (!list) { + lxc_log_syserror("failed to allocate memory"); + return -1; + } + + list_init(list); + list->elem = inet6dev; + + slash = strstr(value, "/"); + if (slash) { + *slash = '\0'; + netmask = slash + 1; + inet6dev->prefix = atoi(netmask); + } + + if (!inet_pton(AF_INET6, value, &inet6dev->addr)) { + lxc_log_syserror("invalid ipv6 address: %s", value); + return -1; + } + + + netdev = list_first_elem(&network->netdev); + list_add(&netdev->ipv6, list); + + return 0; +} + +static int config_mount(char *value, struct lxc_conf *lxc_conf) +{ + if (strlen(value) >= MAXPATHLEN) { + lxc_log_error("%s path is too long", value); + return -1; + } + + lxc_conf->fstab = strdup(value); + if (!lxc_conf->fstab) { + lxc_log_syserror("failed to duplicate string %s", value); + return -1; + } + + return 0; +} + +static int config_chroot(char *value, struct lxc_conf *lxc_conf) +{ + if (strlen(value) >= MAXPATHLEN) { + lxc_log_error("%s path is too long", value); + return -1; + } + + lxc_conf->chroot = strdup(value); + if (!lxc_conf->chroot) { + lxc_log_syserror("failed to duplicate string %s", value); + return -1; + } + + return 0; +} + +static int config_utsname(char *value, struct lxc_conf *lxc_conf) +{ + struct utsname *utsname; + + utsname = malloc(sizeof(*utsname)); + if (!utsname) { + lxc_log_syserror("failed to allocate memory"); + return -1; + } + + if (strlen(value) >= sizeof(utsname->nodename)) { + lxc_log_error("node name '%s' is too long", + utsname->nodename); + return -1; + } + + strcpy(utsname->nodename, value); + lxc_conf->utsname = utsname; + + return 0; +} + +static int parse_line(char *buffer, void *data) +{ + struct config *config; + char *dot; + char *key; + char *value; + + if (is_line_empty(buffer)) + return 0; + + buffer += char_left_gc(buffer, strlen(buffer)); + if (buffer[0] == '#') + return 0; + + dot = strstr(buffer, "="); + if (!dot) { + lxc_log_error("invalid configuration line: %s", buffer); + return -1; + } + + *dot = '\0'; + value = dot + 1; + + key = buffer; + key[char_right_gc(key, strlen(key))] = '\0'; + + value += char_left_gc(value, strlen(value)); + value[char_right_gc(value, strlen(value))] = '\0'; + + config = getconfig(key); + if (!config) { + lxc_log_error("unknow key %s", key); + return -1; + } + + return config->cb(value, data); +} + +static int file_for_each_line(const char *file, file_cb callback, void *data) +{ + char buffer[MAXPATHLEN]; + size_t len = sizeof(buffer); + FILE *f; + int err = -1; + + f = fopen(file, "r"); + if (!f) { + lxc_log_syserror("failed to open %s", file); + return -1; + } + + while (fgets(buffer, len, f)) + if (callback(buffer, data)) + goto out; + err = 0; +out: + fclose(f); + return err; +} + +int config_read(const char *file, struct lxc_conf *conf) +{ + return file_for_each_line(file, parse_line, conf); +} + +int config_init(struct lxc_conf *conf) +{ + conf->chroot = NULL; + conf->fstab = NULL; + conf->utsname = NULL; + conf->cgroup = NULL; + list_init(&conf->networks); + return 0; +} diff --git a/src/lxc/config.h b/src/lxc/config.h new file mode 100644 index 000000000..58439339a --- /dev/null +++ b/src/lxc/config.h @@ -0,0 +1,28 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +extern int config_init(struct lxc_conf *conf); +extern int config_read(const char *file, struct lxc_conf *conf); + + + diff --git a/src/lxc/lxc-priority.c b/src/lxc/lxc-priority.c new file mode 100644 index 000000000..9f0da8960 --- /dev/null +++ b/src/lxc/lxc-priority.c @@ -0,0 +1,33 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + return 0; +} + diff --git a/src/lxc/lxc-ps.in b/src/lxc/lxc-ps.in new file mode 100755 index 000000000..dae220b21 --- /dev/null +++ b/src/lxc/lxc-ps.in @@ -0,0 +1,17 @@ +#!/bin/bash + +LXCPATH=/var/lxc + +if [ ! -r $LXCPATH ]; then + exit 0 +fi + +LXCS=$(ls $LXCPATH) + +for i in $LXCS; do + if [ -d $LXCPATH/$i/nsgroup ]; then + echo "Container : $(basename $i)" + cat $LXCPATH/$i/nsgroup/tasks + fi +done + diff --git a/src/lxc/lxc_console.c b/src/lxc/lxc_console.c new file mode 100644 index 000000000..9f0da8960 --- /dev/null +++ b/src/lxc/lxc_console.c @@ -0,0 +1,33 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + return 0; +} + diff --git a/src/lxc/lxc_create.c b/src/lxc/lxc_create.c new file mode 100644 index 000000000..389f4edf5 --- /dev/null +++ b/src/lxc/lxc_create.c @@ -0,0 +1,86 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "config.h" + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + fprintf(stderr, "\t -f : path of the configuration file\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + const char *name = NULL, *file = NULL; + struct lxc_conf lxc_conf; + int opt; + + while ((opt = getopt(argc, argv, "f:n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + case 'f': + file = optarg; + break; + } + } + + if (!name || !file) + usage(argv[0]); + + if (config_init(&lxc_conf)) { + fprintf(stderr, "failed to initialize the configuration\n"); + return 1; + } + + if (config_read(file, &lxc_conf)) { + fprintf(stderr, "invalid configuration file\n"); + return 1; + } + + if (lxc_create(name, &lxc_conf)) { + fprintf(stderr, "failed to create the container %s\n", name); + return 1; + } + + return 0; +} + diff --git a/src/lxc/lxc_destroy.c b/src/lxc/lxc_destroy.c new file mode 100644 index 000000000..f8c834a81 --- /dev/null +++ b/src/lxc/lxc_destroy.c @@ -0,0 +1,63 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + int nbargs = 0; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + + nbargs++; + } + + if (!name) + usage(argv[0]); + + if (lxc_destroy(name)) { + fprintf(stderr, "failed to destroy %s\n", name); + return 1; + } + + return 0; +} + diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c new file mode 100644 index 000000000..fea4974c7 --- /dev/null +++ b/src/lxc/lxc_execute.c @@ -0,0 +1,68 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + char **args; + int nbargs = 0; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + + nbargs++; + } + + if (!name || !argv[optind] || !strlen(argv[optind])) + usage(argv[0]); + + args = &argv[optind]; + argc -= nbargs; + + if (lxc_execute(name, argc, args, NULL, NULL)) { + fprintf(stderr, "failed to start %s\n", name); + return 1; + } + + return 0; +} + diff --git a/src/lxc/lxc_freeze.c b/src/lxc/lxc_freeze.c new file mode 100644 index 000000000..f247233c4 --- /dev/null +++ b/src/lxc/lxc_freeze.c @@ -0,0 +1,64 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + int nbargs = 0; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + + nbargs++; + } + + if (!name) + usage(argv[0]); + + if (lxc_freeze(name)) { + fprintf(stderr, "failed to freeze '%s'\n", name); + return 1; + } + + return 0; +} + diff --git a/src/lxc/lxc_kill.c b/src/lxc/lxc_kill.c new file mode 100644 index 000000000..9f0da8960 --- /dev/null +++ b/src/lxc/lxc_kill.c @@ -0,0 +1,33 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + return 0; +} + diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c new file mode 100644 index 000000000..8736885b6 --- /dev/null +++ b/src/lxc/lxc_monitor.c @@ -0,0 +1,98 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + int fds[2]; + pid_t pid; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + } + + if (!name) + usage(argv[0]); + + if (pipe(fds)) { + perror("pipe"); + return 1; + } + + pid = fork(); + if (pid < 0) { + perror("fork"); + return 1; + } + + if (!pid) { + close(fds[0]); + if (lxc_monitor(name, fds[1])) { + fprintf(stderr, "failed to monitor %s\n", name); + return 1; + } + + return 0; + } + + close(fds[1]); + + for (;;) { + int err, state; + + err = read(fds[0], &state, sizeof(state)); + if (err < 0) { + perror("read"); + return 1; + } + + if (!err) { + printf("container has been destroyed\n"); + return 0; + } + + printf("container has changed the state to %d - %s\n", + state, state2str(state)); + } + return 0; +} + diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c new file mode 100644 index 000000000..a9c75d85b --- /dev/null +++ b/src/lxc/lxc_start.c @@ -0,0 +1,74 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + char **args; + int nbargs = 0; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + + nbargs++; + } + + if (!name || !argv[optind] || !strlen(argv[optind])) + usage(argv[0]); + + args = &argv[optind]; + argc -= nbargs; + + if (lxc_start(name, argc, args, NULL, NULL)) { + fprintf(stderr, "failed to start %s\n", name); + return 1; + } + + return 0; +} + diff --git a/src/lxc/lxc_state.c b/src/lxc/lxc_state.c new file mode 100644 index 000000000..a173d19ad --- /dev/null +++ b/src/lxc/lxc_state.c @@ -0,0 +1,67 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + int state, nbargs = 0; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + + nbargs++; + } + + if (!name) + usage(argv[0]); + + state = lxc_getstate(name); + if (state < 0) { + fprintf(stderr, "failed to freeze '%s'\n", name); + return 1; + } + + printf("'%s' is %s\n", name, state2str(state)); + + return 0; +} + diff --git a/src/lxc/lxc_stop.c b/src/lxc/lxc_stop.c new file mode 100644 index 000000000..2ed34878a --- /dev/null +++ b/src/lxc/lxc_stop.c @@ -0,0 +1,62 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + int nbargs = 0; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + + nbargs++; + } + + if (!name) + usage(argv[0]); + + if (lxc_stop(name)) { + fprintf(stderr, "failed to stop %s\n", name); + return 1; + } + + return 0; +} diff --git a/src/lxc/lxc_unfreeze.c b/src/lxc/lxc_unfreeze.c new file mode 100644 index 000000000..39a796a69 --- /dev/null +++ b/src/lxc/lxc_unfreeze.c @@ -0,0 +1,63 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + int nbargs = 0; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + + nbargs++; + } + + if (!name) + usage(argv[0]); + + if (lxc_unfreeze(name)) { + fprintf(stderr, "failed to freeze '%s'\n", name); + return 1; + } + + return 0; +} + diff --git a/test/.cvsignore b/test/.cvsignore new file mode 100644 index 000000000..6c7646b6b --- /dev/null +++ b/test/.cvsignore @@ -0,0 +1,19 @@ +.deps +Makefile +Makefile.in +conf +dev +forward +ipv4_add +lxc_create +lxc_destroy +lxc_monitor +lxc_start +lxc_stop +lxc_state +macvlan +movedev +proxy +veth +confile +ipv6_add diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 000000000..cc6faaaf2 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,91 @@ +INCLUDES= -I$(top_srcdir)/src/liblxc + +noinst_PROGRAMS = \ + tst_list \ + confile \ + conf \ + movedev \ + dev \ + forward \ + proxy \ + veth \ + macvlan \ + ipv4_add \ + ipv6_add \ + \ + lxc_create \ + lxc_destroy \ + lxc_start \ + lxc_stop \ + lxc_monitor \ + lxc_state + + +tst_list_SOURCES = tst_list.c +tst_list_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +confile_SOURCES = confile.c +confile_LDADD = \ + $(top_builddir)/src/lxc/config.o \ + $(top_builddir)/src/liblxc/liblxc.a + +conf_SOURCES = conf.c +conf_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +movedev_SOURCES = movedev.c +movedev_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +dev_SOURCES = dev.c +dev_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +forward_SOURCES = forward.c +forward_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +proxy_SOURCES = proxy.c +proxy_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +veth_SOURCES = veth.c +veth_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +macvlan_SOURCES = macvlan.c +macvlan_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +ipv4_add_SOURCES = ipv4_add.c +ipv4_add_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +ipv6_add_SOURCES = ipv6_add.c +ipv6_add_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_create_SOURCES = lxc_create.c +lxc_create_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_destroy_SOURCES = lxc_destroy.c +lxc_destroy_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_start_SOURCES = lxc_start.c +lxc_start_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_stop_SOURCES = lxc_stop.c +lxc_stop_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_monitor_SOURCES = lxc_monitor.c +lxc_monitor_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a + +lxc_state_SOURCES = lxc_state.c +lxc_state_LDADD = \ + $(top_builddir)/src/liblxc/liblxc.a diff --git a/test/conf.c b/test/conf.c new file mode 100644 index 000000000..419e4db54 --- /dev/null +++ b/test/conf.c @@ -0,0 +1,102 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * I want to setup a container with a veth attached on a bridge, + * and have them up + */ + +int main(int argc, char *argv[]) +{ +/* struct network network = { */ +/* .net = init_list(&network.net), */ +/* .netdev = init_list(&network.netdev), */ +/* }; */ + +/* struct veth veth = { */ +/* .link = "veth1", */ +/* .peer = "veth2", */ +/* .bridge = "br0", */ +/* }; */ + +/* struct net net = { */ +/* .type = VETH, */ +/* }; */ + +/* net.veth = veth; */ + +/* struct netdev lo = { */ +/* .ifname = "lo", */ +/* .flags = IFF_UP, */ +/* .ipv4 = init_list(&lo.ipv4), */ +/* .ipv6 = init_list(&lo.ipv6), */ +/* }; */ + +/* struct netdev veth1 = { */ +/* .ifname = "veth1", */ +/* .flags = IFF_UP, */ +/* .ipv4 = init_list(&veth1.ipv4), */ +/* .ipv6 = init_list(&veth1.ipv6), */ +/* }; */ + +/* struct netdev veth2 = { */ +/* .ifname = "veth2", */ +/* .flags = IFF_UP, */ +/* .netns = 1, */ +/* .ipv4 = init_list(&veth2.ipv4), */ +/* .ipv6 = init_list(&veth2.ipv6), */ +/* }; */ + +/* struct netdev br0 = { */ +/* .ifname = "br0", */ +/* .ipv4 = init_list(&br0.ipv4), */ +/* .ipv6 = init_list(&br0.ipv6), */ +/* }; */ + +/* list_add(&network.netdev, &lo.list); */ +/* list_add(&network.netdev, &veth1.list); */ +/* list_add(&network.netdev, &veth2.list); */ +/* list_add(&network.netdev, &br0.list); */ +/* list_add(&network.net, &net.list); */ + +/* struct lxc_conf lxc_conf = { */ +/* .network = &network, */ +/* .mounts = init_list(&lxc_conf.mounts), */ +/* }; */ + +/* if (lxc_configure("foo", &lxc_conf)) { */ +/* fprintf(stderr, "failed to configure\n"); */ +/* return 1; */ +/* } */ + + return 0; +} diff --git a/test/confile.c b/test/confile.c new file mode 100644 index 000000000..5e9dbdd59 --- /dev/null +++ b/test/confile.c @@ -0,0 +1,82 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../src/lxc/config.h" + +static void usage(const char *cmd) +{ + fprintf(stderr, "%s -n \n", cmd); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char *file = NULL, *name = NULL; + struct lxc_conf lxc_conf; + int opt; + + while ((opt = getopt(argc, argv, "n:f:")) != -1) { + switch (opt) { + case 'f': + file = optarg; + break; + case 'n': + name = optarg; + break; + } + } + + if (!file || !name) + usage(argv[0]); + + if (config_init(&lxc_conf)) { + fprintf(stderr, "failed to initialize configuration structure\n"); + return 1; + } + + if (config_read(file, &lxc_conf)) { + fprintf(stderr, "failed to read configuration\n"); + return 1; + } + + if (lxc_create(name, &lxc_conf)) { + fprintf(stderr, "failed to create <%s>\n", name); + return 1; + } + + return 0; +} diff --git a/test/dev.c b/test/dev.c new file mode 100644 index 000000000..b56328841 --- /dev/null +++ b/test/dev.c @@ -0,0 +1,76 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s -i -d -f \n", cmd); +} + +int main(int argc, char *argv[]) +{ + char *ifname = NULL, *flag = NULL; + int opt, destroy = 0, ret = -EINVAL; + + while ((opt = getopt(argc, argv, "i:f:d")) != -1) { + switch (opt) { + case 'i': + ifname = optarg; + break; + case 'f': + flag = optarg; + break; + case 'd': + destroy = 1; + break; + } + } + + if (!ifname || (!flag && !destroy)) { + usage(argv[0]); + return 1; + } + + if (destroy) + ret = device_delete(ifname); + else if (!strcmp(flag, "up")) + ret = device_up(ifname); + else if (!strcmp(flag, "down")) + ret = device_down(ifname); + + if (ret) { + fprintf(stderr, "failed to set %s: %s\n", + ifname, strerror(-ret)); + return 1; + } + + return 0; +} diff --git a/test/forward.c b/test/forward.c new file mode 100644 index 000000000..a14336105 --- /dev/null +++ b/test/forward.c @@ -0,0 +1,77 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include + +#include + +void usage(const char *cmd) +{ + fprintf(stderr, "%s -i -f \n", cmd); +} + +int main(int argc, char *argv[]) +{ + char *ifname = NULL, *flag = NULL; + int opt, ret, family = AF_INET; + + while ((opt = getopt(argc, argv, "6i:f:")) != -1) { + switch (opt) { + case 'i': + ifname = optarg; + break; + case 'f': + flag = optarg; + break; + case '6': + family = AF_INET6; + break; + } + } + + if (!ifname || !flag) { + usage(argv[0]); + return 1; + } + + if (!strcmp(flag, "on")) + ret = ip_forward_on(ifname, family); + else if (!strcmp(flag, "off")) + ret = ip_forward_off(ifname, family); + else { + usage(argv[0]); + return 1; + } + + if (ret) { + fprintf(stderr, "failed for %s: %s\n", + ifname, strerror(-ret)); + return 1; + } + + return 0; +} diff --git a/test/ipv4_add.c b/test/ipv4_add.c new file mode 100644 index 000000000..402f55655 --- /dev/null +++ b/test/ipv4_add.c @@ -0,0 +1,66 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s -i -a \n", cmd); +} + +int main(int argc, char *argv[]) +{ + char *ifname = NULL, *addr = NULL; + int opt, ret = -EINVAL; + + while ((opt = getopt(argc, argv, "i:a:")) != -1) { + switch (opt) { + case 'a': + addr = optarg; + break; + case 'i': + ifname = optarg; + break; + } + } + + if (!addr || !ifname) { + usage(argv[0]); + return 1; + } + + ret = ip_addr_add(ifname, addr, 24, NULL); + if (ret) { + fprintf(stderr, "failed to set %s: %s\n", + ifname, strerror(-ret)); + return 1; + } + + return 0; +} diff --git a/test/ipv6_add.c b/test/ipv6_add.c new file mode 100644 index 000000000..d68b5f536 --- /dev/null +++ b/test/ipv6_add.c @@ -0,0 +1,66 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s -i -a \n", cmd); +} + +int main(int argc, char *argv[]) +{ + char *ifname = NULL, *addr = NULL; + int opt, ret = -EINVAL; + + while ((opt = getopt(argc, argv, "i:a:")) != -1) { + switch (opt) { + case 'a': + addr = optarg; + break; + case 'i': + ifname = optarg; + break; + } + } + + if (!addr || !ifname) { + usage(argv[0]); + return 1; + } + + ret = ip6_addr_add(ifname, addr, 64, NULL); + if (ret) { + fprintf(stderr, "failed to set %s: %s\n", + ifname, strerror(-ret)); + return 1; + } + + return 0; +} diff --git a/test/lxc_create.c b/test/lxc_create.c new file mode 100644 index 000000000..9ee71b646 --- /dev/null +++ b/test/lxc_create.c @@ -0,0 +1,176 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static void usage(const char *cmd) +{ + fprintf(stderr, "%s -n \n", cmd); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + const char *name = NULL; + int opt; + +/* struct list mclist; */ +/* struct list mclist2; */ +/* struct list vethlist; */ +/* struct list vethlist2; */ + struct list phylist; + +/* struct inetdev idev; */ +/* struct list l1 = init_list(&l1); */ +/* l1.elem = &idev; */ + +/* struct inetdev idev_2; */ +/* struct list l2 = init_list(&l2); */ +/* l2.elem = &idev_2; */ + +/* struct inet6dev idev6; */ +/* struct list l3 = init_list(&l3); */ +/* l3.elem = &idev6; */ + +/* struct inet6dev idev6_2; */ +/* struct list l4 = init_list(&l4); */ +/* l4.elem = idev6_2; */ + + +/* inet_pton(AF_INET, "1.2.3.4", &idev.addr); */ +/* inet_pton(AF_INET, "1.2.3.255", &idev.bcast); */ +/* idev.prefix = 24; */ + +/* inet_pton(AF_INET, "4.3.2.1", &idev_2.addr); */ +/* inet_pton(AF_INET, "4.3.2.255", &idev_2.bcast); */ + +/* inet_pton(AF_INET6, "2003:db8:1:0:214:5eff:fe0b:3596", &idev6.addr); */ +/* inet_pton(AF_INET6, "2003:db8:1:0:214:1234:fe0b:3596", &idev6_2.addr); */ + +/* struct network veth = { */ +/* .type = VETH, */ +/* .netdev = { */ +/* .flags = IFF_UP, */ +/* .ifname = "br0", */ +/* .newname = "eth0", */ +/* .ipv4 = init_list(&veth.netdev.ipv4), */ +/* .ipv6 = init_list(&veth.netdev.ipv6), */ +/* }, */ +/* }; */ +/* vethlist.elem = &veth; */ + +/* list_add(&veth.netdev.ipv4, &l1); */ +/* list_add(&veth.netdev.ipv4, &l2); */ +/* list_add(&veth.netdev.ipv6, &l4); */ + +/* struct network veth2 = { */ +/* .type = VETH, */ +/* .netdev = { */ +/* .flags = IFF_UP, */ +/* .ifname = "br0", */ +/* .newname = "eth1", */ +/* .ipv4 = init_list(&veth2.netdev.ipv4), */ +/* .ipv6 = init_list(&veth2.netdev.ipv6), */ +/* }, */ +/* }; */ +/* list_add(&veth2.netdev.ipv6, &l3); */ +/* vethlist2.elem = &veth2; */ + +/* struct network macvlan = { */ +/* .type = MACVLAN, */ +/* .netdev = { */ +/* .flags = IFF_UP, */ +/* .ifname = "eth0", */ +/* .ipv4 = init_list(&macvlan.netdev.ipv4), */ +/* .ipv6 = init_list(&macvlan.netdev.ipv6), */ +/* }, */ +/* }; */ +/* mclist.elem = &macvlan; */ + +/* struct network macvlan2 = { */ +/* .type = MACVLAN, */ +/* .netdev = { */ +/* .ifname = "eth0", */ +/* .ipv4 = init_list(&macvlan2.netdev.ipv4), */ +/* .ipv6 = init_list(&macvlan2.netdev.ipv6), */ +/* }, */ +/* }; */ +/* mclist2.elem = &macvlan2; */ + + struct netdev nd = { + .ifname = "dummy0", + .ipv4 = init_list(&nd.ipv4), + .ipv6 = init_list(&nd.ipv6), + }; + struct list ndlist = init_list(&ndlist); + ndlist.elem = &nd; + + struct network phys = { + .type = PHYS, + .netdev = init_list(&phys.netdev), + }; + phylist.elem = &phys; + + struct lxc_conf lxc_conf = { + .networks = init_list(&lxc_conf.networks), + .chroot = "/mnt/iso", + }; + + list_add(&phys.netdev, &ndlist); + +/* list_add(&lxc_conf.networks, &vethlist); */ +/* list_add(&lxc_conf.networks, &mclist); */ + list_add(&lxc_conf.networks, &phylist); +/* list_add(&lxc_conf.networks, &mclist); */ +/* list_add(&lxc_conf.networks, &vethlist2); */ + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + } + + if (!name) + usage(argv[0]); + + if (lxc_create(name, &lxc_conf)) { + fprintf(stderr, "failed to create the container %s\n", name); + return 1; + } + + return 0; +} diff --git a/test/lxc_destroy.c b/test/lxc_destroy.c new file mode 100644 index 000000000..a652f9ea3 --- /dev/null +++ b/test/lxc_destroy.c @@ -0,0 +1,55 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +static void usage(const char *cmd) +{ + fprintf(stderr, "%s -n \n", cmd); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + const char *name = NULL; + int opt; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + } + + if (!name) + usage(argv[0]); + + if (lxc_destroy(name)) { + fprintf(stderr, "failed to destroy %s\n", name); + return 1; + } + + return 0; +} diff --git a/test/lxc_monitor.c b/test/lxc_monitor.c new file mode 100644 index 000000000..8f66d4ee6 --- /dev/null +++ b/test/lxc_monitor.c @@ -0,0 +1,100 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + int fds[2]; + pid_t pid; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + } + + if (!name) + usage(argv[0]); + + if (pipe(fds)) { + perror("pipe"); + return 1; + } + + + + pid = fork(); + if (pid < 0) { + perror("fork"); + return 1; + } + + if (!pid) { + close(fds[0]); + if (lxc_monitor(name, fds[1])) { + fprintf(stderr, "failed to monitor %s\n", name); + return 1; + } + + return 0; + } + + close(fds[1]); + + for (;;) { + int err, state; + + err = read(fds[0], &state, sizeof(state)); + if (err < 0) { + perror("read"); + return 1; + } + + if (!err) { + printf("container has been destroyed\n"); + return 0; + } + + printf("container has changed the state to %d - %s\n", + state, state2str(state)); + } + + return 0; +} diff --git a/test/lxc_start.c b/test/lxc_start.c new file mode 100644 index 000000000..2f551ec51 --- /dev/null +++ b/test/lxc_start.c @@ -0,0 +1,84 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +static int prestart(const char *name, int argc, char *argv[], void *data) +{ + printf("%s hook has been called with data %s\n", + __FUNCTION__, (char *)data); + return 0; +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + char **args; + int nbargs = 0; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + + nbargs++; + } + + if (!name || !argv[optind] || !strlen(argv[optind])) + usage(argv[0]); + + args = &argv[optind]; + argc -= nbargs; + + if (lxc_start(name, argc, args, prestart, "hello world")) { + fprintf(stderr, "failed to start %s\n", name); + return 1; + } + + return 0; +} diff --git a/test/lxc_state.c b/test/lxc_state.c new file mode 100644 index 000000000..2e5540873 --- /dev/null +++ b/test/lxc_state.c @@ -0,0 +1,66 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + int state; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + } + + if (!name) + usage(argv[0]); + + state = lxc_state(name); + if (state < 0) { + fprintf(stderr, "failed to retrieve the state of %s\n", name); + return 1; + } + + printf("container has the state to %d - %s\n", + state, state2str(state)); + + + return 0; +} diff --git a/test/lxc_stop.c b/test/lxc_stop.c new file mode 100644 index 000000000..f38e9efc0 --- /dev/null +++ b/test/lxc_stop.c @@ -0,0 +1,59 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include + +void usage(char *cmd) +{ + fprintf(stderr, "%s \n", basename(cmd)); + fprintf(stderr, "\t -n : name of the container\n"); + _exit(1); +} + +int main(int argc, char *argv[]) +{ + char opt; + char *name = NULL; + + while ((opt = getopt(argc, argv, "n:")) != -1) { + switch (opt) { + case 'n': + name = optarg; + break; + } + } + + if (!name) + usage(argv[0]); + + if (lxc_stop(name)) { + fprintf(stderr, "failed to stop %s\n", name); + return 1; + } + + return 0; +} diff --git a/test/macvlan.c b/test/macvlan.c new file mode 100644 index 000000000..a29a68741 --- /dev/null +++ b/test/macvlan.c @@ -0,0 +1,66 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include + +#include + +void usage(const char *cmd) +{ + fprintf(stderr, "%s -i -p \n", cmd); +} + +int main(int argc, char *argv[]) +{ + char *ifname = NULL, *peer = NULL; + int opt, ret = -EINVAL; + + while ((opt = getopt(argc, argv, "i:p:")) != -1) { + switch (opt) { + case 'i': + ifname = optarg; + break; + case 'p': + peer = optarg; + break; + } + } + + if (!ifname || !peer) { + usage(argv[0]); + return 1; + } + + ret = macvlan_create(ifname, peer); + if (ret) { + fprintf(stderr, "failed to set %s/%s: %s\n", + ifname, peer, strerror(-ret)); + return 1; + } + + return 0; +} diff --git a/test/movedev.c b/test/movedev.c new file mode 100644 index 000000000..662eba017 --- /dev/null +++ b/test/movedev.c @@ -0,0 +1,64 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#include + +void usage(const char *cmd) +{ + fprintf(stderr, "%s -i -p \n", cmd); +} + +int main(int argc, char *argv[]) +{ + char *ifname = NULL; + pid_t pid = -1; + int opt; + + while ((opt = getopt(argc, argv, "p:i:")) != -1) { + switch (opt) { + case 'p': + pid = atoi(optarg); + break; + case 'i': + ifname = optarg; + break; + } + } + + if (!ifname || pid == -1) { + usage(argv[0]); + return 1; + } + + if (device_move(ifname, pid)) { + fprintf(stderr, "failed to move %s\n", ifname); + return 1; + } + + return 0; +} diff --git a/test/proxy.c b/test/proxy.c new file mode 100644 index 000000000..fbd4f2d4f --- /dev/null +++ b/test/proxy.c @@ -0,0 +1,77 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include + +#include + +void usage(const char *cmd) +{ + fprintf(stderr, "%s -i -f \n", cmd); +} + +int main(int argc, char *argv[]) +{ + char *ifname = NULL, *flag = NULL; + int opt, ret, family = AF_INET; + + while ((opt = getopt(argc, argv, "6i:f:")) != -1) { + switch (opt) { + case 'i': + ifname = optarg; + break; + case 'f': + flag = optarg; + break; + case '6': + family = AF_INET6; + break; + } + } + + if (!ifname || !flag) { + usage(argv[0]); + return 1; + } + + if (!strcmp(flag, "on")) + ret = neigh_proxy_on(ifname, family); + else if (!strcmp(flag, "off")) + ret = neigh_proxy_off(ifname, family); + else { + usage(argv[0]); + return 1; + } + + if (ret) { + fprintf(stderr, "failed for %s: %s\n", + ifname, strerror(-ret)); + return 1; + } + + return 0; +} diff --git a/test/tst_list.c b/test/tst_list.c new file mode 100644 index 000000000..b4d062481 --- /dev/null +++ b/test/tst_list.c @@ -0,0 +1,66 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + struct list *iterator; + struct list head = init_list(&head); + struct list l1 = init_list(&l1); + struct list l2 = init_list(&l2); + struct list l3 = init_list(&l3); + struct list l4 = init_list(&l4); + + struct dummy { + int a; + }; + + struct dummy *elem; + struct dummy d1 = { .a = 1 }; + struct dummy d2 = { .a = 2 }; + struct dummy d3 = { .a = 3 }; + struct dummy d4 = { .a = 4 }; + + if (!list_empty(&head)) { + fprintf(stderr, "expected empty list\n"); + return -1; + } + + l1.elem = &d1; + l2.elem = &d2; + l3.elem = &d3; + l4.elem = &d4; + + list_add(&head, &l1); + list_add(&head, &l2); + list_add(&head, &l3); + list_add(&head, &l4); + + list_for_each(iterator, &head) { + elem = iterator->elem; + printf("elem has %d\n", elem->a); + } + + list_del(&l3); + + list_for_each(iterator, &head) { + elem = iterator->elem; + printf("elem has %d\n", elem->a); + } + + list_del(&l1); + list_del(&l2); + list_del(&l4); + + if (!list_empty(&head)) { + fprintf(stderr, "expected empty list\n"); + return -1; + } + + list_for_each(iterator, &head) { + fprintf(stderr, "should not loop\n"); + return -1; + } + + return 0; +} diff --git a/test/veth.c b/test/veth.c new file mode 100644 index 000000000..0ada151b5 --- /dev/null +++ b/test/veth.c @@ -0,0 +1,66 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include + +#include + +void usage(const char *cmd) +{ + fprintf(stderr, "%s -i -p \n", cmd); +} + +int main(int argc, char *argv[]) +{ + char *ifname = NULL, *peer = NULL; + int opt, ret = -EINVAL; + + while ((opt = getopt(argc, argv, "i:p:")) != -1) { + switch (opt) { + case 'i': + ifname = optarg; + break; + case 'p': + peer = optarg; + break; + } + } + + if (!ifname || !peer) { + usage(argv[0]); + return 1; + } + + ret = veth_create(ifname, peer); + if (ret) { + fprintf(stderr, "failed to set %s/%s: %s\n", + ifname, peer, strerror(-ret)); + return 1; + } + + return 0; +}