pax_global_header00006660000000000000000000000064121122401040014475gustar00rootroot0000000000000052 comment=69ac5bc7fea67c4d422c52b3bc609534597b5dd5 modglue-1.19/000077500000000000000000000000001211224010400130635ustar00rootroot00000000000000modglue-1.19/.gitignore000066400000000000000000000004031211224010400150500ustar00rootroot00000000000000aclocal.m4 autom4te.cache modglue.pc out* Makefile config.status config.cache config.log modglue-config *.o src/ptywrap src/prompt *.lo *~ src/isatty src/test_child_process src/test_ext_process src/test_writes src/test_writes.out src/test_pipe *.la src/.libs modglue-1.19/AUTHORS000066400000000000000000000000541211224010400141320ustar00rootroot00000000000000Kasper Peeters, modglue-1.19/COPYING000066400000000000000000000431051211224010400141210ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. modglue-1.19/ChangeLog000066400000000000000000000041761211224010400146450ustar00rootroot000000000000002012-01-26 Kasper Peeters * Released 1.18 * Changed read_nonblocking_ in pipe.cc to circumvent a Mac OSX compiler bug. 2010-05-29 Kasper Peeters * Released 1.17 * Removed RPATH from prompt. 2010-03-03 Kasper Peeters * Released 1.16 2009-11-03 Kasper Peeters * Fixed problem with gcc-4.4. 2009-03-24 Kasper Peeters * Started adding Windows compatibility. 2008-12-14 Kasper Peeters * Released 1.12 * Bug fixes for Debian/Ubuntu packages. 2008-05-06 Kasper Peeters * Released 1.10 * Fixed a number of issues with the debian package. * Fixed some issues with superfluous linking. 2008-04-05 Kasper Peeters * Released 1.9 * Fixed various issues to make modglue compile on Solaris: - some additional #includes - linking with sockets library - openpty() Thanks to Alexei Petrash for suggesting these changes. 2007-03-26 Kasper Peeters * Released 1.8 * Added static building of ptywrap. 2007-03-05 Kasper Peeters * Released 1.7 * Fixed linking with -lutil and selection of pty.h or util.h for Mac OS X systems (should now work on 10.3.x and 10.4.x). 2007-02-20 Kasper Peeters * Removed pty opening code in ptywrap with openpty for increased compatbility with e.g. Red Hat systems. 2007-02-19 Kasper Peeters * Released 1.6. * Added "wait()" to the child_process class. * Fixed a problem in ptywrap which would prevent it from ever ending properly on Mac OS X. * Released 1.5. * Enabled ptywrap for Mac OS X. 2007-02-15 Kasper Peeters * Released 1.4. * Made ptywrap compile on Mac OS X. 2007-02-06 Kasper Peeters * Released 1.3. * Added proper versioning support using -version-info rather than the -release system. 2006-08-18 Kasper Peeters * Added support for Mac OS X. * Version 1.2 released. modglue-1.19/INSTALL000066400000000000000000000002661211224010400141200ustar00rootroot00000000000000 To install `modglue', do ./configure make make install as usual. If you want it installed in a different directory than /usr/local, use the --prefix option to configure. modglue-1.19/Makefile.in000066400000000000000000000021761211224010400151360ustar00rootroot00000000000000 export RELEASE=1.19 .PHONY: all install library static examples uninstall clean distclean all: library #examples library: echo @libdir@ ( cd src && $(MAKE) ); static: ( cd src && $(MAKE) static ); examples: library ( cd examples && $(MAKE) ); install: ( cd src && $(MAKE) install ); @INSTALL@ -d -m 755 ${DESTDIR}@prefix@/@libdir@/pkgconfig @INSTALL@ -m 644 modglue.pc ${DESTDIR}@prefix@/@libdir@/pkgconfig/ @INSTALL@ -d -m 755 ${DESTDIR}@prefix@/share/man/man1 @INSTALL@ man/man1/prompt.1 ${DESTDIR}@prefix@/share/man/man1 @INSTALL@ man/man1/ptywrap.1 ${DESTDIR}@prefix@/share/man/man1 # @INSTALL@ man/man1/isatty.1 ${DESTDIR}@prefix@/share/man/man1 uninstall: ( cd src && $(MAKE) uninstall ); rm -f ${DESTDIR}@prefix@/bin/modglue-config tarball: git archive --format=tar --prefix=modglue-${RELEASE}/ HEAD | gzip > ${HOME}/tmp/modglue-${RELEASE}.tar.gz clean: ( cd src && $(MAKE) clean ); ( cd examples && $(MAKE) clean ); rm -f *~ distclean: clean ( cd src && $(MAKE) distclean ); ( cd examples && $(MAKE) distclean ); rm -f Makefile config.cache config.log config.status modglue.pc rm -Rf autom4te.cache aclocal.m4 modglue-1.19/TODO000066400000000000000000000153431211224010400135610ustar00rootroot00000000000000Bugs: - There is a weird issue with O_NONBLOCK setting on stdin of forked processes. This is not what one wants when doing something 'expect'-like; in that case you want the child to wait for input. Why did we make this nonblocking in the first place, only because modglue binaries would always use a select loop to wait for input? Maybe we should make stdin for forked processes blocking when these are normal Unix programs, and let them decide whether to set NONBLOCK. See pipe.cc in opipe::do_fcntl. - use forkpty()? - Need to intercept Ctrl-C in prompt, and intead feed it to the client. - prompt now works, the lesson is to NEVER use cout/cerr in modglue. maybe a warning wouldn't be bad... Still an occasional 'hang' after a program terminates, and something funny with a buffer being flushed at the end (cdb: @quit produces some output). - Output to unix pipe is now flawless. There is still a bug in prompt which leads to cut-off of output. Since sendmsg has now been disabled (everything goes through 'write'), this has to be a problem with the input buffer (i.e. in the input channel of prompt itself). NOTE (important): we got the previous write problems because we ignored EAGAIN on write, _even_ though we never put the write channel in NONBLOCKING mode. Why is that? - an error was recently fixed which has to do with 'read' getting interrupted by a signal. Is this related to the dropped char problem? - We need a wrapper around 'run' which takes a Gtk main object, sets up i/o monitoring on the modglue descriptors, sets up the modglue signal handlers (that's only related to child processes going away, so gtk shouldn't care) and then start the gtk loop. This should perhaps go into a pure header file, since it is only a few lines and can easily be inlined (then we won't need to have GTK/Inti installed to compile modglue, but can still always 'turn this on'). ---- - What confirmation mechanisms do we want? - blocking acks are bad, they lead to deadlocks. - so put the read end of the socket into the select loop and monitor that internally for return codes. - and then we need to have a callback function which is called whenever the status of the other side of a pipe is changed. - return codes: DATA_WILL_BE_IGNORED DATA_WILL_BE_USED PROCESSED [mid] any others? - Add the logic that determines whether a process should keep running after the input of a given pipe has stopped, or whether it should exit and a new process should start. - Every address space should have only one loader, but we can have multiple listener threads in that address space listening to outside pipes. So things have to be split, but we need a nice way to merge the select callback routines. DONE. Every modglue binary will now be a `main', and we still have one `loader' per address space. Creating a new address space will fork off a `loader', and those will be controllable through pipes. - if we separate the gui from the real loader, and duplicate inforeq and infodump to stdin and stdout respectively, we can have a simple command line loader. You can start that one by running `loader' and then type add gtkshell (process) connect loader:infodump,gtkshell:infohandle connect loader:inforeq,gtkshell:infocommands run or something like that. Note that we still need to be able to connect internally. But for modglue processes that is trivial since we can just broadcast data to modglue pipes very easily. > loader // for monitoring add gtk-shell (process) connect :infodump, gtk-shell:infohandle connect :inforeq, gtk-shell:infocommands // these can be done through the gtk-shell instead if required add gtk-browser (thread) add gtk-renderer (thread) add wget (process) for testing one can then do add loader loader:inforeq add gtk-browser (thread) connect :stdin, loader:gtk-browser:stdin connect :stdout, loader:gtk-browser:stdout - if we want to make `loader' a proper replacement for a shell, we should really be doing something else with the commands: > gtk-shell ^ > gtk-iowin ^ > which connect builtin command > jobs gtk-shell (process, not running) gtk-iowin (process, not running) > connect gtk-shell /* KEY: modules are _algorithms_, while they exchange _data_. You do note exchange full _objects_! Unix works because programs are cut at places where they no longer care what is going to happen with the data they spit out. Is that the proper way to think of it? (ie. restrict your module boundaries). This is also why http servers are nice: they spit out data that is easy to manipulate but they don't care what you do with it. Unix pipes also have one other disadvantage: once you let go of data (ie. write it out to a pipe) you can no longer manipulate it at a later stage unless you get it fed back. We could think of multi-processes sharing dom trees and being able to modify them (locking is important). But that is a bit like writing something to a temporary file and being able to get back at the data later. The SAX vs DOM thing is the same sort of problem: with SAX the outputting program lets go of data as it is being output, while with DOM there remains an agreed upon standard data structure in memory. Plan9 plumbing is our old concept of broadcasting messages. It's too inflexible, as you have a global map from message type to receiver. ------------ The library essentially offers a simple interface to the functionality of clone, in other words it allows you to start new processes in a separate or in the same address space in a robust way. Moreover, it provides a clean, pipe based way to send messages between these processes, which are always transported in the most efficient way. All processes contain at their core a select loop listening to input and output message pipes, which generalise the concept of stdin, stdout and stderr. Finally, the library provides a way to wire the processes together and determine how messages should flow (for instance it is possible to indicate whether a message should lead to new process creation or whether the previous receiver should remain doing so). External modules are always started using fork, internal modules always run as threads. All modules have a select loop at their core. Messages between different address spaces are serialised and put on the pipe between two processes, while messages in the same address space are just objects sitting in memory which are announced by writing an announcement message on the pipe between two threads. Process entry points and thread entry points are identical: the `main' function. */ modglue-1.19/configure000077500000000000000000005165451211224010400150120ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.63. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="src/shell.cc" ac_default_prefix=/usr/local # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS LINK_UTIL USE_UTIL_H MAC_OS_X sigc_LIBS sigc_CFLAGS PKG_CONFIG EGREP GREP CPP INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM SET_MAKE LN_S ac_ct_CXX CXXFLAGS CXX OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CPP PKG_CONFIG sigc_CFLAGS sigc_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { $as_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { $as_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { $as_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor PKG_CONFIG path to pkg-config utility sigc_CFLAGS C compiler flags for sigc, overriding pkg-config sigc_LIBS linker flags for sigc, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.63. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test -r "$ac_site_file"; then { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { $as_echo "$as_me:$LINENO: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } if test -z "$ac_file"; then $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:$LINENO: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi { $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' MAC_OS_X="" if test x"`uname`" == "xDarwin" then MAC_OS_X="1" echo "checking system type... Darwin" else echo "checking system type... Unix" fi # Taken from a random aclocal.m4 found on the net; # tests to ensure that we link with the right libraries # for networking functionality. # Most operating systems have gethostbyname() in the default searched # libraries (i.e. libc): { $as_echo "$as_me:$LINENO: checking for gethostbyname" >&5 $as_echo_n "checking for gethostbyname... " >&6; } if test "${ac_cv_func_gethostbyname+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define gethostbyname to an innocuous variant, in case declares gethostbyname. For example, HP-UX 11i declares gettimeofday. */ #define gethostbyname innocuous_gethostbyname /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef gethostbyname /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_gethostbyname || defined __stub___gethostbyname choke me #endif int main () { return gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_gethostbyname=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 $as_echo "$ac_cv_func_gethostbyname" >&6; } if test "x$ac_cv_func_gethostbyname" = x""yes; then : else # Some OSes (eg. Solaris) place it in libnsl: { $as_echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_nsl_gethostbyname=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" else # Some strange OSes (SINIX) have it in libsocket: { $as_echo "$as_me:$LINENO: checking for gethostbyname in -lsocket" >&5 $as_echo_n "checking for gethostbyname in -lsocket... " >&6; } if test "${ac_cv_lib_socket_gethostbyname+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_socket_gethostbyname=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_gethostbyname=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_socket_gethostbyname" >&5 $as_echo "$ac_cv_lib_socket_gethostbyname" >&6; } if test "x$ac_cv_lib_socket_gethostbyname" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" else # Unfortunately libsocket sometimes depends on libnsl. # AC_CHECK_LIB's API is essentially broken so the following # ugliness is necessary: { $as_echo "$as_me:$LINENO: checking for gethostbyname in -lsocket" >&5 $as_echo_n "checking for gethostbyname in -lsocket... " >&6; } if test "${ac_cv_lib_socket_gethostbyname+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket -lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_socket_gethostbyname=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_gethostbyname=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_socket_gethostbyname" >&5 $as_echo "$ac_cv_lib_socket_gethostbyname" >&6; } if test "x$ac_cv_lib_socket_gethostbyname" = x""yes; then LIBS="-lsocket -lnsl $LIBS" else { $as_echo "$as_me:$LINENO: checking for gethostbyname in -lresolv" >&5 $as_echo_n "checking for gethostbyname in -lresolv... " >&6; } if test "${ac_cv_lib_resolv_gethostbyname+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_resolv_gethostbyname=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_resolv_gethostbyname=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_gethostbyname" >&5 $as_echo "$ac_cv_lib_resolv_gethostbyname" >&6; } if test "x$ac_cv_lib_resolv_gethostbyname" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBRESOLV 1 _ACEOF LIBS="-lresolv $LIBS" fi fi fi fi fi { $as_echo "$as_me:$LINENO: checking for socket" >&5 $as_echo_n "checking for socket... " >&6; } if test "${ac_cv_func_socket+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define socket to an innocuous variant, in case declares socket. For example, HP-UX 11i declares gettimeofday. */ #define socket innocuous_socket /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef socket /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_socket || defined __stub___socket choke me #endif int main () { return socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_socket=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_socket=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_socket" >&5 $as_echo "$ac_cv_func_socket" >&6; } if test "x$ac_cv_func_socket" = x""yes; then : else { $as_echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 $as_echo_n "checking for socket in -lsocket... " >&6; } if test "${ac_cv_lib_socket_socket+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_socket_socket=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_socket=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 $as_echo "$ac_cv_lib_socket_socket" >&6; } if test "x$ac_cv_lib_socket_socket" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" else { $as_echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 $as_echo_n "checking for socket in -lsocket... " >&6; } if test "${ac_cv_lib_socket_socket+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket -lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_socket_socket=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_socket=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 $as_echo "$ac_cv_lib_socket_socket" >&6; } if test "x$ac_cv_lib_socket_socket" = x""yes; then LIBS="-lsocket -lnsl $LIBS" fi fi fi USE_UTIL_H=1 ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:$LINENO: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$LINENO: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in util.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test x"${ac_cv_header_util_h}" == "xno" then USE_UTIL_H=0 fi LINK_UTIL="" { $as_echo "$as_me:$LINENO: checking for openpty in -lutil" >&5 $as_echo_n "checking for openpty in -lutil... " >&6; } if test "${ac_cv_lib_util_openpty+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lutil $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char openpty (); int main () { return openpty (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_util_openpty=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_util_openpty=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_util_openpty" >&5 $as_echo "$ac_cv_lib_util_openpty" >&6; } if test "x$ac_cv_lib_util_openpty" = x""yes; then LINK_UTIL="-lutil" fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; then $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:$LINENO: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:$LINENO: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:$LINENO: checking for sigc" >&5 $as_echo_n "checking for sigc... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$sigc_CFLAGS"; then pkg_cv_sigc_CFLAGS="$sigc_CFLAGS" else if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"sigc++-2.0\"") >&5 ($PKG_CONFIG --exists --print-errors "sigc++-2.0") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_sigc_CFLAGS=`$PKG_CONFIG --cflags "sigc++-2.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$sigc_LIBS"; then pkg_cv_sigc_LIBS="$sigc_LIBS" else if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"sigc++-2.0\"") >&5 ($PKG_CONFIG --exists --print-errors "sigc++-2.0") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_sigc_LIBS=`$PKG_CONFIG --libs "sigc++-2.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then sigc_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "sigc++-2.0"` else sigc_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "sigc++-2.0"` fi # Put the nasty error message in config.log where it belongs echo "$sigc_PKG_ERRORS" >&5 { { $as_echo "$as_me:$LINENO: error: Package requirements (sigc++-2.0) were not met: $sigc_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables sigc_CFLAGS and sigc_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " >&5 $as_echo "$as_me: error: Package requirements (sigc++-2.0) were not met: $sigc_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables sigc_CFLAGS and sigc_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " >&2;} { (exit 1); exit 1; }; } elif test $pkg_failed = untried; then { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables sigc_CFLAGS and sigc_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details." >&5 $as_echo "$as_me: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables sigc_CFLAGS and sigc_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } else sigc_CFLAGS=$pkg_cv_sigc_CFLAGS sigc_LIBS=$pkg_cv_sigc_LIBS { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } : fi ac_config_files="$ac_config_files Makefile modglue.pc src/Makefile examples/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.63. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { $as_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "modglue.pc") CONFIG_FILES="$CONFIG_FILES modglue.pc" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { $as_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=' ' ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\).*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\).*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$ac_file_inputs '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi modglue-1.19/configure.in000066400000000000000000000036511211224010400154010ustar00rootroot00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT(src/shell.cc) dnl Variable overrides dnl PACKAGE=modglue dnl VERSION=0.9 dnl AC_SUBST(PACKAGE) dnl AC_SUBST(VERSION) dnl Checks for programs. AC_PROG_CC AC_PROG_CXX AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_INSTALL dnl AC_PROG_LIBTOOL dnl Checks for libraries. dnl Checks for header files. MAC_OS_X="" if test x"`uname`" == "xDarwin" then MAC_OS_X="1" echo "checking system type... Darwin" else echo "checking system type... Unix" fi AC_PREFIX_DEFAULT(/usr/local) # Taken from a random aclocal.m4 found on the net; # tests to ensure that we link with the right libraries # for networking functionality. AC_DEFUN(AC_LIBRARY_NET, [ # Most operating systems have gethostbyname() in the default searched # libraries (i.e. libc): AC_CHECK_FUNC(gethostbyname, , # Some OSes (eg. Solaris) place it in libnsl: AC_CHECK_LIB(nsl, gethostbyname, , # Some strange OSes (SINIX) have it in libsocket: AC_CHECK_LIB(socket, gethostbyname, , # Unfortunately libsocket sometimes depends on libnsl. # AC_CHECK_LIB's API is essentially broken so the following # ugliness is necessary: AC_CHECK_LIB(socket, gethostbyname, LIBS="-lsocket -lnsl $LIBS", AC_CHECK_LIB(resolv, gethostbyname), -lnsl) ) ) ) AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, , AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl))) ]) AC_LIBRARY_NET USE_UTIL_H=1 AC_CHECK_HEADERS(util.h) if test x"${ac_cv_header_util_h}" == "xno" then USE_UTIL_H=0 fi LINK_UTIL="" AC_CHECK_LIB(util,openpty, [LINK_UTIL="-lutil"]) PKG_CHECK_MODULES([sigc], [sigc++-2.0]) dnl AC_SUBST(install_flags) AC_SUBST([MAC_OS_X]) AC_SUBST([USE_UTIL_H]) AC_SUBST([LINK_UTIL]) AC_SUBST([LIBS]) dnl The output files AC_OUTPUT( Makefile modglue.pc src/Makefile examples/Makefile ) modglue-1.19/doc/000077500000000000000000000000001211224010400136305ustar00rootroot00000000000000modglue-1.19/doc/IDEAS000066400000000000000000000015061211224010400144020ustar00rootroot00000000000000 > new window(-1,-1,600,800); < 1945 > new button("kasper"); < 1946 > 1945->add(1946); > new canvas(); < 1947 > 1945->add(1947); { 1946.pressed { 1947.redraw(0,0,680,800); > 1947.draw_string(100,100,"test"); > 1947.set_color("red"); > 1947.draw_box(120,0,125,800); or for XML xml_in> blabla

foo

barbar bar command> new iterator(top); out> 1945 command> 1945.print(); out> html command> 1945.num_children(); out> 1 command> 1945.next_child(); command> 1945.print(); out> body command> 1945.type(); out> element cycling through input-pipes by pressing shift-tab. class object { public: string name; int reference; }; class message { public: enum message_type { new_type, delete_type, call_type, reference_type, signal_type }; int reference(); }; modglue-1.19/doc/index.html000066400000000000000000000061741211224010400156350ustar00rootroot00000000000000 libModglue: a C++ library for handling co-processes

libModglue: a C++ library for handling co-processes

Kasper Peeters, kasper.peeters (at) aei.mpg.de

Overview

The libModglue library is a C++ library with classes for forking external processes and asynchronous reading from streams. It takes away the burden of all subtleties involving the Unix fork call. The asynchronous read facility enables one to read on multiple input streams at the same time, without losing any of the standard C++ stream facilities.
There are also several small additional programs bundled with modglue, such as a program to add readline capability to any command line program. Moreover, the modglue library extends the idea of standard Unix pipes by providing a general framework for the creation of new processes with more than just the standard stdin/stdout/stderr pipes.

Simple example

#include <modglue/modglue.hh>

modglue::pipe foopipe("foo", modglue::pipe::input,  0);
modglue::pipe barpipe("bar", modglue::pipe::output, 1);

void print(const string& txt)
   {
   cout << "received " << txt << " on foo pipe" << endl;
   cout << "sending something on bar pipe" << endl;
   while(txt!="end") {
      string str;
      if(!foopipe.read(str,2))
         break;
      }
   barpipe.sender("thank you!");
   }

int main(int argc, char **argv) 
   {
   modglue::main mm(&argc, &argv);

   mm.add(pipe1);
   mm.add(pipe2);

   foopipe.receiver.connect(slot(print));
   
   mm.run();
   }

Download

For all download information please visit the download page of cadabra.

Utilities

Several small programs are bundled with modglue. They provide some additional functionality that was easy to implement with the library, or are generally useful for command-line driven programs.
ptywrap
Starts a program with stdin/stdout/stderr connected to a pseudo tty device, and map them to fd 0,1,2. This can be used to trick programs like ftp or sed into thinking that they are running interactively.
> ptywrap [unix executable]
is all you need to know.

prompt
The prompt utility wraps other programs such that their input has the well-known readline behaviour. In other words, you can use the cursor keys for editing, there is a history, and so on. Useful for programs like ftp that lack this functionality.


modglue-1.19/doc/oldindex.html000066400000000000000000000471611211224010400163350ustar00rootroot00000000000000 modglue documentation

modglue

a Plan9-inspired extension of the Unix pipe concept

Kasper Peeters, <K.Peeters@damtp.cam.ac.uk>

[overview] [download] [library] [shell overview] [shell manual] [utilities] [faq]

WARNING: Modglue is in an experimental stage right now. It may not even compile. The text below does not necessarily reflect the status of the code.

Overview

Modglue is a combination of several software tools that assist in writing and running programs connected to each other using standard Unix pipes. There are two main parts to it, the modglue library and the modglue shell. In more detail:
modglue library
This is a C++ library with classes for forking external processes and asynchronous reading from streams. It takes away the burden of all subtleties involving the Unix fork call. The asynchronous read facility enables one to read on multiple input streams at the same time, without loosing any of the standard C++ stream facilities.
modglue shell
A shell with special support for arbitrarily connecting process pipes together, in a way that goes beyond the standard Unix linear pipe idea (a bit like ksh co-processes, but much more powerful). In contrast to existing shells, you can start any number of processes and connect their stdin/stderr/stdout pipes in any way you like, not just linear as usual.
Each of these is explained in more detail below. There are also several small additional programs bundled with modglue, such as a program to add readline capability to any command line program.

Moreover, the modglue library extends the idea of standard Unix pipes by providing a general framework for the creation of new processes with more input or output pipes. The modglue library has support for this built in, but the setup is general and can be used from any language.

In general, the idea behind modglue is that the Unix pipe concept is very powerful, but insufficient to construct interactive programs that require bidirectional communication between processes. The library and shell extend this concept in a completely backwards compatible way such that large robust systems can be built from individual Unix building blocks.

The idea of "circularly connected pipes" is not new, but usually only implemented in an ad-hoc fashion. See for instance satshell, which is a gui tool which reads gui building commands from stdin and writes event information (pressed buttons and so forth) to stdout. In this case, the satshell program itself is given a program to which it should connect its stdin and stdout. For another similar idea (though without implementation), see this Freshmeat editorial by David Symonds. Modglue separates the connection logic from the actual program (in the context of satshell, the gui tool would be one process and the script another, and modglue would connect their stdin/stdout pipes in a circular way).

Once Unix building blocks are more easily connected in order to build complex programs, one can perhaps start building graphical tools to do this (an example of this approach, though with custom building blocks instead of programs that stick to the Unix pipe philosophy, can be found in triana).


Download and install

You need the following additional software in order to compile and use modglue:

Then, download and install modglue.tar.gz. Follow the instructions in the INSTALL file for installation details.


Modglue library

#include <modglue/modglue.hh>

modglue::pipe foopipe("foo", modglue::pipe::input,  0);
modglue::pipe barpipe("bar", modglue::pipe::output, 1);

void print(const string& txt)
   {
   cout << "received " << txt << " on foo pipe" << endl;
   cout << "sending something on bar pipe" << endl;
   while(txt!="end") {
      string str;
      if(!foopipe.read(str,2))
         break;
      }
   barpipe.sender("thank you!");
   }

int main(int argc, char **argv) 
   {
   modglue::main mm(&argc, &argv);

   mm.add(pipe1);
   mm.add(pipe2);

   foopipe.receiver.connect(slot(print));
   
   mm.run();
   }


Modglue shell overview

On Unix systems, the standard way to combine small programs into bigger ones is to tie them together using pipes. As all standard conforming programs have three standard pipes (stdin, stdout, stderr) open, it is easy to feed the output of one program into another one:
wget -O - http://somewhere | grep "something"
However, this way of connecting programs is limited in the sense that data only flows one way (from the first program to the second and so on, but never back).

Some shells have ways to circumvent this limitation. The korn shell has so-called "co-processes", which you can start as

program |&
after which you can read from and write to the standard pipes. A similar concept exists in zsh, where co-processes are started by pre-fixing them with the command "coproc". Although very useful, these shells only allow for a single co-process.

Moreover, there is no standard way to extend the number of input/output pipes that a program can have. (co-processes do not allow for input redirection to startup arguments; since many programs can only take their arguments from argv and not from stdin, this is (unfortunately) a requirement. Also, these guys do not provide a pseudo-tty so most programs started as coprocesses will start buffering).

The modglue library takes the Unix concept one step further and allows programs to open more than these three standard pipes. Furthermore, the links between programs can be more flexible (you can have complicated graph-like structures instead of just a single linear pipe) and writing programs that listen on multiple pipes in a non-blocking way is considerably easier. For instance, a program could be prompting the user with a dialog for entering a url, then send that request out through its output pipe, and read in any responses through its input pipe.

The modglue library implements a strict superset of the standard Unix pipe idea: all normal Unix programs can be used as modglue building blocks, the only limitation being that these programs of course have only the three standard pipes.

There are two types of programs in the modglue world: unix executables and modglue executables. The second category is a strict superset of the first one; all modglue executables are also unix executables, though they may not be able to offer full functionality when run from a unix shell instead of the modglue shell.


Modglue shell user manual

Modshell is the analogue of a normal unix shell like bash or csh. It contains the logic to tie sockets of various modglue executables together and spawn new processes. However, it is intended to be usable as a replacement for a normal Unix shell, in the sense that running programs in the normal Unix way is supported (with the standard notation, eg. using the '&' character to start programs in the background and the '|' character to connect stdout/stdin of programs). In more detail, the options are:
start programs immediately
This is like starting programs on a Unix shell. Just type the command (followed by its arguments, if any) and press return. You will not get a prompt back before the program returns. The stdin/stdout/stderr sockets of the program will be connected to the stdin/stdout/stderr sockets of the modshell.

If you try to start Unix executables this way, they will automatically be wrapped using the "ptywrap" command.

start programs in the background
This is again like starting programs on a Unix shell. Just type the command (followed by its arguments, if any) followed by a '&' character and press return. Any output will be buffered, but in contrast to the situation in Unix, you can connect the stdout/stderr (or any socket, for that matter) of the running program even after the program has been started.

list all running and runnable programs
Type the command "jobs". This produces a list of the following form:
> jobs
13446 running                       xbiff
                                      xbiff::stdin
                                      xbiff::stdout
                                      xbiff::stderr
13447 running                       gtkiowin
                                      gtkiowin::stdin
                                      gktiowin::stdexc
13558 standby, start_on_input       wget -O -
                                      wget::stdin
                                      wget::stdout
                                      wget::stderr

list all socket connections
Type the command "bonds". This produces a list of the all connections between sockets of different executables.

add programs to the runnable list
Type the program name, and append a '^' character. This will not start the program yet, so that you can still connect its socket to those of other programs (see the "connect" command).

Options can be given by adding them in a comma separated list after the '^' character. At the moment, the available ones are start_on_input and abort_on_failed_write.

start programs in the runnable list
Type "[pid] &" where `pid' is the process identifier of a process in the runnable list. This is similar to the way suspended unix binaries are restarted in the background in normal unix shells.

connect sockets of different programs
Type "connect" followed by a space-separated list of the sockets of the programs which you want to connect.

There is a shortcut possible if you just want to connect in the normal Unix way (connect stdout and/or stderr of one program to stdin of the next): just type the program names separated by a pipe symbol '|'.


Utilities

Several small programs are bundled with modglue. They provide some additional functionality that was easy to implement with the library, or are generally useful for command-line driven programs.
ptywrap (modglue executable)

Starts a program with stdin/stdout/stderr connected to a pseudo tty device, and map them to fd 0,1,2. This can be used to trick programs like ftp or sed into thinking that they are running interactively.
> ptywrap [unix executable]
is all you need to know.

prompt (modglue executable)

The prompt utility wraps other programs such that their input has the well-known readline behaviour. In other words, you can use the cursor keys for editing, there is a history, and so on. Useful for programs like ftp that lack this functionality.


Frequently asked questions

What about threads?
An initial implemention of modglue supported loading modglue executables as threads. This was, however, extremely ugly. Studying Plan9 I have come to the conclusion that for almost all tasks it is better to redesign modules (divide the functionality differently) in such a way that they can each run in individual address spaces. Careful use of the select loop facilities of modglue is the right way to go.

How does it compare to DCOP, CORBA, XML-RPC and so on?
What sets modglue apart from other mechanisms to build software using independent components are its compatibility with the Unix pipe system, the idea of a shell determining which connections to make (instead of modules determining themselves to which other module they want to connect) and its simplicity. Among the other available systems, there is DCOP (used in KDE, has a special non-ascii communication method that is incompatible with Unix pipes, modules make explicit requests for services instead of leaving that to the shell), CORBA and XML-RPC.

Some of the functionality of modglue can be found in TCL, in particular the ability to send data to the stdin of an already forked program. Modglue aims for a much more basic goal: it just links programs together, nothing more. In this sense it is a lot simpler than TCL (and it feels more like a normal Unix shell).

Sockets are bidirectional, so why are all modglue pipes still uni-directional?
Even though modglue uses sockets for all communication between processes, the pipes are always either reading or writing pipes, but not both. This is done to mimick as closely as possible the Unix pipe idea, which uses unidirectional communication (you cannot write to stdin, for instance).

The `other' component of the socket channel is used solely for status information, and never directly visible to the user of the program. These status messages are suppressed when modglue binaries run in Unix mode, so they do not interfere with normal expected Unix pipe behaviour.

What names should I give to my pipes?
Even though you have the option of giving arbitrary names to programs, it pays off to think about this for a little while. If the program is small enough and the program name itself describes its function, just using stdin, stdout and stderr can be a good choice.

In case your program is going to write explicit requests for data on a pipe and then listen for the reply on another one, it is good to make the names related. Suggested are reqout and reqret and variations thereof if you need more than one pair.

How does message tagging work?
Since the sendmsg and recvmsg system calls can cut up and re-assemble the messages in arbitrary ways, modglue provides an alternative mechanism to make sure that the messages you send are only processed at the other end when all the data has arrived. The way in which this works is that all data is encapsulated in the following structure before it is handed to sendmsg:
fieldsize (bytes
version number and flags1
stream identifier8
length4
datalength
The reader will then be able to figure out whether to wait for more messages to come which really belong to the same outgoing message.

See the next question for info about the stream identifier field.

Obviously this header yields some overhead, and makes it clear that you should try to avoid sending only a few bytes of data. Compared to something like XML-RPC, the cost is still pretty minimal though.

How can I make asynchronous requests for data? (asynchronous remote procedure calls)
If you send a message using the normal sender member of a pipe, it will be stamped with a system wide unique identifier (see the table above). It is, however, possible to send a message with the identifier of a previously received message, such that it becomes possible to relate a number of messages into one `stream'.

Making an asynchronous request then goes as follows. Create a message with a new identifier, and store the identifier somewhere. When input comes in, compare its identifier to what was stored. If they match, it is a reply.

What about synchronous (blocking) reads or send/read?
There are no facilities for this, because it very easily leads to deadlocks. If your reading process blocks, waiting for data, then it blocks everything, including reading from other channels.

If you never block but instead use the main event loop to wait for incoming data, you avoid all potential deadlock situations. Just think differently.

How does modglue compare to notification messaging systems like Elvin?
The idea of notification systems is always that various programs send messages out, and other programs can decide to subscribe to these messages (based on the content). The Plan9 plumbing concept is similar in spirit.

In modglue, the user who starts processes decides which pipes it is going to listen to. This puts a little bit more burden on the user, but removes altogether a complicated layer of message distribution algorithms. Modglue is thus simpler, at the expense of needing a user willing to do a little bit more work.

Is it fast enough?
Obviously, you cannot expect a few thousand small read/writes from one process to the other to be anywhere near as fast as the same number of direct function calls in a linked library. Therefore, it pays off to think about how to group your data into big chunks if you want to have maximum speed.



$Id: oldindex.html,v 1.1 2007/03/05 22:39:00 peekas Exp $ modglue-1.19/doc/streams.html000066400000000000000000000027461211224010400162050ustar00rootroot00000000000000 overflow: This function is called on output, when there is no buffer, or no space in the existing buffer. If you want buffering, the buffer should be set up in the first call to overflow. The argument is the character to be output, or EOF. For historical reasons, it is probably advisable to call sync on EOF. The exact functionality of this function will depend on the buffering strategy used. Without buffering, just output the argument, returning the character output, or EOF on error. With buffering: if there is no buffer, create one, otherwise flush it, and insert the character into the buffer. (Use the function setp to initialize the buffer, or to reset it to empty once you've flushed it, and the functions gptr and egptr to get the current values.) underflow: This function is called on input, which is a little more complicated. In particular, although the function returns the next character in the stream, it does *not* extract it from the stream. Input *must* be buffered, although a one character buffer is sufficient. Also, there is no guarantee that the get buffer will be empty when this function is called, so you have to check that. In all cases, when you return, 1) the next character must be present in the buffer -- if there wasn't a buffer before, you have to create one, and 2) that character must be returned. modglue-1.19/examples/000077500000000000000000000000001211224010400147015ustar00rootroot00000000000000modglue-1.19/examples/Makefile.in000066400000000000000000000011341211224010400167450ustar00rootroot00000000000000 all: periodic multi_io use_wget #periodic_modglue #multi_io %.o: %.cc @CXX@ @CFLAGS@ -I@top_srcdir@/include `pkg-config modglue --cflags` -c -o $@ $< use_wget: use_wget.o @CXX@ -o use_wget -L../src `pkg-config modglue --libs` use_wget.o multi_io: multi_io.o @CXX@ -o multi_io -L../src `pkg-config modglue --libs` multi_io.o -lmodglue periodic: periodic.o @CXX@ -o periodic -L../src periodic.o periodic_modglue: periodic_modglue.o @CXX@ -o periodic_modglue -L../src periodic_modglue.o -lmodglue install: clean: rm -f *.o *~ multi_io periodic periodic_modglue distclean: rm -f Makefile modglue-1.19/examples/fetcher000077500000000000000000000011671211224010400162540ustar00rootroot00000000000000#!/bin/sh src/gtkshell \ --module='sed -e "s/\(.*\)/\1 -O -/"' \ --id=sed \ --module='grep HTML' \ --id=grep \ --module='wget' \ --options=start_on_input \ --module='src/gtkiowin' \ --id=viewer \ --module='src/gtkiowin' \ --options=start_on_input \ --id=error_output \ --module='examples/periodic "Type a URL in the box above."' \ --options=abort_on_failed_write \ --bond=sed:stdout,wget:startup_args \ --bond=sed:stdin,viewer:stdout \ --bond=wget:stdout,grep:stdin \ --bond=grep:stdout,viewer:stdin \ --bond=examples/periodic:stdout,viewer:stdexc \ $* # --bond=wget:stderr,error_output:stdexc \ modglue-1.19/examples/multi_io.cc000066400000000000000000000033451211224010400170360ustar00rootroot00000000000000/* Modglue example program. Copyright (C) 2001-2009 Kasper Peeters 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. */ /* Simple program to show usage of multiple I/O pipes in addition to the standard stdin/stdout/stderr combo. */ #include #include #include #include using namespace std; modglue::ipipe foopipe("foo"); modglue::ipipe foo2pipe("foo2"); modglue::opipe barpipe("bar"); bool print(modglue::ipipe& p) { string txt; while(p >> txt) { cerr << "from foo: |" << txt << "|" << endl; barpipe << "bar:" << txt << endl; } p.clear(); return true; } bool print2(modglue::ipipe& p) { string txt; while(p >> txt) { barpipe << "thank you 2!" << endl; } p.clear(); return true; } int main(int argc, char **argv) { modglue::main mm(argc, argv); mm.add(&foopipe,0); mm.add(&foo2pipe); mm.add(&barpipe,2); foopipe.receiver.connect(sigc::ptr_fun(print)); foo2pipe.receiver.connect(sigc::ptr_fun(print2)); mm.run(2); } modglue-1.19/examples/periodic.cc000066400000000000000000000024171211224010400170120ustar00rootroot00000000000000/* Test program to yield output at given interval. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include int main(int argc, char **argv) { int counter=1; char buffer[100]; while(true) { if(argc>1) { if(write(1, argv[1], strlen(argv[1])) 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. */ #include #include #include #include #include #include modglue::pipe *foopipe; main(int argc, char **argv) { modglue::main *mm=modglue::loader::instance().create_main(argc, argv); foopipe=new modglue::pipe("stdout", modglue::pipe::output); mm->add(foopipe); if(mm->check()) { int counter=1; char buffer[100]; while(true) { sprintf(buffer, "test %d\n", counter); foopipe->sender(buffer); ++counter; sleep(1); } } } modglue-1.19/examples/recursive000077500000000000000000000003541211224010400166400ustar00rootroot00000000000000#!/bin/sh src/gtkshell \ --module='src/gtkshell' \ --module='src/gtkiowin' \ --bond=src/gtkshell:inforeq,src/gtkiowin:stdout \ --bond=src/gtkshell:infodump,src/gtkiowin:stdin \ --bond=src/gtkshell:fddump,src/gtkiowin:stdexc \ $* modglue-1.19/examples/simple000077500000000000000000000004711211224010400161220ustar00rootroot00000000000000#!/bin/sh gtkshell \ --module='src/gtkiowin' \ --module='examples/periodic_modglue' \ --options=abort_on_failed_write \ --module='examples/periodic' \ --options=abort_on_failed_write \ --bond=src/gtkiowin:stdexc,examples/periodic_modglue:foo \ --bond=src/gtkiowin:stdin,examples/periodic:stdout \ $* modglue-1.19/examples/use_wget.cc000066400000000000000000000037331211224010400170400ustar00rootroot00000000000000/* Modglue example program. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include bool receive_html(modglue::ipipe& p) { std::string str; while(getline(p,str)) { } p.clear(); return true; } bool receive_info(modglue::ipipe& p) { std::string str; while(getline(p,str)) { } std::cerr << "." << std::flush; p.clear(); return true; } bool receive_exitstatus(modglue::ext_process& pr) { std::cerr << "exit code:" << pr.exit_code() << std::endl; return true; } int main(int argc, char **argv) { modglue::main mm(argc, argv); modglue::ext_process wgett("wget"); wgett << "-O" << "-"; try { modglue::ext_process wget1(wgett); wget1 << "http://www.ictp.trieste.it"; wget1.setup_pipes(); mm.add(&wget1); wget1.input_pipe("stdout")->receiver.connect(sigc::ptr_fun(receive_html)); wget1.input_pipe("stderr")->receiver.connect(sigc::ptr_fun(receive_info)); mm.process_died.connect(sigc::ptr_fun(receive_exitstatus)); wget1.fork(); /* This would be cleaner when written as: wget.set_io(&receive_html,&receive_info); wget.fork(); */ mm.run(1); } catch(std::exception& ex) { std::cerr << ex.what() << std::endl; } } modglue-1.19/include/000077500000000000000000000000001211224010400145065ustar00rootroot00000000000000modglue-1.19/include/modglue/000077500000000000000000000000001211224010400161425ustar00rootroot00000000000000modglue-1.19/include/modglue/ext_process.hh000066400000000000000000000052721211224010400210270ustar00rootroot00000000000000/* $Id: ext_process.hh,v 1.11 2006/03/10 14:23:23 kp229 Exp $ Extended process class (with pipe interface instead of bare file descriptors). Copyright (C) 2001-2009 Kasper Peeters 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. */ #ifndef ext_process_hh_ #define ext_process_hh_ #include #include #include namespace modglue { class ext_process /*: public SigC::Object */ { public: ext_process(const std::string&); ext_process(const std::string&, const std::vector&); ext_process(const ext_process& ); // only copies name and arguments ~ext_process(); void setup_pipes(void); ext_process& operator<<(const std::string&); void fork(); void terminate(int exit_code=0); void pause(); void restart(); std::string name(void) const; pid_t get_pid() const; int exit_code() const; const std::vector& args(void) const; const std::vector& input_pipes(void) const; const std::vector& output_pipes(void) const; ipipe* input_pipe(const std::string&) const; opipe* output_pipe(const std::string&) const; const std::vector& output(void) const; // FIXME: remove private: void determine_path_(void); void determine_binary_type_(void); void setup_pipes_from_string_(const std::string& desc); void open_pipes_(void); void dup_unix_pipes_(void); void close_parentside_(void); void close_childside_(void); bool receive_output_(ipipe&); std::string name_; std::vector args_; std::string full_path_; bool modglue_binary_; std::vector input_pipes_; std::vector output_pipes_; pid_t pid_; bool paused_; int exit_code_; bool pipes_done_; std::vector output_; }; }; #endif modglue-1.19/include/modglue/main.hh000066400000000000000000000063021211224010400174100ustar00rootroot00000000000000/* $Id: main.hh,v 1.20 2006/03/10 14:23:23 kp229 Exp $ Event loop handler Copyright (C) 2001-2009 Kasper Peeters 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. */ #ifndef modglue_main_hh_ #define modglue_main_hh_ #include #include #include #include #include #include #include #include #include #include #include #include static volatile char signature[]="MODGLUE_1.0_BINARY"; namespace modglue { class main /* : public SigC::Object */ { public: main(); main(int argc, char **argv); ~main(); void add(ipipe *, int default_fd=-1); // main does not get ownership void add(opipe *, int default_fd=-1); void add(ext_process *); void run(int min_pipes); bool check(void); // When using a non-modglue event loop, the file descriptors on which // to listen for modglue can be obtained through the pipe structures. // The user is responsible for making sure that the select_callback() gets // called when data is available or exceptions occur on one of these pipes. void last_read(void); int fds_to_watch(std::vector& fds) const; bool select_callback(int); // false if connection should be disconnected sigc::signal1 process_died; std::ofstream debugout; private: static int sig_chld_pipe_[2]; // used by sig_chld_ to signal died process // is a copy installed by setup_signal_handlers // int old_sig_chld_pipe_[2]; struct sigaction old_sigaction_chld_; struct sigaction old_sigaction_term_; struct sigaction old_sigaction_int_; bool list_pipes_; std::vector ipipes_; std::vector opipes_; int argc_; char **argv_; std::map pipe_fds_; std::vector processes_; bool terminate_main_loop_; void select_loop_(int min_pipes); std::string build_pipe_list(void) const; void setup_signal_handlers_(void); void restore_signal_handlers_(void); int add_fds_(fd_set& rfds, fd_set& efds, int& maxfd) const; static void sig_chld_(int signo); static void sig_term_(int signo); }; }; #endif modglue-1.19/include/modglue/mid.hh000066400000000000000000000024771211224010400172460ustar00rootroot00000000000000/* Identifiers for messages. Copyright (C) 2001-2009 Kasper Peeters 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. */ #ifndef mid_hh_ #define mid_hh_ #include #include #include //#include //#include namespace modglue { class mid { public: mid(void); mid(const mid&); int operator==(const mid&) const; friend std::ostream& operator<<(std::ostream&, const mid&); private: pid_t process_; int serial_; static int highwater_; }; std::ostream& operator<<(std::ostream&, const modglue::mid&); }; #endif modglue-1.19/include/modglue/pipe.hh000066400000000000000000000064131211224010400174240ustar00rootroot00000000000000 /* $Id: pipe.hh,v 1.16 2006/03/10 14:23:23 kp229 Exp $ Pipe class (generalises Unix standard pipes and the pipe() call) Copyright (C) 2001-2009 Kasper Peeters 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. */ #ifndef pipe_hh_ #define pipe_hh_ #include #include #include #include #include namespace modglue { class pipebuf; class ext_process; class pipe { public: virtual ~pipe(); std::string name(void) const; int fd(void) const; int fd_external(void) const; bool is_broken(void) const; // ie. is the other end closed? void open(int fd=-1, int fd_external=-1); void set_unix_style(void); void set_blocking(); void close(void); void close_external(void); void first_read_after_select(); void send_with_ack(const char *, int length); int read_with_ack(char *, int maxlen); ext_process *process; protected: pipe(const std::string& name); virtual void do_fcntl_(void) const=0; int read_nonblocking_(char *data, int maxlen); // returns as 'read' int send_blocking_(const char *data, int len); // returns as 'write' int fd_, fd_external_; bool broken_; bool first_read_after_select_; bool unix_style_pipe_; // uni-directional, no acknowledgement bool make_blocking_; private: std::string name_; }; class pipebuf : public std::streambuf { public: pipebuf(pipe *); ~pipebuf(); void put_buffer(void); void put_char(int); protected: int overflow(int=EOF); int underflow(); int sync(); int flushbuffer(void); private: pipe *pipe_; static const int bufsiz = 1024; static const int putbackarea = 8; char i_buf[bufsiz]; // input buffer; char o_buf[bufsiz]; // output buffer }; class opipe : public pipe, public std::ostream { public: opipe(const std::string& name); private: virtual void do_fcntl_(void) const; }; class ipipe : /* public sigc::object, */ public pipe, public std::istream { public: ipipe(const std::string& name); sigc::signal1 receiver; private: virtual void do_fcntl_(void) const; }; // sockets are always bidirectional... How is this going to fit in? //class server_isocket : public ipipe { // public: //}; // //class server_osocket : public ipipe { // public: //}; // //class client_isocket : public ipipe { // public: //}; // //class client_osocket : public opipe { // public: //}; }; #endif modglue-1.19/include/modglue/process.hh000066400000000000000000000052341211224010400201450ustar00rootroot00000000000000/* $Id: process.hh,v 1.9 2007/02/19 11:01:16 peekas Exp $ Process class (for forking external processes) Copyright (C) 2001-2009 Kasper Peeters 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. */ #ifndef process_hh_ #define process_hh_ #include #include #include #include #include #include //#include //#include namespace modglue { /// A class to start external processes and communicate with them in a blocking /// way. If you need asynchronous communication, use the ext_process class. class child_process { public: child_process(const std::string&); child_process(const std::string&, const std::vector&); ~child_process(); /// Higher-level communication with the external process. void call(const std::string& stdin_txt, std::string& stdout_txt); void call(const std::string& stdin_txt, std::string& stdout_txt, std::string& stderr_txt); void write(const std::string&); void read(std::string&); /// Compatibility functions mimicking Unix read/write. ssize_t read(void *, size_t len); ssize_t write(void *, size_t len); /// Starting and stopping. void fork(); // start the process void terminate(); // terminate the process with kill void close(); // close all pipes void wait(); // wait until process ends pid_t get_pid() const; /// Name and arguments of the child process std::string name; std::vector args; child_process& operator<<(const std::string&); /// Pipe related members void standard_pipes(); class fd_pair { public: enum direction_t { child_output, child_input }; fd_pair(int, direction_t); int child_fd; // better call this `external_fd' int parent_fd; // and this `our_fd' direction_t direction; }; std::vector pipes; private: pid_t pid_; }; }; #endif modglue-1.19/include/modglue/shell.hh000066400000000000000000000057731211224010400176060ustar00rootroot00000000000000/* $Id: shell.hh,v 1.14 2001/08/17 18:39:20 t16 Exp $ The modglue shell, connecting modglue binaries. Copyright (C) 2001-2009 Kasper Peeters 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. */ #ifndef shell_hh_ #define shell_hh_ #include #include #include #include #include #include #include #include #include #include namespace modglue { class process_info { public: process_info(const std::string& name, const std::string& unique_name); modglue::ext_process process; bool start_on_input; bool restart_after_exit; bool abort_on_failed_write; bool remove_after_exit; private: std::string unique_name_; }; class bond { public: bond(const std::string&); typedef std::set >::const_iterator const_iterator; typedef std::set >::iterator iterator; std::string name; std::set > pipes; }; class loader : public SigC::Object { public: loader(modglue::main *, modglue::ipipe *, modglue::opipe *, modglue::opipe *); ~loader(); void quit(void); void print_prompt(void); bool accept_commands(modglue::ipipe& p); bool accept_commands_old(std::istream& p); bool pipe_input(modglue::ipipe& p); void process_died(modglue::ext_process& pr); private: class groupelem { public: string process; string pipe; }; enum status_t { s_initial, s_command, s_skipwhite, s_arg_or_control, s_scan, s_groupscan, s_curlygroup }; std::vector status_; std::vector errors_; std::vector new_processes_; std::string current_; vector current_group_; bool ingroup_; bool parse_(modglue::ipipe& ); void add_bond_(bond *); void remove_bond_(bond *); void print_jobs_(std::ostream& ss); void print_bonds_(std::ostream& ss); main * main_; modglue::ipipe *p_command; modglue::opipe *p_result; modglue::opipe *p_error; std::vector processes_; std::vector bonds_; }; }; #endif modglue-1.19/include/modglue/sock000066400000000000000000000023271211224010400170300ustar00rootroot00000000000000 int sd, newSd, cliLen; struct sockaddr_in cliAddr, servAddr; char line[MAX_MSG]; /* create socket */ sd = socket(AF_INET, SOCK_STREAM, 0); if(sd<0) { perror("cannot open socket "); return ERROR; } /* bind server port */ servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.sin_port = htons(SERVER_PORT); if(bind(sd, (struct sockaddr *) &servAddr, sizeof(servAddr))<0) { perror("cannot bind port "); return ERROR; } listen(sd,5); while(1) { printf("%s: waiting for data on port TCP %u\n",argv[0],SERVER_PORT); cliLen = sizeof(cliAddr); newSd = accept(sd, (struct sockaddr *) &cliAddr, &cliLen); if(newSd<0) { perror("cannot accept connection "); return ERROR; In order to be notified of incoming connections on a socket, you can use select(2) or poll(2). A readable event will be delivered when a new connection is attempted and you may then call accept to get a socket for that connection. Alternatively, you can set the socket to deliver SIGIO when activity occurs on a socket; see socket(7) for details. How do I handle pipes in main right now? modglue-1.19/install-sh000077500000000000000000000144061211224010400150740ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # # 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. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. 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}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # 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 $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 modglue-1.19/man/000077500000000000000000000000001211224010400136365ustar00rootroot00000000000000modglue-1.19/man/man1/000077500000000000000000000000001211224010400144725ustar00rootroot00000000000000modglue-1.19/man/man1/isatty.1000066400000000000000000000023371211224010400160760ustar00rootroot00000000000000.TH ISATTY 1 "Oct 16, 2008" "" "" .\" .\" Man page written by Kasper Peeters .\" .\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .\" .SH NAME isatty \- show whether default streams are terminals .SH SYNOPSIS .BR "isatty" .SH DESCRIPTION .B isatty is a simple program which shows whether the default streams (stdin, stdout, stderr) are connected to a terminal. .SH SEE ALSO .BR modglue (1). .BR ptywrap (1). See the web page at .BR "http://www.aei.mpg.de/~peekas/modglue/" for more information. .SH AUTHORS Kasper Peeters modglue-1.19/man/man1/prompt.1000066400000000000000000000027301211224010400160770ustar00rootroot00000000000000.TH PROMPT 1 "Jul 12, 2008" "" "" .\" .\" Man page written by Kasper Peeters .\" .\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .\" .SH NAME prompt \- give any program command-line editing facilities .SH SYNOPSIS .BR "prompt" .SH DESCRIPTION .B prompt is a simple wrapper which provides command-line editing for programs that do not have it. Not all programs with a command line interface provide an input history or even the ability to use the cursor keys to change the input. The prompt program wraps any program, intercepting stdin, stdout and stderr and providing the user with such editing facilities. .SH SEE ALSO .BR modglue (1). .BR ptywrap (1). See the web page at .BR "http://www.aei.mpg.de/~peekas/modglue/" for more information. .SH AUTHORS Kasper Peeters modglue-1.19/man/man1/ptywrap.1000066400000000000000000000030061211224010400162610ustar00rootroot00000000000000.TH PTYWRAP 1 "Jul 12, 2008" "" "" .\" .\" Man page written by Kasper Peeters .\" .\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .\" .SH NAME ptywrap \- fool programs into thinking they are talking to a pseudo-tty .SH SYNOPSIS .BR "ptywrap" .SH DESCRIPTION .B ptywrap is a simple tool to wrap other programs' input/output streams in a pseudo-tty. Many programs determine whether or not they should buffer their input/output based on whether or not these are connected to a pseudo-tty. Ptywrap can be used to fool programs into thinking that they are connected to a pseudo-tty even if they are not (e.g. even if the input/output is redirected to a file). .SH SEE ALSO .BR modglue (1). .BR prompt (1). See the web page at .BR "http://www.aei.mpg.de/~peekas/modglue/" for more information. .SH AUTHORS Kasper Peeters modglue-1.19/modglue.pc.in000066400000000000000000000005451211224010400154540ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=${prefix} # defining another variable in terms of the first libdir=${exec_prefix}/lib includedir=${prefix}/include Name: modglue Description: C++ library for pipes and external processes Version: 1.0.0 URL: http://www.aei.mpg.de/~peekas/modglue Requires: sigc++-2.0 >= 2.0.0 Libs: -L${libdir} -lmodglue Cflags: -I${includedir} modglue-1.19/src/000077500000000000000000000000001211224010400136525ustar00rootroot00000000000000modglue-1.19/src/.cvsignore000066400000000000000000000003171211224010400156530ustar00rootroot00000000000000*.lo *.la .libs shell modshell gtkshell gtkiowin libmodglue.so* libmid.so* isatty ptywrap ptywrap_static prompt prompt_static Makefile test_pipe test_pipe_gtk test_child_process test_ext_process test_writes modglue-1.19/src/Makefile.in000066400000000000000000000115141211224010400157210ustar00rootroot00000000000000 MACTEST= @MAC_OS_X@ ifeq ($(strip $(MACTEST)),) LIBTOOL = libtool else #export MACOSX_DEPLOYMENT_TARGET=10.3 LIBTOOL = glibtool endif # Ubuntu/Debian sometimes use DEVDESTDIR, but if it is # absent, just set it equal to DESTDIR otherwise macs will # get confused. ifndef DEVDESTDIR DEVDESTDIR=${DESTDIR} endif # We use libtool but without any of the automake # nonsense, so we only need the following 5 lines. LTRELEASE = `echo ${RELEASE} | sed -e "s/\./:/g"` CPHASE = ${LIBTOOL} --tag=CXX --mode=compile @CXX@ -c @CFLAGS@ LPHASE = ${LIBTOOL} --tag=CXX --mode=link @CXX@ -version-info ${LTRELEASE} -rpath @prefix@@libdir@ @LIBS@ #LPHASE = ${LIBTOOL} --tag=CXX --mode=link @CXX@ -version-info ${LTRELEASE} @LIBS@ MPHASE = ${LIBTOOL} --tag=CXX --mode=link @CXX@ IPHASE = ${LIBTOOL} --mode=install @INSTALL@ FPHASE = ${LIBTOOL} --mode=finish @prefix@/@libdir@ TIMESTAMP = -D"DATETIME=\"`date | sed -e 's/ / /'`\"" -DHOSTNAME=\"`hostname`\" all: library tests tools TOOLS = ptywrap isatty prompt THELIB = libmodglue.la libmid.la TESTS = test_child_process test_pipe test_ext_process test_writes library: ${THELIB} tools: ${TOOLS} tests: ${TESTS} static: prompt_static ptywrap_static #------- Generic ---------------------------------------- %.lo: %.cc ${CPHASE} ${TIMESTAMP} -I@top_srcdir@/include `pkg-config sigc++-2.0 --cflags` $< %.o: %.cc @CXX@ -c ${TIMESTAMP} -D"USE_UTIL_H=@USE_UTIL_H@" -I@top_srcdir@/include `pkg-config sigc++-2.0 --cflags` $< libmid.la: mid.lo ${LPHASE} -o libmid.la $< libmodglue.la: process.lo pipe.lo main.lo ext_process.lo ${LPHASE} -o libmodglue.la `pkg-config sigc++-2.0 --libs` $^ #------- Tests ---------------------------------------- test_child_process: test_child_process.o ${MPHASE} -o test_child_process $< libmodglue.la test_ext_process: test_ext_process.o ${MPHASE} -o test_ext_process $< libmodglue.la test_pipe: test_pipe.o ${MPHASE} -o test_pipe $< libmodglue.la test_writes: test_writes.o ${MPHASE} -o test_writes $< libmodglue.la #------- Tools ---------------------------------------- prompt: prompt.o ${MPHASE} -o prompt prompt.o `pkg-config sigc++-2.0 --libs` libmodglue.la # chrpath -d .libs/prompt prompt_static: prompt.cc library ${CPHASE} ${TIMESTAMP} -o prompt.o \ -I@top_srcdir@/include -DSTATICBUILD `pkg-config sigc++-2.0 --cflags` prompt.cc ifeq ($(strip $(MACTEST)),) g++ -o prompt -static prompt.o -L.libs `pkg-config sigc++-2.0 --libs` -lmodglue -lsigc-2.0 else g++ -o prompt prompt.o ./.libs/libmodglue.a \ `pkg-config sigc++-2.0 --libs | sed -e 's/ .*//' -e 's/-L//'`/libsigc-2.0.a endif ptywrap: ptywrap.o ${MPHASE} -o ptywrap ptywrap.o @LINK_UTIL@ ptywrap_static: ptywrap.o ${CPHASE} ${TIMESTAMP} -o ptywrap.o \ -I@top_srcdir@/include -DSTATICBUILD ptywrap.cc ifeq ($(strip $(MACTEST)),) g++ -o ptywrap -static ptywrap.o -L.libs @LINK_UTIL@ else g++ -o ptywrap ptywrap.o ./.libs/libmodglue.a \ `pkg-config sigc++-2.0 --libs | sed -e 's/ .*//' -e 's/-L//'`/libsigc-2.0.a @LINK_UTIL@ endif isatty: isatty.o @CXX@ -o isatty $< #------- Library -------------------------------------- install: library tools ifeq ($(strip ${DEVDESTDIR}),) DEVDESTDIR=${DESTDIR} endif @INSTALL@ -m 755 -d ${DESTDIR}@prefix@ @INSTALL@ -m 755 -d ${DESTDIR}@prefix@/@libdir@ @INSTALL@ -m 755 -d ${DEVDESTDIR}@prefix@/@libdir@ @INSTALL@ -m 755 -d ${DESTDIR}@prefix@/bin @INSTALL@ -m 755 -d ${DEVDESTDIR}@prefix@/include/modglue ${IPHASE} libmodglue.la ${DESTDIR}@prefix@/@libdir@ ifneq ($(DESTDIR),$(DEVDESTDIR)) mv ${DESTDIR}@prefix@/@libdir@/libmodglue*.so ${DEVDESTDIR}@prefix@/@libdir@ endif # ${IPHASE} libmid.la ${DESTDIR}@prefix@/lib ${FPHASE} ${IPHASE} ptywrap ${DESTDIR}@prefix@/bin ${IPHASE} prompt ${DESTDIR}@prefix@/bin # ${IPHASE} isatty ${DESTDIR}@prefix@/bin @INSTALL@ -m 0644 ../include/modglue/ext_process.hh ${DEVDESTDIR}@prefix@/include/modglue @INSTALL@ -m 0644 ../include/modglue/process.hh ${DEVDESTDIR}@prefix@/include/modglue @INSTALL@ -m 0644 ../include/modglue/pipe.hh ${DEVDESTDIR}@prefix@/include/modglue @INSTALL@ -m 0644 ../include/modglue/main.hh ${DEVDESTDIR}@prefix@/include/modglue clean: rm -f *.o *.lo *~ libmodglue* libmid* rm -f ${TESTS} ${TOOLS} ptywrap_static prompt_static distclean: clean rm -f Makefile rm -Rf .libs #------- Disabled ---------------------------------------- # open.o: open.c # @CC@ @CFLAGS@ `dlobject --cflags` -I@top_srcdir@/include -c -o $@ $< # # shell.o: shell.cc # @CXX@ -o shell.o -I@top_srcdir@/include `proj++-config --cflags` `pkg-config sigc++-2.0 --cflags` -c $< # # modshell: modshell.o shell.o # @CXX@ -o modshell -L. `proj++-config --libs` `pkg-config sigc++-2.0 --libs` $^ -lmodglue # # preload: libpipe.so.${VERSION} # # libpipe.so.${VERSION}: open.o # @CC@ `dlobject --visiblename=libpipe.so.${VVERSION} --lflags` -o libpipe.so.${VERSION} $^ -ldl # ln -f -s libpipe.so.${VERSION} libpipe.so # modglue-1.19/src/ext_process.cc000066400000000000000000000250771211224010400165320ustar00rootroot00000000000000/* Extended process class. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace modglue; ext_process::ext_process(const std::string& name) : name_(name), modglue_binary_(false), pid_(0), paused_(false), exit_code_(0), pipes_done_(false) { } ext_process::ext_process(const std::string& name, const std::vector& args) : name_(name), args_(args), modglue_binary_(false), pid_(0), paused_(false), exit_code_(0), pipes_done_(false) { } ext_process::ext_process(const ext_process& other) : name_(other.name_), args_(other.args_), modglue_binary_(false), pid_(0), paused_(false), exit_code_(0), pipes_done_(false) { } ext_process::~ext_process() { for(unsigned int i=0; i& ext_process::output() const { return output_; } const std::vector& ext_process::input_pipes() const { return input_pipes_; } const std::vector& ext_process::output_pipes() const { return output_pipes_; } ipipe* ext_process::input_pipe(const std::string& name) const { for(unsigned int i=0; iname()==name) return input_pipes_[i]; } throw std::logic_error("ext_process::input_pipe: pipe "+name+" not known"); } opipe* ext_process::output_pipe(const std::string& name) const { for(unsigned int i=0; iname()==name) return output_pipes_[i]; } throw std::logic_error("ext_process::output_pipe: pipe "+name+" not known"); } ext_process& ext_process::operator<<(const std::string& st) { args_.push_back(st); return (*this); } void ext_process::fork() { assert(pid_==0); if(!pipes_done_) setup_pipes(); open_pipes_(); // std::cerr << "pipes open for " << name_ << std::endl; std::vector realargs=args_; // add '--pipe' arguments for modglue binaries if(modglue_binary_) { for(unsigned int i=0; ifd_external() << std::ends; realargs.push_back(tmp.str()); } for(unsigned int i=0; ifd_external() << std::ends; realargs.push_back(tmp.str()); } } // convert args to something that execvp groks const char *cargs[realargs.size()+2]; cargs[0]=name_.c_str(); for(unsigned int i=0; i(cargs)); throw std::logic_error("modglue::ext_process::fork: execvp failed"); break; default: // we are the parent close_childside_(); break; } } void ext_process::close_childside_(void) { for(unsigned int i=0; iclose_external(); for(unsigned int i=0; iclose_external(); } void ext_process::close_parentside_(void) { for(unsigned int i=0; iclose(); for(unsigned int i=0; iclose(); } void ext_process::terminate(int exit_code) { for(unsigned int i=0; iclose(); for(unsigned int i=0; iclose(); exit_code_=exit_code; if(pid_!=0) { if(kill(pid_, 0)) kill(pid_, SIGTERM); pid_=0; } } void ext_process::pause() { if(pid_!=0 && !paused_) { if(kill(pid_, 0)) kill(pid_, SIGSTOP); paused_=true; } } void ext_process::restart() { if(pid_!=0 && paused_) { if(kill(pid_, 0)) kill(pid_, SIGCONT); paused_=false; } } bool ext_process::receive_output_(ipipe& p) { // std::cerr << "received output" << std::endl; for(unsigned int i=0; iopen(); } for(unsigned int i=0; iopen(); } } void ext_process::dup_unix_pipes_(void) { assert(!modglue_binary_); for(unsigned int i=0; iname()=="stdin") { if(::dup2(output_pipes_[i]->fd_external(), 0)<0) throw std::logic_error("modglue::ext_process::fork: dup2 failed"); ::close(output_pipes_[i]->fd_external()); // is dupped, so no longer needed ::close(output_pipes_[i]->fd()); // parent side } } for(unsigned int i=0; iname()=="stdout") { if(::dup2(input_pipes_[i]->fd_external(), 1)<0) throw std::logic_error("modglue::child_process::fork: dup2 failed"); ::close(input_pipes_[i]->fd_external()); ::close(input_pipes_[i]->fd()); // parent side } else if(input_pipes_[i]->name()=="stderr") { if(::dup2(input_pipes_[i]->fd_external(), 2)<0) throw std::logic_error("modglue::child_process::fork: dup2 failed"); ::close(input_pipes_[i]->fd_external()); ::close(input_pipes_[i]->fd()); // parent side } } } void ext_process::setup_pipes(void) { assert(output_pipes_.size()==0); assert(input_pipes_.size()==0); determine_path_(); determine_binary_type_(); // std::cerr << "path: |" << full_path_ << "|" << std::endl // << "type: " << (modglue_binary_?"modglue":"unix") << std::endl; if(modglue_binary_) { output_pipes_.push_back(new opipe("startup_args")); child_process pr_tst(full_path_); pr_tst.args.push_back("--list-pipes"); std::string result; pr_tst.call("", result); // std::cout << "|" << result << "|" << std::endl; setup_pipes_from_string_(result); if(input_pipes_.size()==0 && output_pipes_.size()==1) throw std::logic_error("moglue::ext_process::setup_pipes: process reports no pipes."); } else { // direction has to be flipped since we are at the other side output_pipes_.push_back(new opipe("startup_args")); output_pipes_.push_back(new opipe("stdin")); input_pipes_.push_back(new ipipe("stdout")); input_pipes_.push_back(new ipipe("stderr")); for(unsigned int i=0; iset_unix_style(); for(unsigned int i=0; iset_unix_style(); } pipes_done_=true; } modglue-1.19/src/gtkiowin.cc000066400000000000000000000103031211224010400160110ustar00rootroot00000000000000/* Modglue & Gtk-- based program to view traffic on pipes. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include #include #include #include #include #include #include #include class PipeView : public Gtk::Window { public: PipeView(void); void print(const string& txt); void excprint(const string& txt); void cb_erase(void); void cb_send(void); int delete_event_impl(GdkEventAny *event); private: Gtk::VBox vb1_; Gtk::HBox hb1_; Gtk::ToggleButton tb1_, tb2_; Gtk::Entry out_; Gtk::ScrolledWindow sw_; Gtk::Text monitor_; Gtk::Button but_; Gdk_Color black,white,red; Gdk_Font fixed_font; }; PipeView::PipeView(void) : tb1_("send double lf"), tb2_("strip input lf"), but_("clear") { add(vb1_); vb1_.pack_start(out_,false); vb1_.pack_start(hb1_,false); hb1_.pack_start(tb1_,true); hb1_.pack_start(tb2_,true); vb1_.pack_start(sw_,true); sw_.add(monitor_); monitor_.set_usize(200,300); vb1_.pack_start(but_,false); vb1_.show_all(); red.set_rgb(0xffff,0,0); white.set_rgb(0xffff,0xffff,0xffff); black.set_rgb(0,0,0); monitor_.set_editable(false); but_.clicked.connect(slot(this,&PipeView::cb_erase)); out_.activate.connect(slot(this,&PipeView::cb_send)); } int PipeView::delete_event_impl(GdkEventAny *) { Gtk::Main::quit(); return 0; } void PipeView::cb_erase(void) { monitor_.set_point(0); monitor_.forward_delete(monitor_.get_length()); } void PipeView::print(const string& txt) { string tmp=txt; monitor_.freeze(); if(tb2_.get_active()) if(txt[txt.size()-1]=='\n') tmp=txt.substr(0,txt.size()-1); if(txt[tmp.size()-1]=='\004') tmp=tmp.substr(0,tmp.size()-1)+"\n--EOF--\n"; monitor_.insert(fixed_font, black, white, tmp, -1); monitor_.thaw(); } void PipeView::excprint(const string& txt) { monitor_.freeze(); // cerr << "|" << txt << "| " << txt.size() << endl; monitor_.insert(fixed_font, red, white, txt, -1); monitor_.thaw(); } modglue::pipe *outpipe;; modglue::pipe *foopipe; modglue::pipe *excpipe; map connections; void PipeView::cb_send(void) { try { if(tb1_.get_active()) outpipe->sender(out_.get_text()+"\n\n"); else outpipe->sender(out_.get_text()+"\n"); } catch(exception &ex) { // cerr << "caught writing exception: " << ex.what() << endl; } } void callmm(int fd, GdkInputCondition, modglue::main *mm) { if(!(mm->select_callback(fd))) { connections[fd].disconnect(); } } int main(int argc, char **argv) { modglue::main *mm=new modglue::main(argc, argv); Gtk::Main mymain(&argc, &argv); outpipe =new modglue::pipe("stdout", modglue::pipe::output, 1); foopipe =new modglue::pipe("stdin", modglue::pipe::input, 0); excpipe =new modglue::pipe("stdexc", modglue::pipe::input, 2); mm->add(outpipe); mm->add(foopipe); mm->add(excpipe); if(mm->check()) { PipeView mp; foopipe->receiver.connect(SigC::slot(&mp,&PipeView::print)); excpipe->receiver.connect(SigC::slot(&mp,&PipeView::excprint)); mp.show(); for(unsigned int i=0; ipipes().size(); ++i) { connections[mm->pipes()[i]->get_fd()]=Gtk::Main::input.connect(bind(SigC::slot(&callmm),mm), mm->pipes()[i]->get_fd(), (GdkInputCondition)(GDK_INPUT_READ|GDK_INPUT_EXCEPTION)); } mymain.run(); } } modglue-1.19/src/gtkshell.cc000066400000000000000000000563611211224010400160110ustar00rootroot00000000000000/* Gtk shell for modglue. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* If we want to eg. use wget to fetch network data, we need some way to make `blocked' data transfer possible such that we know when a certain write has finished. The latter can be faked by requiring a null or something like that at the end for the time being. BETTER: use sendmsg. echo "http://www.somewhere.net" | sed -e 's/\(.*\)/\1 -q -O -/' Also make it possible to write out the data stored in the loader object in a file and reload it at a later stage. */ class ProcessView; modglue::pipe *inforeq; modglue::pipe *infodump; modglue::pipe *fddump; class BondItem : public Gtk::TreeItem { public: BondItem(modglue::Bond *bd, ProcessView *owner); void refresh_subtree(void); // call this when bond_ content changes modglue::Bond *bond_; private: Gtk::Tree pipetree_; ProcessView *owner_; }; class InfoItem : public Gtk::TreeItem { public: InfoItem(modglue::pipeinfo *); modglue::pipeinfo *get_pipeinfo(void) const; private: modglue::pipeinfo *info_; }; class ASpaceItem : public Gtk::TreeItem { public: ASpaceItem(const string& name, ProcessView *owner); private: Gtk::Tree proctree_; std::vector proc_items_; modglue::process *proc_; ProcessView *owner_; }; class ToggleItem : public Gtk::TreeItem { public: ToggleItem(const string& name); Gtk::CheckButton *button(void); void select_impl(void) {} ; private: Gtk::CheckButton *cb_; }; class ProcessItem : public Gtk::TreeItem { public: ProcessItem(const string& name, ProcessView *owner); void activate_subtree(modglue::process *); const vector& info_items(void) const; void update_pipe_subtree(void); modglue::process *get_process(void) const; void toggle_event(Gtk::CheckButton *tb); ToggleItem toggle_start_on_input_; ToggleItem toggle_abort_on_failed_write_; private: Gtk::Tree infotree_; std::vector info_items_; modglue::process *proc_; ProcessView *owner_; ToggleItem toggle_restart_after_exit_; }; class ProcessView : public Gtk::Window { public: ProcessView(int argc, char **argv, modglue::main& mn); ~ProcessView(); void cb_select_child(Gtk::Widget& child,Gtk::Tree *root_tree, Gtk::Tree *subtree); void cb_unselect_child(Gtk::Widget& child,Gtk::Tree *root_tree, Gtk::Tree *subtree); void cb_add_proc(void); void cb_run_proc(void); void cb_kill_proc(void); void cb_connect(void); void cb_generate(void); void cb_hide(void); void cb_remove_bonds(void); int delete_event_impl(GdkEventAny *); void io_callback(int fd, GdkInputCondition); void inforeq_cb(const string&); void popup_window(int fd, GdkInputCondition); bool no_window; private: void setup_tables_(int argc, char **argv); Gtk::ScrolledWindow sw,bsw; Gtk::Tree tr; // for address spaces and processes Gtk::Tree btr; // for bonds Gtk::VBox vb0,vb1,vb2; Gtk::HBox hb0,hb1,hb2,hb3,hb4,hb_misc; Gtk::Label l_newproc, l_newid, l_newaddr; Gtk::Entry e_procname, e_newid, e_addrname; Gtk::Button b_newproc, b_newaddr; Gtk::Button b_kill, b_connect, b_remove, b_run, b_cremove, b_generate, b_hide; std::vector processes_; std::vector bonds_; std::map fdhandlers_; modglue::main &main_; }; ToggleItem::ToggleItem(const string& name) : Gtk::TreeItem(name) { remove(); Gtk::HBox *hb=new Gtk::HBox; add(*(manage(hb))); cb_=new Gtk::CheckButton(); hb->pack_start(*(manage(cb_)),false); hb->pack_start(*(manage(new Gtk::Label(name))),false); show_all(); } Gtk::CheckButton *ToggleItem::button(void) { return cb_; } int ProcessView::delete_event_impl(GdkEventAny *) { modglue::loader::instance().quit(); Gtk::Main::quit(); return 0; } BondItem::BondItem(modglue::Bond *bd, ProcessView *ow) : bond_(bd), owner_(ow), Gtk::TreeItem(bd->name) { } void BondItem::refresh_subtree(void) { set_subtree(pipetree_); modglue::Bond::const_iterator it=bond_->pipes.begin(); while(it!=bond_->pipes.end()) { Gtk::TreeItem *tmp=new Gtk::TreeItem((*it).first->get_name()+":"+ (*it).first->pipes[(*it).second]->get_name()); pipetree_.tree().push_back(*(manage(tmp))); tmp->show_all(); ++it; } } InfoItem::InfoItem(modglue::pipeinfo *inf) : info_(inf), Gtk::TreeItem(" "+inf->get_name()+ ((inf->get_inout()==modglue::pipeinfo::input)?" (input)":" (output)") ) { } modglue::pipeinfo *InfoItem::get_pipeinfo(void) const { return info_; } ProcessItem::ProcessItem(const string& name, ProcessView *owner) : Gtk::TreeItem(name), owner_(owner), toggle_start_on_input_("start on input"), toggle_abort_on_failed_write_("abort on failed write"), toggle_restart_after_exit_("restart after exit") { } void ProcessItem::activate_subtree(modglue::process *proc) { proc_=proc; set_subtree(infotree_); infotree_.select_child.connect(bind(SigC::slot(owner_,&ProcessView::cb_select_child), &infotree_, &infotree_)); infotree_.append(toggle_start_on_input_); infotree_.append(toggle_abort_on_failed_write_); // infotree_.append(toggle_restart_after_exit_); toggle_start_on_input_.show_all(); toggle_abort_on_failed_write_.show_all(); // toggle_restart_after_exit_.show_all(); toggle_start_on_input_.button()->toggled.connect(SigC::bind(SigC::slot(this, &ProcessItem::toggle_event), toggle_start_on_input_.button())); toggle_abort_on_failed_write_.button()->toggled.connect( SigC::bind(SigC::slot(this, &ProcessItem::toggle_event), toggle_abort_on_failed_write_.button())); toggle_restart_after_exit_.button()->toggled.connect(SigC::bind(SigC::slot(this, &ProcessItem::toggle_event), toggle_restart_after_exit_.button())); update_pipe_subtree(); } void ProcessItem::update_pipe_subtree(void) { // This only _adds_, it cannot yet handle removals (but modglue cannot either). for(unsigned int i=info_items_.size(); ipipes.size(); ++i) { info_items_.push_back(new InfoItem(proc_->pipes[i])); infotree_.append(*(info_items_.back())); info_items_.back()->show_all(); } } const vector& ProcessItem::info_items(void) const { return info_items_; } modglue::process *ProcessItem::get_process(void) const { return proc_; } void ProcessItem::toggle_event(Gtk::CheckButton *tb) { bool onoff=tb->get_active(); if(tb==toggle_start_on_input_.button()) proc_->start_on_input=onoff; else if(tb==toggle_abort_on_failed_write_.button()) proc_->abort_on_failed_write=onoff; else proc_->restart_after_exit=onoff; } ProcessView::ProcessView(int argc, char **argv, modglue::main& mn) : no_window(false), l_newproc("program:"), l_newid("unique id:"), b_newproc("new process"), l_newaddr("space name:"), b_newaddr("new address space"), b_kill("kill"), b_connect("connect"), b_remove("remove proc"), b_run("run"), b_cremove("remove bond"), b_generate("generate script"), b_hide("hide"), main_(mn) { add(vb0); vb0.pack_start(hb2, false); // vb0.pack_start(hb3,false); vb0.add(hb0); hb0.pack_start(vb1,true); hb0.pack_start(vb2,true); vb1.pack_start(sw, true); sw.add_with_viewport(tr); vb2.pack_start(bsw,true); bsw.add_with_viewport(btr); tr.select_child.connect(bind(SigC::slot(this,&ProcessView::cb_select_child), &tr, &tr)); tr.unselect_child.connect(bind(SigC::slot(this,&ProcessView::cb_unselect_child), &tr, &tr)); vb1.pack_start(hb1, false); hb1.add(b_connect); hb1.add(b_run); hb1.add(b_kill); hb1.add(b_remove); vb2.pack_start(hb4, false); hb4.add(b_cremove); vb2.pack_start(hb_misc,false); hb_misc.pack_start(b_generate,true); hb_misc.pack_start(b_hide,false); hb2.pack_start(l_newproc,false); hb2.pack_start(e_procname,true); hb2.pack_start(l_newid,false); hb2.pack_start(e_newid,true); hb2.pack_start(b_newproc,false); hb3.pack_start(l_newaddr,false); hb3.pack_start(e_addrname,true); hb3.pack_start(b_newaddr,false); b_newproc.clicked.connect(SigC::slot(this,&ProcessView::cb_add_proc)); e_procname.activate.connect(SigC::slot(this,&ProcessView::cb_add_proc)); e_newid.activate.connect(SigC::slot(this,&ProcessView::cb_add_proc)); b_connect.clicked.connect(SigC::slot(this,&ProcessView::cb_connect)); b_generate.clicked.connect(SigC::slot(this,&ProcessView::cb_generate)); b_run.clicked.connect(SigC::slot(this,&ProcessView::cb_run_proc)); b_kill.clicked.connect(SigC::slot(this,&ProcessView::cb_kill_proc)); b_hide.clicked.connect(SigC::slot(this,&ProcessView::cb_hide)); b_cremove.clicked.connect(SigC::slot(this,&ProcessView::cb_remove_bonds)); vb1.show_all(); b_kill.set_sensitive(false); b_remove.set_sensitive(false); // b_run.set_sensitive(false); tr.set_selection_mode(GTK_SELECTION_MULTIPLE); setup_tables_(argc, argv); } void ProcessView::cb_select_child(Gtk::Widget& child,Gtk::Tree *root_tree, Gtk::Tree *subtree) { Gtk::Tree::SelectionList &selection=tr.selection(); if(selection.empty()) { // b_run.set_sensitive(false); b_remove.set_sensitive(false); b_kill.set_sensitive(false); } else { // b_run.set_sensitive(true); b_remove.set_sensitive(true); b_kill.set_sensitive(true); } } void ProcessView::cb_unselect_child(Gtk::Widget& child,Gtk::Tree *root_tree, Gtk::Tree *subtree) { } void ProcessView::cb_add_proc(void) { ProcessItem *it=new ProcessItem(e_procname.get_text(), this); vector args; modglue::loader::instance().convert_to_args(e_procname.get_text(), args); modglue::process *proc=modglue::loader::instance().load(args); if(e_newid.get_text()!="" && e_newid.get_text()!=e_procname.get_text()) proc->set_id(e_newid.get_text()); for(unsigned int i=0; iget_process()->get_id()==proc->get_id() || processes_[i]->get_process()->get_name()==proc->get_id() ) { cerr << "module with id " << proc->get_id() << " already present" << endl; delete it; // FIXME: remove proc from loader return; } } tr.append(*it); it->activate_subtree(proc); processes_.push_back(it); it->expand(); it->show(); } void ProcessView::cb_run_proc(void) { // first start all processes vector changed; // keep track of which process changed status for(unsigned int k=0; kget_process()->has_sockets()==false) { if(processes_[k]->get_process()->get_pid()==0) { modglue::loader::instance().start(processes_[k]->get_process()); Gtk::Label *pl=dynamic_cast(processes_[k]->get_child()); assert(pl!=0); if(processes_[k]->get_process()->start_on_input) pl->set_text(processes_[k]->get_process()->get_name()+" (standby)"); else pl->set_text(processes_[k]->get_process()->get_name()+" (running)"); changed.push_back(processes_[k]); } } } // then add to the select loop for(unsigned int k=0; kget_process()->pipes.size(); ++i) { if(changed[k]->get_process()->pipes[i]->get_fd()!=-1) { if(changed[k]->get_process()->pipes[i]->get_inout()==modglue::pipeinfo::output) { fdhandlers_[changed[k]->get_process()->pipes[i]->get_fd()]= Gtk::Main::input.connect(slot(this,&ProcessView::io_callback), changed[k]->get_process()->pipes[i]->get_fd(), (GdkInputCondition)(GDK_INPUT_READ)); } // cerr << "adding " << changed[k]->get_process()->pipes[i]->fd() << endl; } } } } void ProcessView::cb_kill_proc(void) { Gtk::Tree::SelectionList &selection=tr.selection(); Gtk::Tree::SelectionList::iterator i=selection.begin(); vector > sels; while(i!=selection.end()) { Gtk::TreeItem *item = (*i); Gtk::Label *label = dynamic_cast(item->get_child()); if(label!=0) { // only if this is a properstupid selections of non-pipe items... string name=label->get(); for(unsigned int k=0; k(processes_[k])==item) { modglue::loader::instance().kill_process(processes_[k]->get_process()); break; } } } ++i; } } void ProcessView::cb_hide(void) { hide_all(); } void ProcessView::cb_remove_bonds(void) { Gtk::Tree::SelectionList &selection=btr.selection(); Gtk::Tree::SelectionList::iterator i=selection.begin(); while(i!=selection.end()) { BondItem *bitem = dynamic_cast(*i); if(bitem) { Gtk::Tree_Helpers::ItemList::iterator ili=btr.tree().begin(); while(ili!=btr.tree().end()) { if((*ili)==bitem) { modglue::loader::instance().remove_bond(bitem->bond_); // FIXME: if processes are running, we have to remove the fd listening // too. This will require the signalling pipe in modglue, otherwise // we end up with races. Perhaps remove_bond() should contain that logic. // FIXME: also remove it from the bonds_ container in processview; (*ili)->hide(); btr.remove_item(**ili); break; } ++ili; } } ++i; } } void ProcessView::io_callback(int fd, GdkInputCondition) { vector proc; vector remfds, addfds; modglue::loader::instance().select_callback(fd, proc, remfds, addfds); for(unsigned int i=0; iget_pid()==0) { if(proc[k]->has_sockets()==false) txt=proc[k]->get_name(); else txt=proc[k]->get_name()+" (standby)"; } else { txt=proc[k]->get_name()+" (running)"; } for(unsigned int i=0; iget_process()==proc[k]) { processes_[i]->update_pipe_subtree(); Gtk::Label *pl=dynamic_cast(processes_[i]->get_child()); assert(pl!=0); pl->set_text(txt); break; } } } } void ProcessView::setup_tables_(int argc, char **argv) { int i=1; string argbit; ProcessItem *current_module_=0; while(i args; modglue::loader::instance().convert_to_args(obj, args); modglue::process *proc=modglue::loader::instance().load(args); current_module_->activate_subtree(proc); // current_module_->expand(); current_module_->show(); } else if(argbit.substr(0,5)=="--id=") { assert(current_module_!=0); current_module_->get_process()->set_id(argbit.substr(5)); } else if(argbit.substr(0,9)=="--options") { if(argbit.substr(10)=="start_on_input") { current_module_->get_process()->start_on_input=true; current_module_->toggle_start_on_input_.button()->set_active(true); } else if(argbit.substr(10)=="abort_on_failed_write") { current_module_->get_process()->abort_on_failed_write=true; current_module_->toggle_abort_on_failed_write_.button()->set_active(true); } } else if(argbit.substr(0,7)=="--bond=") { unsigned int pos=0; string subarg=argbit.substr(6); vector > pps; do { subarg=subarg.substr(pos+1); string argument=subarg.substr(0,subarg.find_first_of(",")); string prog=argument.substr(0,argument.find_first_of(":")); string pip =argument.substr(argument.find_first_of(":")+1); // cerr << prog << "|" << pip << endl; pair tmp; tmp.second=-1; for(unsigned int i=0; iget_process()->get_id()==prog) { tmp.first=processes_[i]->get_process(); for(unsigned int j=0; jpipes.size(); ++j) { // cerr << tmp.first->get_name() << ":" << tmp.first->pipes[j]->get_name() << endl; if(tmp.first->pipes[j]->get_name()==pip) { tmp.second=j; break; } } break; } } if(tmp.first==0) { cerr << "module " << prog << " not declared." << endl; continue; } if(tmp.second==-1) { cerr << "no pipe " << pip << " in module " << prog << endl; continue; } pps.push_back(tmp); } while((pos=subarg.find_first_of(","))pipes.insert(pps[j]); } modglue::loader::instance().add_bond(bd); BondItem *bi=new BondItem(bd, this); bonds_.push_back(bi); btr.tree().push_back(*bi); bi->refresh_subtree(); bi->expand(); bi->show(); } else { // cerr << "unknown argument " << argbit << endl; } ++i; } } void ProcessView::inforeq_cb(const string& inf) { if(inf.substr(0,10)=="list-pipes") { string tmp=main_.build_pipe_list(); infodump->sender(tmp); } else if(inf.substr(0,10)=="list-bonds") { } else if(inf.substr(0,4)=="add ") { infodump->sender("adding "+inf.substr(4)); string obj=inf.substr(4); if(obj[obj.size()-1]=='\n') obj=obj.substr(0,obj.size()-1); ProcessItem *current_module_=new ProcessItem(obj,this); processes_.push_back(current_module_); tr.append(*current_module_); vector args; modglue::loader::instance().convert_to_args(obj, args); modglue::process *proc=modglue::loader::instance().load(args); current_module_->activate_subtree(proc); current_module_->expand(); current_module_->show(); infodump->sender("creating"); vector addfds; modglue::loader::instance().create_forward_pipes(proc, fddump, addfds); for(unsigned int i=0; i > sels; while(i!=selection.end()) { Gtk::TreeItem *item = (*i); Gtk::Label *label = dynamic_cast(item->get_child()); if(label!=0) { // stupid selections of non-pipe items... string name=label->get(); for(unsigned int k=0; k(processes_[k])==item) { // cerr << "main: " << processes_[k] << " " << name << endl; break; } for(unsigned m=0; minfo_items().size(); ++m) { if(processes_[k]->info_items()[m]==item) { sels.push_back(pair(k,m)); // cerr << "pipe: " << processes_[k]->info_items()[m]->get_pipeinfo()->get_name() // << " of process " << processes_[k]->get_process()->get_name() << endl; } } } } ++i; } modglue::Bond *bd=new modglue::Bond("bond"); for(unsigned int j=0; jinfo_items()[sels[j].second]; Gtk::Label *pl=dynamic_cast(inf->get_child()); assert(pl!=0); bd->pipes.insert(pair(processes_[sels[j].first]->get_process(), sels[j].second)); // pl->set_text("C "+inf->get_pipeinfo()->get_name()+ // ((inf->get_pipeinfo()->get_inout()==modglue::pipeinfo::input)?" (input)":" (output)")); } modglue::loader::instance().add_bond(bd); BondItem *bi=new BondItem(bd, this); bonds_.push_back(bi); btr.tree().push_back(*bi); bi->refresh_subtree(); bi->expand(); bi->show(); /* for(unsigned int i=0; ideselect(); ++i; } */ } ProcessView::~ProcessView() { for(unsigned int i=0; iadd(inforeq); mm->add(infodump); mm->add(fddump); if(mm->check()) { ProcessView pv(argc, argv, *mm); pv.set_usize(400,500); if(pv.no_window==false) { pv.show_all(); } inforeq->receiver.connect(SigC::slot(pv,&ProcessView::inforeq_cb)); Gtk::Main::input.connect(slot(pv,&ProcessView::io_callback), modglue::loader::instance().sig_chld_pipe_[0], (GdkInputCondition)(GDK_INPUT_READ|GDK_INPUT_EXCEPTION)); if(inforeq->get_fd()!=-1) { Gtk::Main::input.connect(slot(pv,&ProcessView::io_callback), inforeq->get_fd(), (GdkInputCondition)(GDK_INPUT_READ|GDK_INPUT_EXCEPTION)); } // quick trick to allow us to pop up a window by sending something to stdin; should // be replaced with a handler that listens to SIGHUP or something like that. Gtk::Main::input.connect(slot(pv,&ProcessView::popup_window), 0, (GdkInputCondition)(GDK_INPUT_READ|GDK_INPUT_EXCEPTION)); try { if(pv.no_window) pv.cb_run_proc(); mymain.run(); } catch(exception &ex) { cerr << "[exception]: " << ex.what() << endl; } } } modglue-1.19/src/gtkshell2.cc000066400000000000000000000564001211224010400160650ustar00rootroot00000000000000/* Gtk based moglue shell. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* If we want to eg. use wget to fetch network data, we need some way to make `blocked' data transfer possible such that we know when a certain write has finished. The latter can be faked by requiring a null or something like that at the end for the time being. BETTER: use sendmsg. echo "http://www.somewhere.net" | sed -e 's/\(.*\)/\1 -q -O -/' Also make it possible to write out the data stored in the loader object in a file and reload it at a later stage. */ class ProcessView; modglue::pipe *inforeq; modglue::pipe *infodump; modglue::pipe *fddump; class BondItem : public Gtk::TreeItem { public: BondItem(modglue::Bond *bd, ProcessView *owner); void refresh_subtree(void); // call this when bond_ content changes // modglue::Bond *bond_; private: Gtk::Tree pipetree_; ProcessView *owner_; }; class InfoItem : public Gtk::TreeItem { public: InfoItem(modglue::pipeinfo *); // modglue::pipeinfo *get_pipeinfo(void) const; private: // modglue::pipeinfo *info_; }; class ASpaceItem : public Gtk::TreeItem { public: ASpaceItem(const string& name, ProcessView *owner); private: Gtk::Tree proctree_; std::vector proc_items_; // modglue::process *proc_; ProcessView *owner_; }; class ToggleItem : public Gtk::TreeItem { public: ToggleItem(const string& name); Gtk::CheckButton *button(void); void select_impl(void) {} ; private: Gtk::CheckButton *cb_; }; class ProcessItem : public Gtk::TreeItem { public: ProcessItem(const string& name, ProcessView *owner); void activate_subtree(modglue::process *); const vector& info_items(void) const; void update_pipe_subtree(void); // modglue::process *get_process(void) const; void toggle_event(Gtk::CheckButton *tb); ToggleItem toggle_start_on_input_; ToggleItem toggle_abort_on_failed_write_; private: Gtk::Tree infotree_; std::vector info_items_; // modglue::process *proc_; ProcessView *owner_; ToggleItem toggle_restart_after_exit_; }; class ProcessView : public Gtk::Window { public: ProcessView(int argc, char **argv, modglue::main& mn); ~ProcessView(); void cb_select_child(Gtk::Widget& child,Gtk::Tree *root_tree, Gtk::Tree *subtree); void cb_unselect_child(Gtk::Widget& child,Gtk::Tree *root_tree, Gtk::Tree *subtree); void cb_add_proc(void); void cb_run_proc(void); void cb_kill_proc(void); void cb_connect(void); void cb_generate(void); void cb_hide(void); void cb_remove_bonds(void); int delete_event_impl(GdkEventAny *); void io_callback(int fd, GdkInputCondition); void inforeq_cb(const string&); void popup_window(int fd, GdkInputCondition); bool no_window; private: void setup_tables_(int argc, char **argv); Gtk::ScrolledWindow sw,bsw; Gtk::Tree tr; // for address spaces and processes Gtk::Tree btr; // for bonds Gtk::VBox vb0,vb1,vb2; Gtk::HBox hb0,hb1,hb2,hb3,hb4,hb_misc; Gtk::Label l_newproc, l_newid, l_newaddr; Gtk::Entry e_procname, e_newid, e_addrname; Gtk::Button b_newproc, b_newaddr; Gtk::Button b_kill, b_connect, b_remove, b_run, b_cremove, b_generate, b_hide; std::vector processes_; std::vector bonds_; std::map fdhandlers_; // modglue::main &main_; }; ToggleItem::ToggleItem(const string& name) : Gtk::TreeItem(name) { remove(); Gtk::HBox *hb=new Gtk::HBox; add(*(manage(hb))); cb_=new Gtk::CheckButton(); hb->pack_start(*(manage(cb_)),false); hb->pack_start(*(manage(new Gtk::Label(name))),false); show_all(); } Gtk::CheckButton *ToggleItem::button(void) { return cb_; } int ProcessView::delete_event_impl(GdkEventAny *) { modglue::loader::instance().quit(); Gtk::Main::quit(); return 0; } BondItem::BondItem(modglue::Bond *bd, ProcessView *ow) : bond_(bd), owner_(ow), Gtk::TreeItem(bd->name) { } void BondItem::refresh_subtree(void) { set_subtree(pipetree_); modglue::Bond::const_iterator it=bond_->pipes.begin(); while(it!=bond_->pipes.end()) { Gtk::TreeItem *tmp=new Gtk::TreeItem((*it).first->get_name()+":"+ (*it).first->pipes[(*it).second]->get_name()); pipetree_.tree().push_back(*(manage(tmp))); tmp->show_all(); ++it; } } InfoItem::InfoItem(modglue::pipeinfo *inf) : info_(inf), Gtk::TreeItem(" "+inf->get_name()+ ((inf->get_inout()==modglue::pipeinfo::input)?" (input)":" (output)") ) { } modglue::pipeinfo *InfoItem::get_pipeinfo(void) const { return info_; } ProcessItem::ProcessItem(const string& name, ProcessView *owner) : Gtk::TreeItem(name), owner_(owner), toggle_start_on_input_("start on input"), toggle_abort_on_failed_write_("abort on failed write"), toggle_restart_after_exit_("restart after exit") { } void ProcessItem::activate_subtree(modglue::process *proc) { proc_=proc; set_subtree(infotree_); infotree_.select_child.connect(bind(SigC::slot(owner_,&ProcessView::cb_select_child), &infotree_, &infotree_)); infotree_.append(toggle_start_on_input_); infotree_.append(toggle_abort_on_failed_write_); // infotree_.append(toggle_restart_after_exit_); toggle_start_on_input_.show_all(); toggle_abort_on_failed_write_.show_all(); // toggle_restart_after_exit_.show_all(); toggle_start_on_input_.button()->toggled.connect(SigC::bind(SigC::slot(this, &ProcessItem::toggle_event), toggle_start_on_input_.button())); toggle_abort_on_failed_write_.button()->toggled.connect( SigC::bind(SigC::slot(this, &ProcessItem::toggle_event), toggle_abort_on_failed_write_.button())); toggle_restart_after_exit_.button()->toggled.connect(SigC::bind(SigC::slot(this, &ProcessItem::toggle_event), toggle_restart_after_exit_.button())); update_pipe_subtree(); } void ProcessItem::update_pipe_subtree(void) { // This only _adds_, it cannot yet handle removals (but modglue cannot either). for(unsigned int i=info_items_.size(); ipipes.size(); ++i) { info_items_.push_back(new InfoItem(proc_->pipes[i])); infotree_.append(*(info_items_.back())); info_items_.back()->show_all(); } } const vector& ProcessItem::info_items(void) const { return info_items_; } modglue::process *ProcessItem::get_process(void) const { return proc_; } void ProcessItem::toggle_event(Gtk::CheckButton *tb) { bool onoff=tb->get_active(); if(tb==toggle_start_on_input_.button()) proc_->start_on_input=onoff; else if(tb==toggle_abort_on_failed_write_.button()) proc_->abort_on_failed_write=onoff; else proc_->restart_after_exit=onoff; } ProcessView::ProcessView(int argc, char **argv, modglue::main& mn) : no_window(false), l_newproc("program:"), l_newid("unique id:"), b_newproc("new process"), l_newaddr("space name:"), b_newaddr("new address space"), b_kill("kill"), b_connect("connect"), b_remove("remove proc"), b_run("run"), b_cremove("remove bond"), b_generate("generate script"), b_hide("hide"), main_(mn) { add(vb0); vb0.pack_start(hb2, false); // vb0.pack_start(hb3,false); vb0.add(hb0); hb0.pack_start(vb1,true); hb0.pack_start(vb2,true); vb1.pack_start(sw, true); sw.add_with_viewport(tr); vb2.pack_start(bsw,true); bsw.add_with_viewport(btr); tr.select_child.connect(bind(SigC::slot(this,&ProcessView::cb_select_child), &tr, &tr)); tr.unselect_child.connect(bind(SigC::slot(this,&ProcessView::cb_unselect_child), &tr, &tr)); vb1.pack_start(hb1, false); hb1.add(b_connect); hb1.add(b_run); hb1.add(b_kill); hb1.add(b_remove); vb2.pack_start(hb4, false); hb4.add(b_cremove); vb2.pack_start(hb_misc,false); hb_misc.pack_start(b_generate,true); hb_misc.pack_start(b_hide,false); hb2.pack_start(l_newproc,false); hb2.pack_start(e_procname,true); hb2.pack_start(l_newid,false); hb2.pack_start(e_newid,true); hb2.pack_start(b_newproc,false); hb3.pack_start(l_newaddr,false); hb3.pack_start(e_addrname,true); hb3.pack_start(b_newaddr,false); b_newproc.clicked.connect(SigC::slot(this,&ProcessView::cb_add_proc)); e_procname.activate.connect(SigC::slot(this,&ProcessView::cb_add_proc)); e_newid.activate.connect(SigC::slot(this,&ProcessView::cb_add_proc)); b_connect.clicked.connect(SigC::slot(this,&ProcessView::cb_connect)); b_generate.clicked.connect(SigC::slot(this,&ProcessView::cb_generate)); b_run.clicked.connect(SigC::slot(this,&ProcessView::cb_run_proc)); b_kill.clicked.connect(SigC::slot(this,&ProcessView::cb_kill_proc)); b_hide.clicked.connect(SigC::slot(this,&ProcessView::cb_hide)); b_cremove.clicked.connect(SigC::slot(this,&ProcessView::cb_remove_bonds)); vb1.show_all(); b_kill.set_sensitive(false); b_remove.set_sensitive(false); // b_run.set_sensitive(false); tr.set_selection_mode(GTK_SELECTION_MULTIPLE); setup_tables_(argc, argv); } void ProcessView::cb_select_child(Gtk::Widget& child,Gtk::Tree *root_tree, Gtk::Tree *subtree) { Gtk::Tree::SelectionList &selection=tr.selection(); if(selection.empty()) { // b_run.set_sensitive(false); b_remove.set_sensitive(false); b_kill.set_sensitive(false); } else { // b_run.set_sensitive(true); b_remove.set_sensitive(true); b_kill.set_sensitive(true); } } void ProcessView::cb_unselect_child(Gtk::Widget& child,Gtk::Tree *root_tree, Gtk::Tree *subtree) { } void ProcessView::cb_add_proc(void) { ProcessItem *it=new ProcessItem(e_procname.get_text(), this); vector args; modglue::loader::instance().convert_to_args(e_procname.get_text(), args); modglue::process *proc=modglue::loader::instance().load(args); if(e_newid.get_text()!="" && e_newid.get_text()!=e_procname.get_text()) proc->set_id(e_newid.get_text()); for(unsigned int i=0; iget_process()->get_id()==proc->get_id() || processes_[i]->get_process()->get_name()==proc->get_id() ) { cerr << "module with id " << proc->get_id() << " already present" << endl; delete it; // FIXME: remove proc from loader return; } } tr.append(*it); it->activate_subtree(proc); processes_.push_back(it); it->expand(); it->show(); } void ProcessView::cb_run_proc(void) { // first start all processes vector changed; // keep track of which process changed status for(unsigned int k=0; kget_process()->has_sockets()==false) { if(processes_[k]->get_process()->get_pid()==0) { modglue::loader::instance().start(processes_[k]->get_process()); Gtk::Label *pl=dynamic_cast(processes_[k]->get_child()); assert(pl!=0); if(processes_[k]->get_process()->start_on_input) pl->set_text(processes_[k]->get_process()->get_name()+" (standby)"); else pl->set_text(processes_[k]->get_process()->get_name()+" (running)"); changed.push_back(processes_[k]); } } } // then add to the select loop for(unsigned int k=0; kget_process()->pipes.size(); ++i) { if(changed[k]->get_process()->pipes[i]->get_fd()!=-1) { if(changed[k]->get_process()->pipes[i]->get_inout()==modglue::pipeinfo::output) { fdhandlers_[changed[k]->get_process()->pipes[i]->get_fd()]= Gtk::Main::input.connect(slot(this,&ProcessView::io_callback), changed[k]->get_process()->pipes[i]->get_fd(), (GdkInputCondition)(GDK_INPUT_READ)); } // cerr << "adding " << changed[k]->get_process()->pipes[i]->fd() << endl; } } } } void ProcessView::cb_kill_proc(void) { Gtk::Tree::SelectionList &selection=tr.selection(); Gtk::Tree::SelectionList::iterator i=selection.begin(); vector > sels; while(i!=selection.end()) { Gtk::TreeItem *item = (*i); Gtk::Label *label = dynamic_cast(item->get_child()); if(label!=0) { // only if this is a properstupid selections of non-pipe items... string name=label->get(); for(unsigned int k=0; k(processes_[k])==item) { modglue::loader::instance().kill_process(processes_[k]->get_process()); break; } } } ++i; } } void ProcessView::cb_hide(void) { hide_all(); } void ProcessView::cb_remove_bonds(void) { Gtk::Tree::SelectionList &selection=btr.selection(); Gtk::Tree::SelectionList::iterator i=selection.begin(); while(i!=selection.end()) { BondItem *bitem = dynamic_cast(*i); if(bitem) { Gtk::Tree_Helpers::ItemList::iterator ili=btr.tree().begin(); while(ili!=btr.tree().end()) { if((*ili)==bitem) { modglue::loader::instance().remove_bond(bitem->bond_); // FIXME: if processes are running, we have to remove the fd listening // too. This will require the signalling pipe in modglue, otherwise // we end up with races. Perhaps remove_bond() should contain that logic. // FIXME: also remove it from the bonds_ container in processview; (*ili)->hide(); btr.remove_item(**ili); break; } ++ili; } } ++i; } } void ProcessView::io_callback(int fd, GdkInputCondition) { vector proc; vector remfds, addfds; modglue::loader::instance().select_callback(fd, proc, remfds, addfds); for(unsigned int i=0; iget_pid()==0) { if(proc[k]->has_sockets()==false) txt=proc[k]->get_name(); else txt=proc[k]->get_name()+" (standby)"; } else { txt=proc[k]->get_name()+" (running)"; } for(unsigned int i=0; iget_process()==proc[k]) { processes_[i]->update_pipe_subtree(); Gtk::Label *pl=dynamic_cast(processes_[i]->get_child()); assert(pl!=0); pl->set_text(txt); break; } } } } void ProcessView::setup_tables_(int argc, char **argv) { int i=1; string argbit; ProcessItem *current_module_=0; while(i args; modglue::loader::instance().convert_to_args(obj, args); modglue::process *proc=modglue::loader::instance().load(args); current_module_->activate_subtree(proc); // current_module_->expand(); current_module_->show(); } else if(argbit.substr(0,5)=="--id=") { assert(current_module_!=0); current_module_->get_process()->set_id(argbit.substr(5)); } else if(argbit.substr(0,9)=="--options") { if(argbit.substr(10)=="start_on_input") { current_module_->get_process()->start_on_input=true; current_module_->toggle_start_on_input_.button()->set_active(true); } else if(argbit.substr(10)=="abort_on_failed_write") { current_module_->get_process()->abort_on_failed_write=true; current_module_->toggle_abort_on_failed_write_.button()->set_active(true); } } else if(argbit.substr(0,7)=="--bond=") { unsigned int pos=0; string subarg=argbit.substr(6); vector > pps; do { subarg=subarg.substr(pos+1); string argument=subarg.substr(0,subarg.find_first_of(",")); string prog=argument.substr(0,argument.find_first_of(":")); string pip =argument.substr(argument.find_first_of(":")+1); // cerr << prog << "|" << pip << endl; pair tmp; tmp.second=-1; for(unsigned int i=0; iget_process()->get_id()==prog) { tmp.first=processes_[i]->get_process(); for(unsigned int j=0; jpipes.size(); ++j) { // cerr << tmp.first->get_name() << ":" << tmp.first->pipes[j]->get_name() << endl; if(tmp.first->pipes[j]->get_name()==pip) { tmp.second=j; break; } } break; } } if(tmp.first==0) { cerr << "module " << prog << " not declared." << endl; continue; } if(tmp.second==-1) { cerr << "no pipe " << pip << " in module " << prog << endl; continue; } pps.push_back(tmp); } while((pos=subarg.find_first_of(","))pipes.insert(pps[j]); } modglue::loader::instance().add_bond(bd); BondItem *bi=new BondItem(bd, this); bonds_.push_back(bi); btr.tree().push_back(*bi); bi->refresh_subtree(); bi->expand(); bi->show(); } else { // cerr << "unknown argument " << argbit << endl; } ++i; } } void ProcessView::inforeq_cb(const string& inf) { if(inf.substr(0,10)=="list-pipes") { string tmp=main_.build_pipe_list(); infodump->sender(tmp); } else if(inf.substr(0,10)=="list-bonds") { } else if(inf.substr(0,4)=="add ") { infodump->sender("adding "+inf.substr(4)); string obj=inf.substr(4); if(obj[obj.size()-1]=='\n') obj=obj.substr(0,obj.size()-1); ProcessItem *current_module_=new ProcessItem(obj,this); processes_.push_back(current_module_); tr.append(*current_module_); vector args; modglue::loader::instance().convert_to_args(obj, args); modglue::process *proc=modglue::loader::instance().load(args); current_module_->activate_subtree(proc); current_module_->expand(); current_module_->show(); infodump->sender("creating"); vector addfds; modglue::loader::instance().create_forward_pipes(proc, fddump, addfds); for(unsigned int i=0; i > sels; while(i!=selection.end()) { Gtk::TreeItem *item = (*i); Gtk::Label *label = dynamic_cast(item->get_child()); if(label!=0) { // stupid selections of non-pipe items... string name=label->get(); for(unsigned int k=0; k(processes_[k])==item) { // cerr << "main: " << processes_[k] << " " << name << endl; break; } for(unsigned m=0; minfo_items().size(); ++m) { if(processes_[k]->info_items()[m]==item) { sels.push_back(pair(k,m)); // cerr << "pipe: " << processes_[k]->info_items()[m]->get_pipeinfo()->get_name() // << " of process " << processes_[k]->get_process()->get_name() << endl; } } } } ++i; } modglue::Bond *bd=new modglue::Bond("bond"); for(unsigned int j=0; jinfo_items()[sels[j].second]; Gtk::Label *pl=dynamic_cast(inf->get_child()); assert(pl!=0); bd->pipes.insert(pair(processes_[sels[j].first]->get_process(), sels[j].second)); // pl->set_text("C "+inf->get_pipeinfo()->get_name()+ // ((inf->get_pipeinfo()->get_inout()==modglue::pipeinfo::input)?" (input)":" (output)")); } modglue::loader::instance().add_bond(bd); BondItem *bi=new BondItem(bd, this); bonds_.push_back(bi); btr.tree().push_back(*bi); bi->refresh_subtree(); bi->expand(); bi->show(); /* for(unsigned int i=0; ideselect(); ++i; } */ } ProcessView::~ProcessView() { for(unsigned int i=0; iadd(inforeq); mm->add(infodump); mm->add(fddump); if(mm->check()) { ProcessView pv(argc, argv, *mm); pv.set_usize(400,500); if(pv.no_window==false) { pv.show_all(); } inforeq->receiver.connect(SigC::slot(pv,&ProcessView::inforeq_cb)); Gtk::Main::input.connect(slot(pv,&ProcessView::io_callback), modglue::loader::instance().sig_chld_pipe_[0], (GdkInputCondition)(GDK_INPUT_READ|GDK_INPUT_EXCEPTION)); if(inforeq->get_fd()!=-1) { Gtk::Main::input.connect(slot(pv,&ProcessView::io_callback), inforeq->get_fd(), (GdkInputCondition)(GDK_INPUT_READ|GDK_INPUT_EXCEPTION)); } // quick trick to allow us to pop up a window by sending something to stdin; should // be replaced with a handler that listens to SIGHUP or something like that. Gtk::Main::input.connect(slot(pv,&ProcessView::popup_window), 0, (GdkInputCondition)(GDK_INPUT_READ|GDK_INPUT_EXCEPTION)); try { if(pv.no_window) pv.cb_run_proc(); mymain.run(); } catch(exception &ex) { cerr << "[exception]: " << ex.what() << endl; } } } modglue-1.19/src/isatty.cc000066400000000000000000000022301211224010400154730ustar00rootroot00000000000000/* Wrapper around isatty(3). Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include int main(int argc, char **argv) { std::cout << ((isatty(0)==1)?"stdin is a tty":"stdin is NOT a tty") << std::endl; std::cout << ((isatty(1)==1)?"stdout is a tty":"stdout is NOT a tty") << std::endl; std::cout << ((isatty(2)==1)?"stderr is a tty":"stderr is NOT a tty") << std::endl; return(2); } modglue-1.19/src/load000066400000000000000000000002021211224010400145060ustar00rootroot00000000000000#!/bin/sh # # This script will eventually be replaced with something that does # not rely on gtkshell. # gtkshell \ --module=$1 modglue-1.19/src/main.cc000066400000000000000000000265431211224010400151170ustar00rootroot00000000000000/* Modglue library entry points. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace modglue; int modglue::main::sig_chld_pipe_[2]; modglue::main *themm; void main::setup_signal_handlers_(void) { themm=this; if(::pipe(sig_chld_pipe_)) { throw std::logic_error("cannot create sig_chld_pipe"); } fcntl(sig_chld_pipe_[0], F_SETFL, O_NONBLOCK); struct sigaction act; act.sa_handler = &main::sig_chld_; sigemptyset(&act.sa_mask); act.sa_flags = SA_NOCLDSTOP | SA_RESTART; if(sigaction(SIGCHLD, &act, &old_sigaction_chld_) < 0) { throw std::logic_error("sigaction failed"); } act.sa_handler = &main::sig_term_; sigemptyset(&act.sa_mask); if(sigaction(SIGTERM, &act, &old_sigaction_term_) < 0) { throw std::logic_error("sigaction failed"); } // When we are in the middle of a write subroutine and the process // to which we write terminates, we catch the SIG_CLD signal but // we cannot react to that before a certain sync point. If we happen // to write to the sockets, we get a SIGPIPE. Since we handle pipe // closing afterwards, everything will be fine if we ignore this // signal. signal(SIGPIPE, SIG_IGN); } void main::restore_signal_handlers_(void) { close(sig_chld_pipe_[0]); close(sig_chld_pipe_[1]); sigaction(SIGCHLD, &old_sigaction_chld_, NULL); sigaction(SIGTERM, &old_sigaction_term_, NULL); } void main::sig_chld_(int signo) { int status; pid_t childpid; // std::cerr << "*****" << std::endl; char buffer[100]; if((childpid=waitpid(-1, &status, WNOHANG)) < 0) { if(errno==ECHILD) // No more children left, return immediately. return; else { sprintf(buffer, "waitpid failed, errno = %d", errno); throw std::logic_error(buffer); } } if(WIFEXITED(status)) { // std::cerr << "***** exited" << std::endl; int child_val = WEXITSTATUS(status); sprintf(buffer, "%ld %d", (long)childpid, child_val); write(main::sig_chld_pipe_[1], buffer, strlen(buffer)); } else if(WIFSIGNALED(status)) { // std::cerr << "***** signalled" << std::endl; sprintf(buffer, "%ld", (long)childpid); write(main::sig_chld_pipe_[1], buffer, strlen(buffer)); } } void main::sig_term_(int signo) { // This does of course not catch SIGKILL, that will still leave // process adopted by init. But there is no way around that, apparently. write(main::sig_chld_pipe_[1], "T", 1); } //----------------- main::main(void) : list_pipes_(false), argc_(0), argv_(0), terminate_main_loop_(false) { setup_signal_handlers_(); } main::main(int argc, char **argv) : list_pipes_(false), argc_(argc), argv_(argv), terminate_main_loop_(false) { setup_signal_handlers_(); int ac=1; while(acfd()==-1) { std::map::const_iterator it=pipe_fds_.find(p->name()); if(it==pipe_fds_.end()) { if(p->name()=="stdin") { throw std::logic_error("pipe name stdin and type output incompatible"); } else if(p->name()=="stdout") { p->open(1); p->set_unix_style(); } else if(p->name()=="stderr") { p->open(2); p->set_unix_style(); } else if(default_fd!=-1) { p->open(default_fd); p->set_unix_style(); } } else p->open((*it).second); } } void main::add(ipipe *p, int default_fd) { ipipes_.push_back(p); if(p->fd()==-1) { std::map::const_iterator it=pipe_fds_.find(p->name()); if(it==pipe_fds_.end()) { if(p->name()=="stdin") { p->open(0); p->set_unix_style(); } else if(p->name()=="stdout") { throw std::logic_error("pipe name stdout and type input incompatible"); } else if(p->name()=="stderr") { throw std::logic_error("pipe name stdout and type input incompatible"); } else if(default_fd!=-1) { p->open(default_fd); p->set_unix_style(); } } else p->open((*it).second); } } void main::add(ext_process *proc) { processes_.push_back(proc); for(unsigned int i=0; iinput_pipes().size(); ++i) { proc->input_pipes()[i]->process=proc; } for(unsigned int i=0; ioutput_pipes().size(); ++i) { proc->output_pipes()[i]->process=proc; } } main::~main() { // FIXME: should we terminate all processes? Not sure, we do // not own them after all. restore_signal_handlers_(); } void main::run(int min_pipes) { if(check()) select_loop_(min_pipes); } std::string main::build_pipe_list(void) const { std::stringstream str; for(unsigned int i=0; iname() << "\" , " << "input" << " }" << std::endl; } for(unsigned int i=0; iname() << "\" , " << "output" << " }" << std::endl; } str << std::ends; return str.str(); } bool main::check(void) { if(list_pipes_) { std::cout << build_pipe_list() << std::flush; return false; } else return true; } void main::last_read(void) { for(unsigned int i=0; iis_broken()==false) { ipipes_[i]->first_read_after_select(); ipipes_[i]->receiver(*(ipipes_[i])); } } for(unsigned int i=0; iinput_pipes().size(); ++k) { if(processes_[i]->input_pipes()[k]->is_broken()==false) { processes_[i]->input_pipes()[k]->first_read_after_select(); processes_[i]->input_pipes()[k]->receiver(*(processes_[i]->input_pipes()[k])); } } } } bool main::select_callback(int fd) { // debugout << "sc: " << fd << std::endl; if(fd==sig_chld_pipe_[0]) { // std::cerr << "sig_chld_pipe" << std::endl; char buffer[1024]; int pos=-1; do { pos=read(fd,buffer,1023-1); } while(pos<0 && (errno==EINTR || errno==EAGAIN)); if(pos>0) { // std::cerr << "sig_chld_pipe " << buffer[0] << std::endl; if(buffer[0]=='T') { for(unsigned int i=0; iterminate(); } exit(-1); } else { buffer[pos]=0; pid_t childpid=0; int exit_code=0; // std::cerr << buffer << std::endl; sscanf(buffer, "%ld %d", (long *)&childpid, &exit_code); // This often gets reached after cerr has gone away. Why? for(unsigned int i=0; iget_pid() << std::endl; if(processes_[i]->get_pid()==childpid) { // std::cerr << "process " << processes_[i]->name() << " exited" << std::endl; // process all unprocessed data from this process for(unsigned int lp=0; lpinput_pipes().size(); ++lp) { processes_[i]->input_pipes()[lp]->receiver(*(processes_[i]->input_pipes()[lp])); } processes_[i]->terminate(exit_code); if(process_died(*(processes_[i]))) terminate_main_loop_=true; break; } } } } else { throw std::logic_error("main::select_callback: read failed"); } return true; } for(unsigned int i=0; iis_broken()==false && ipipes_[i]->fd()==fd) { ipipes_[i]->first_read_after_select(); return ipipes_[i]->receiver(*(ipipes_[i])); } } for(unsigned int i=0; iinput_pipes().size(); ++k) { if(processes_[i]->input_pipes()[k]->is_broken()==false && processes_[i]->input_pipes()[k]->fd()==fd) { processes_[i]->input_pipes()[k]->first_read_after_select(); processes_[i]->input_pipes()[k]->receiver(*(processes_[i]->input_pipes()[k])); return true; } } } // Unknown fd, happens sometimes when processes end and a last // select woke up on an already closed pipe. Should figure out // whether this is an exception. return false; } int main::fds_to_watch(std::vector& fds) const { int maxfd=0; // control pipe maxfd=std::max(maxfd, sig_chld_pipe_[0]); // separate pipes for(unsigned int i=0; iis_broken()==false) if(ipipes_[i]->fd()!=-1) { fds.push_back(ipipes_[i]->fd()); maxfd=std::max(maxfd, ipipes_[i]->fd()); } } // pipes associated to processes for(unsigned int i=0; iinput_pipes().size(); ++k) { if(processes_[i]->input_pipes()[k]->is_broken()) { at_least_one_broken=true; break; } } if(!at_least_one_broken) { for(unsigned int k=0; kinput_pipes().size(); ++k) { fds.push_back(processes_[i]->input_pipes()[k]->fd()); maxfd=std::max(maxfd, processes_[i]->input_pipes()[k]->fd()); } } } fds.push_back(sig_chld_pipe_[0]); // std::cerr << fds.size() << std::endl; return maxfd; } int main::add_fds_(fd_set& rfds, fd_set& efds, int& maxfd) const { FD_ZERO(&rfds); FD_ZERO(&efds); std::vector fds; maxfd=fds_to_watch(fds); for(unsigned int i=0; i 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. */ #include #include #include using namespace modglue; int mid::highwater_=0; mid::mid(void) { process_=getpid(); ++highwater_; serial_=highwater_; } mid::mid(const mid& other) { serial_=other.serial_; process_=other.process_; } int mid::operator==(const mid& other) const { return (process_==other.process_ && serial_==other.serial_); } std::ostream& modglue::operator<<(std::ostream& str, const modglue::mid & m) { return (str << "mid=" << m.process_ << ", " << m.serial_); } modglue-1.19/src/modshell.cc000066400000000000000000000027251211224010400157760ustar00rootroot00000000000000/* Modglue shell. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include int main(int argc, char **argv) { modglue::main mm(argc, argv); modglue::ipipe p_command("stdin"); modglue::opipe p_result("stdout"); modglue::opipe p_error("stderr"); mm.add(&p_command,0); mm.add(&p_result,1); mm.add(&p_error,2); if(mm.check()) { modglue::loader ld(&mm, &p_command, &p_result, &p_error); if(argc>1) { // read from script before going interactive std::ifstream ff(argv[1]); ld.accept_commands_old(ff); ff.close(); } ld.print_prompt(); try { mm.run(1); } catch(std::exception& ex) { std::cerr << ex.what() << std::endl; } } return 0; } modglue-1.19/src/modwrap.cc000066400000000000000000000114271211224010400156370ustar00rootroot00000000000000/* Helper program to add modglue functionality to normal binaries. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int sig_chld_pipe[2]; pid_t childpid_; void sig_kill(int signo) { // This does of course not catch SIGKILL, that will still leave // process adopted by init. But there is no way around that, apparently. kill(childpid_, SIGTERM); exit(-1); } void sig_chld(int signo) { int status; pid_t childpid; if((childpid=waitpid(-1, &status, WNOHANG)) < 0) { throw logic_error("waitpid failed"); } if(WIFEXITED(status)) { int child_val = WEXITSTATUS(status); write(sig_chld_pipe[1],&child_val,1); } else if(WIFSIGNALED(status)) { int child_sig = WTERMSIG(status); int buf[1]; buf[0]=-1; write(sig_chld_pipe[1],buf,1); } } int main(int argc, char **argv) { if(argc==1) { cerr << "usage: modwrap [program] [options] ...." << endl << endl; cerr << "Creates a set of pseudo tty devices for stdin/stdout/stderr of" << endl << "the given program, and maps them to the corresponding pipes of" << endl << "the ptywrap program, thereby fooling the program to think that" << endl << "it is always connected to a pseudo tty." << endl << endl << "example: isatty out" << endl << " ptywrap isatty out" << endl << endl << "info: message identifier size = " << sizeof(modglue::mid) << endl; exit(1); } pair p_stdin =open_pty_master(); pair p_stdout=open_pty_master(); pair p_stderr=open_pty_master(); if(pipe(sig_chld_pipe)!=0) throw logic_error("cannot create sig_chld_pipe"); struct sigaction act; act.sa_handler = sig_chld; sigemptyset(&act.sa_mask); act.sa_flags = SA_NOCLDSTOP; if(sigaction(SIGCHLD, &act, NULL) < 0) { throw logic_error("sigaction failed"); } act.sa_handler = sig_kill; sigemptyset(&act.sa_mask); if(sigaction(SIGTERM, &act, NULL) < 0) { throw logic_error("sigaction failed"); } switch(childpid_=fork()) { case -1: throw logic_error("cannot fork"); break; case 0: { dup2(open_pty_slave(p_stdin.second), 0); dup2(open_pty_slave(p_stdout.second),1); dup2(open_pty_slave(p_stderr.second),2); execvp(argv[1],&(argv[1])); } default: break; } fd_set rfds; fd_set efds; fcntl(0, F_SETFL, O_NONBLOCK); fcntl(p_stdout.first, F_SETFL, O_NONBLOCK); fcntl(p_stderr.first, F_SETFL, O_NONBLOCK); int retcode=0; char buffer[1024]; do { FD_ZERO(&rfds); FD_ZERO(&efds); FD_SET(sig_chld_pipe[0],&rfds); FD_SET(0, &rfds); FD_SET(0, &efds); FD_SET(p_stdout.first, &rfds); FD_SET(p_stdout.first, &efds); FD_SET(p_stderr.first, &rfds); FD_SET(p_stderr.first, &efds); int retval = select(max(sig_chld_pipe[0], max(p_stdout.first,p_stderr.first))+1, &rfds, NULL, &efds, NULL); if(FD_ISSET(sig_chld_pipe[0], &rfds)) { read(sig_chld_pipe[0],buffer,1); retcode=buffer[0]; break; } if(FD_ISSET(0,&rfds)) { int length=read(0,buffer,1023); if(length>0) { // FIXME: strip identifier from input channel and remember it. write(p_stdin.first,buffer,length); } } if(FD_ISSET(p_stdout.first,&rfds)) { int length=read(p_stdout.first,buffer,1023); if(length>0) { // FIXME: add identifier write(1,buffer,length); } } if(FD_ISSET(p_stderr.first,&rfds)) { int length=read(p_stderr.first,buffer,1023); if(length>0) { // FIXME: add identifier write(2,buffer,length); } } } while(1==1); if(retcode!=-1) { int length=0; while((length=read(p_stdout.first,buffer,1023))>0) { // FIXME: add identifier write(1,buffer,length); } while((length=read(p_stderr.first,buffer,1023))>0) { // FIXME: add identifier write(2,buffer,length); } } exit(retcode); } modglue-1.19/src/moving000077500000000000000000000000651211224010400151000ustar00rootroot00000000000000#!/bin/sh echo -n "to moving mode..." cat modglue-1.19/src/pipe.cc000066400000000000000000000204141211224010400151170ustar00rootroot00000000000000/* Modglue pipes. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include #include #include #include #include #include #include using namespace modglue; modglue::pipe::pipe(const std::string& name) : process(0), name_(name), fd_(-1), fd_external_(-1), first_read_after_select_(false), broken_(true), unix_style_pipe_(false), make_blocking_(false) { } modglue::pipe::~pipe() { close(); close_external(); } std::string modglue::pipe::name(void) const { return name_; } int modglue::pipe::fd(void) const { return fd_; } int modglue::pipe::fd_external(void) const { return fd_external_; } void modglue::pipe::set_unix_style(void) { unix_style_pipe_=true; } void modglue::pipe::set_blocking(void) { make_blocking_=true; } bool modglue::pipe::is_broken(void) const { return broken_; } void modglue::pipe::open(int fd, int fd_external) { if(fd_!=-1 || fd_external_!=-1) { throw std::logic_error("pipe already open"); } if(fd==-1 && fd_external==-1) { int socks[2]; if(socketpair(AF_UNIX, SOCK_STREAM, 0, socks)!=0) { throw std::logic_error("cannot open sockets"); } fd_=socks[0]; fd_external_=socks[1]; } else { fd_=fd; fd_external_=fd_external; } broken_=false; do_fcntl_(); } void modglue::pipe::close(void) { if(fd_!=-1) { ::close(fd_); fd_=-1; broken_=true; } } void modglue::pipe::close_external(void) { if(fd_external_!=-1) { ::close(fd_external_); fd_external_=-1; } } void modglue::pipe::first_read_after_select() { first_read_after_select_=true; } void modglue::pipe::send_with_ack(const char *txt, int length) { // FILE *fp=fopen("/tmp/send_with_ack","a"); if(/* fd_!=-1 && */ !broken_) { // fprintf(fp, "%s", txt); if(send_blocking_(txt, length)==false) { throw std::logic_error("modglue::pipe::send_with_ack: error writing data, " + std::string(strerror(errno))); } } // if(!unix_style_pipe_) { // std::string result; // if(read_blocking_(result, 5)==false || result!="OK") { // cerr << "error reading data on " << fd_ // << ", error " << errno << ", " << strerror(errno) << endl; // broken_=true; // } // cerr << "send ack received for " << fd_ << endl; // } // fclose(fp); } int modglue::pipe::read_with_ack(char *txt, int maxlen) { int ret=read_nonblocking_(txt, maxlen); // std::cerr << "read with ack on " << name_ << " " << ret; // if(ret<0) // std::cerr << " " << strerror(errno); // std::cerr << std::endl; // We cannot set the pipe to broken here, because somebody may // have called read without coming from a select (this is typically // what happens when doing 'while(p>>var)' inside a callback). // A pipe is set to broken when the associated process dies, or // when the acknowledgement fails to come back (the latter has not // yet been implemented, have to think first). if(ret==0 && first_read_after_select_) { broken_=true; } first_read_after_select_=false; // if(!unix_style_pipe_) // if(ret>0) // send_blocking_("OK", 2); if(ret==0) return -1; return ret; } int modglue::pipe::read_nonblocking_(char *data, int maxlen) { if(fd_==-1 || broken_) { return -1; } if(1==1 /* unix_style_pipe_*/ ) { int ret; do { ret=read(fd_, data, maxlen); } while(ret<0 && errno==EINTR); return ret; } else { // CHECKED: recmsg is not the reason for dropped bytes int len=CMSG_SPACE(sizeof(int)); char *cbuf = new char[len]; struct msghdr mh = {0}; struct iovec iov; mh.msg_iov = &iov; mh.msg_iovlen = 1; iov.iov_base = data; iov.iov_len = maxlen; mh.msg_control = cbuf; mh.msg_controllen = len; int ret; do { ret = recvmsg(fd_, &mh, 0); } while(ret<0 && errno==EINTR); assert(!(ret<0 && errno!=EAGAIN)); delete [] cbuf; return ret; } } int modglue::pipe::send_blocking_(const char *data, int length) { assert(data); assert(length>0); if(fd_==-1 || broken_) return false; if(1==1 /*unix_style_pipe_*/) { if(length>0) { // write fails on large blocks. unsigned int len=0; while(len0) len+=ret; } } return length; } else { // CHECKED: sendmsg is not the reason for dropped bytes struct iovec iov[1]; struct msghdr msg; struct { struct cmsghdr cm; int fd; } cmsg; memset( &msg, 0, sizeof(msg) ); memset( &cmsg, 0, sizeof(cmsg) ); msg.msg_control=0; msg.msg_controllen=0; msg.msg_iov = iov; /* msg header */ msg.msg_iovlen = 1; msg.msg_name = 0; iov[0].iov_base = (void *)data; iov[0].iov_len = length; int bytes_sent; if((bytes_sent=sendmsg(fd_,&msg,0))==-1) { throw std::logic_error("modglue::pipe::send_blocking_: sendmsg error " + std::string(strerror(errno))); } assert((unsigned int)bytes_sent==length); // std::cerr << "send " << bytes_sent << std::endl; return bytes_sent; } } /* Pipebuf */ pipebuf::pipebuf(pipe *p) : pipe_(p) { setg(i_buf + putbackarea, i_buf + putbackarea, i_buf + putbackarea); setp(o_buf, o_buf + bufsiz - 1); } pipebuf::~pipebuf() { sync(); } int pipebuf::underflow(void) { //still before end of buffer? if (gptr() < egptr()) { return *gptr(); } int numPutback = gptr() - eback(); if (numPutback > putbackarea) { numPutback = putbackarea; } //copy characters into put back area. memcpy(i_buf + (putbackarea - numPutback), gptr() - numPutback, numPutback); //read new characters int num; // CHECKED: the total 'num' gives the correct number of characters, so we // do read everything in (when things come from a unix pipe). num = pipe_->read_with_ack(i_buf+putbackarea, bufsiz-putbackarea); if (num <= 0) return EOF; // std::cerr << "read " << num << std::endl; // setg(eback, gptr, egptr) setg(i_buf + (putbackarea - numPutback), i_buf + putbackarea, i_buf + putbackarea + num); //return next character return *gptr(); } int pipebuf::sync(void) { if(flushbuffer()==EOF) return -1; else return 0; } int pipebuf::overflow(int ch) { if (ch != EOF) { *pptr() = ch; pbump(1); } if(flushbuffer()==EOF) return EOF; else return ch; } int pipebuf::flushbuffer(void) { int length = pptr() - pbase(); if (length > 0) { pipe_->send_with_ack(o_buf, length); pbump(-length); } return length; } /* Output pipe */ modglue::opipe::opipe(const std::string& name) : pipe(name), std::ostream(new pipebuf(this)) { } void modglue::opipe::do_fcntl_(void) const { // FIXME: the problem is that this is not inherited. The // blocking flag does something funny on both sides. You have // to first fork, and then set the fd blocking, before execing // the child process. // // Done here, it does not do anything. // if(make_blocking_) // fcntl(fd_, F_SETFL, 0); } /* Input pipe */ modglue::ipipe::ipipe(const std::string& name) : pipe(name), std::istream(new pipebuf(this)) { } void modglue::ipipe::do_fcntl_(void) const { // FIXME: MAIN MYSTERY: setting fd 0 to NONBLOCK leads to // loss of _output_ on std::cout and std::cerr. I don't get it. // Can we live without this NONBLOCK? if(fd_!=0) fcntl(fd_, F_SETFL, O_NONBLOCK); } modglue-1.19/src/process.cc000066400000000000000000000122401211224010400156360ustar00rootroot00000000000000/* Process class. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include #include #include #include #include using namespace modglue; child_process::fd_pair::fd_pair(int fd, direction_t dir) : child_fd(fd), parent_fd(-1), direction(dir) { } child_process::child_process(const std::string& nm) : name(nm), pid_(0) { } child_process::child_process(const std::string& nm, const std::vector& ar) : name(nm), args(ar), pid_(0) { } child_process::~child_process() { close(); if(pid_ > 0) kill(pid_, SIGTERM); } child_process& child_process::operator<<(const std::string& st) { args.push_back(st); return (*this); } void child_process::standard_pipes() { assert(pid_==0); // cannot be called after program has been forked pipes.clear(); pipes.push_back(fd_pair(0,fd_pair::child_input)); pipes.push_back(fd_pair(1,fd_pair::child_output)); pipes.push_back(fd_pair(2,fd_pair::child_output)); } void child_process::call(const std::string& inp, std::string& outp) { std::string outerr; call(inp, outp, outerr); } void child_process::call(const std::string& inp, std::string& outp, std::string& outerr) { standard_pipes(); fork(); // FIXME: for very long input std::strings, this leads to failure. if(inp.size()>0) ::write(pipes[0].parent_fd, inp.c_str(), inp.size()); char buffer[1024]; int pos; stdoutagain: while((pos=::read(pipes[1].parent_fd, buffer, 1023))>0) { buffer[pos]=0; outp+=buffer; } if(pos<0 && errno==EINTR) goto stdoutagain; stderragain: while((pos=::read(pipes[2].parent_fd, buffer, 1023))>0) { buffer[pos]=0; outerr+=buffer; } if(pos<0 && errno==EINTR) goto stderragain; close(); terminate(); } void child_process::terminate() { if(pid_ > 0) { kill(pid_, SIGTERM); pid_=0; } } void child_process::wait() { if(pid_ > 0) { waitpid(pid_, 0, 0); pid_=0; } } void child_process::write(const std::string& str) { ::write(pipes[0].parent_fd, str.c_str(), str.size()); } void child_process::read(std::string& str) { int pos=0; char buffer[2]; while((pos=::read(pipes[1].parent_fd, buffer, 1))>0) { if(buffer[0]=='\n') break; str+=buffer[0]; } } ssize_t child_process::read(void *buffer, size_t len) { return ::read(pipes[1].parent_fd, buffer, len); } ssize_t child_process::write(void *buffer, size_t len) { return ::write(pipes[0].parent_fd, buffer, len); } void child_process::fork() { if(pipes.size()==0) standard_pipes(); const char *cargs[args.size()+2]; cargs[0]=name.c_str(); for(unsigned int i=0; i(cargs)); throw std::logic_error("modglue::child_process::fork: execlp failed for "+name); break; } default: // we are the parent for(unsigned int i=0; i 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. */ /* We use some non-standard escape codes: ESC $ [text] $ : fill the edit buffer with [text] */ #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; struct termios saved_attributes, raw_attributes; modglue::main *cmm; modglue::opipe *t_stdin; modglue::ipipe s_stdin("s_stdin"); modglue::opipe s_stdout("s_stdout"); modglue::opipe s_stderr("s_stderr"); pid_t thepid; bool go_to_sleep=false; enum state_t { initial, escape_read, movement_escape_read, eat_one_char } state; string combine, last_output_line; vector history; unsigned int hispos=0; bool moving=false; unsigned int pos=0; void sigc_handler(int num) { kill(thepid, SIGINT); signal(SIGINT,sigc_handler); } void raw_terminal(void); void buffered_terminal(void); void redraw_line(const string& str, unsigned int curpos, unsigned int nextpos); void sigstp_handler(int num) { signal(SIGTSTP,&sigstp_handler); //go_to_sleep=true; tcsetattr(0, TCSANOW, &saved_attributes); kill(getpid(),SIGSTOP); } void sigcont_handler(int num) { signal(SIGCONT,&sigcont_handler); tcsetattr(0, TCSANOW, &raw_attributes); fcntl(0, F_SETFL, O_NONBLOCK); s_stdout << last_output_line << std::flush; redraw_line(combine, 0, pos); } void buffered_terminal(void) { tcsetattr(0, TCSANOW, &saved_attributes); } void raw_terminal(void) { tcgetattr(0, &saved_attributes); atexit(buffered_terminal); tcgetattr(0, &raw_attributes); raw_attributes.c_lflag &= ~(ICANON|ECHO); tcsetattr(0, TCSANOW, &raw_attributes); signal(SIGTSTP,&sigstp_handler); signal(SIGCONT,&sigcont_handler); } // void save_cursor() // { // cout << "\033[s"; // } // // void restore_cursor() // { // cout << "\033[u"; // } void erase_line() { s_stdout << "\033[K"; } void move_left(unsigned int num=1) { if(num>0) s_stdout << "\033[" << num << "D" << flush; } void move_right(unsigned int num=1) { if(num>0) s_stdout << "\033[" << num << "C" << flush; } void redraw_line(const string& str, unsigned int curpos, unsigned int nextpos) { move_left(curpos); erase_line(); s_stdout << str << flush; move_left(str.size()-nextpos); } bool died(modglue::ext_process& pr) { // s_stderr << "********process " << pr.name() << " died" << endl; return true; } void process_stdin(const char *buffer, int len) { for(int curchar=0; curchar0) { combine=(pos>1?combine.substr(0,pos-1):"")+ (pos0) { if(hispos+1==history.size()) { history.pop_back(); history.push_back(combine); } combine=history[--hispos]; redraw_line(combine, pos, combine.size()); pos=combine.size(); } } state=initial; break; case 'B': if(moving) { (*t_stdin) << "\\down" << endl; } else { if(hispos+10) { --pos; move_left(); } } state=initial; break; default: state=initial; break; } break; } } } bool receive_stdout(modglue::ipipe& p) { char buffer[1024]; int len; enum write_t { w_normal, w_fill }; static write_t wmode=w_normal; do { p.read(buffer,1023); len=p.gcount(); if(len>0) { buffer[len]=0; if(len>=3) { if(strncmp("\033[u", &(buffer[len-3]), 3)==0) moving=true; } for(unsigned int i=0; idebugout << buffer[i]; s_stdout << buffer[i]; if(buffer[i]=='\n') last_output_line.clear(); else last_output_line+=buffer[i]; } break; case w_fill: if(buffer[i]=='$') { wmode=w_normal; redraw_line(combine, pos, pos-1); } else combine+=buffer[i]; break; } } s_stdout << flush; } } while(len>0); p.clear(); return true; } bool receive_stdin(modglue::ipipe& p) { char buffer[1024]; int len; do { p.read(buffer,1016); len=p.gcount(); if(len>0) process_stdin(buffer, len); } while(len>0); p.clear(); return true; } bool receive_stderr(modglue::ipipe& p) { char buffer[1024]; int len; do { p.read(buffer,1016); len=p.gcount(); if(len>0) s_stderr << buffer << flush; } while(len>0); p.clear(); return true; } int main(int argc, char **argv) { if(argc==1) { cerr << "prompt ("; #ifdef STATICBUILD cerr << "static, "; #endif cerr << "built on " << DATETIME << /* " on " << HOSTNAME << */ ")" << std::endl << "Copyright (C) 2001-2006 Kasper Peeters " << endl << endl << "Usage: prompt [program] [args]" << endl; exit(-1); } if(!isatty(0)) { cerr << "prompt: stdin is not a tty." << endl; exit(-2); } modglue::main mm(argc, argv); mm.add(&s_stdin, 0); mm.add(&s_stdout, 1); mm.add(&s_stderr, 2); cmm=&mm; fcntl(0, F_SETFL, O_NONBLOCK); if(mm.check()) { int start=1; string program(argv[start]); modglue::ext_process proc(program); for(int i=start+1; ireceiver.connect(sigc::ptr_fun(receive_stdout)); proc.input_pipe("stderr")->receiver.connect(sigc::ptr_fun(receive_stderr)); t_stdin=proc.output_pipe("stdin"); mm.process_died.connect(sigc::ptr_fun(died)); history.push_back(""); raw_terminal(); mm.run(2); } catch(exception& ex) { cerr << ex.what() << endl; return -1; } s_stdout << std::flush; tcsetattr(0, TCSANOW, &saved_attributes); return 0; } else return -2; } modglue-1.19/src/ptywrap.cc000066400000000000000000000232521211224010400156730ustar00rootroot00000000000000/* Wrap program into pseudo-tty. Copyright (C) 2001-2009 Kasper Peeters 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. */ /* The misfeature is the lack of an end-to-end flush operation in Unix. What stdio SHOULD do is to call one after every line of terminal input, pipe-like programs should honour it and pass it on, and output programs should honour it (and reflect it, if they are duplex). All good 1960s technology. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __sun__ #if USE_UTIL_H == 1 #include #else #include #endif #endif #include #include /* Once Solaris has openpty(), this is going to be removed. */ #ifdef __sun__ #include #include #include int openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) { const char *slave; int mfd = -1, sfd = -1; *amaster = *aslave = -1; mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY); if (mfd < 0) goto err; if (grantpt(mfd) == -1 || unlockpt(mfd) == -1) goto err; if ((slave = ptsname(mfd)) == NULL) goto err; if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1) goto err; if (ioctl(sfd, I_PUSH, "ptem") == -1) goto err; if (amaster) *amaster = mfd; if (aslave) *aslave = sfd; if (winp) ioctl(sfd, TIOCSWINSZ, winp); assert(name == NULL); assert(termp == NULL); return 0; err: if (sfd != -1) close(sfd); close(mfd); return -1; } #endif // std::pair open_pty_master(void) // { // unsigned char ptychar='p'; // struct stat statbuff; // static char hexdigit[]="0123456789abcdef"; // int master_fd=0; // // do { // for(unsigned char num=0; num<16; ++num) { // std::stringstream st; // st << "/dev/pty" << ptychar << hexdigit[num] << std::ends; // std::string ptyname=st.str(); // if(stat(ptyname.c_str(), &statbuff)<0) // break; // if((master_fd=open(ptyname.c_str(), O_RDWR))>=0) { // std::string ttyname=ptyname; // ttyname[5]='t'; // int tmp; // if((tmp=open(ttyname.c_str(), O_RDWR))>=0) { // close(tmp); // return std::pair(master_fd, ptyname); // } // else { // close(master_fd); // some systems have incorrect permissions on some /dev/ttyp // } // } // } // ++ptychar; // } while(ptychar!='z'); // throw std::logic_error("cannot open pseudo-tty in master mode"); // return std::pair(-1,""); // } // // int open_pty_slave(std::string ptyname) // { // int slave_fd; // ptyname[5]='t'; // slave_fd=open(ptyname.c_str(), O_RDWR); // if(slave_fd<0) { // std::cerr << "slave open for " << ptyname << " failed: " << strerror(errno) << std::endl; // } // assert(slave_fd>=0); // // // struct termio temp_mode; // // if(ioctl(slave_fd, TCGETA, &temp_mode)<0) // // throw std::logic_error("cannot get tty mode"); // // // // temp_mode.c_iflag = 0; // // temp_mode.c_oflag &= ~OPOST; // // temp_mode.c_lflag &= ~(ISIG | ICANON | ECHO | XCASE); // // temp_mode.c_cflag &= ~(CSIZE | PARENB); // // temp_mode.c_cflag |= CS8; // // temp_mode.c_cc[VMIN]=1; // // temp_mode.c_cc[VTIME]=1; // // // // if(ioctl(slave_fd, TCSETA, &temp_mode)<0) // // throw std::logic_error("cannot set tty mode to raw"); // // struct termios temp_mode; // if(tcgetattr(slave_fd, &temp_mode)<0) // throw std::logic_error("cannot get tty mode"); // // temp_mode.c_iflag = 0; // temp_mode.c_oflag &= ~OPOST; // temp_mode.c_lflag &= ~(ISIG | ICANON | ECHO); // | XCASE); // temp_mode.c_cflag &= ~(CSIZE | PARENB); // temp_mode.c_cflag |= CS8; // temp_mode.c_cc[VMIN]=1; // temp_mode.c_cc[VTIME]=1; // // if(tcsetattr(slave_fd, TCSANOW, &temp_mode)<0) // throw std::logic_error("cannot set tty mode to raw"); // // // return slave_fd; // } int open_pty_slave(int slave_fd) { struct termios temp_mode; if(tcgetattr(slave_fd, &temp_mode)<0) throw std::logic_error("cannot get tty mode"); temp_mode.c_iflag = 0; temp_mode.c_oflag &= ~OPOST; temp_mode.c_lflag &= ~(ISIG | ICANON | ECHO); // | XCASE); temp_mode.c_cflag &= ~(CSIZE | PARENB); temp_mode.c_cflag |= CS8; temp_mode.c_cc[VMIN]=1; temp_mode.c_cc[VTIME]=1; if(tcsetattr(slave_fd, TCSANOW, &temp_mode)<0) throw std::logic_error("cannot set tty mode to raw"); return slave_fd; } int sig_chld_pipe[2]; pid_t childpid_; void sig_kill(int signo) { // This does of course not catch SIGKILL, that will still leave // process adopted by init. But there is no way around that, apparently. kill(childpid_, SIGTERM); exit(-1); } void sig_chld(int signo) { int status; pid_t childpid; if((childpid=waitpid(-1, &status, WNOHANG)) < 0) { throw std::logic_error("waitpid failed"); } if(WIFEXITED(status)) { int child_val = WEXITSTATUS(status); write(sig_chld_pipe[1],&child_val,1); } else if(WIFSIGNALED(status)) { int child_sig = WTERMSIG(status); int buf[1]; buf[0]=-1; write(sig_chld_pipe[1],buf,1); } } int main(int argc, char **argv) { if(argc==1) { std::cerr << "usage: ptywrap [program] [options] ...." << std::endl << std::endl; std::cerr << "Creates a set of pseudo tty devices for stdin/stdout/stderr of" << std::endl << "the given program, and maps them to the corresponding pipes of" << std::endl << "the ptywrap program, thereby fooling the program to think that" << std::endl << "it is always connected to a pseudo tty." << std::endl << std::endl << "example: isatty out" << std::endl << " ptywrap isatty out" << std::endl << std::endl << "info: message identifier size = " << sizeof(modglue::mid) << std::endl; exit(1); } std::pair p_stdin, p_stdout, p_stderr; openpty(&p_stdin.first, &p_stdin.second, 0, 0, 0); openpty(&p_stdout.first, &p_stdout.second, 0, 0, 0); openpty(&p_stderr.first, &p_stderr.second, 0, 0, 0); if(pipe(sig_chld_pipe)!=0) throw std::logic_error("cannot create sig_chld_pipe"); struct sigaction act; act.sa_handler = sig_chld; sigemptyset(&act.sa_mask); act.sa_flags = SA_NOCLDSTOP | SA_RESTART; if(sigaction(SIGCHLD, &act, NULL) < 0) { throw std::logic_error("sigaction failed"); } act.sa_handler = sig_kill; sigemptyset(&act.sa_mask); if(sigaction(SIGTERM, &act, NULL) < 0) { throw std::logic_error("sigaction failed"); } act.sa_handler = sig_kill; sigemptyset(&act.sa_mask); if(sigaction(SIGINT, &act, NULL) < 0) { throw std::logic_error("sigaction failed"); } switch(childpid_=fork()) { case -1: throw std::logic_error("cannot fork"); break; case 0: { // close parent side of the pipe close(p_stdin.first); close(p_stdout.first); close(p_stderr.first); // dup the default streams and then close the originals open_pty_slave(p_stdin.second); open_pty_slave(p_stdout.second); open_pty_slave(p_stderr.second); dup2(p_stdin.second,0); dup2(p_stdout.second,1); dup2(p_stderr.second,2); close(p_stdin.second); close(p_stdout.second); close(p_stderr.second); write(sig_chld_pipe[1], "G", 1); // exec the actual program execvp(argv[1],&(argv[1])); } default: break; } fd_set rfds; fd_set efds; fcntl(0, F_SETFL, O_NONBLOCK); fcntl(p_stdout.first, F_SETFL, O_NONBLOCK); fcntl(p_stderr.first, F_SETFL, O_NONBLOCK); int retcode=0; char buffer[1024]; read(sig_chld_pipe[0], buffer, 1); // wait until child is ready do { FD_ZERO(&rfds); FD_ZERO(&efds); FD_SET(sig_chld_pipe[0],&rfds); FD_SET(0, &rfds); FD_SET(0, &efds); FD_SET(p_stdout.first, &rfds); FD_SET(p_stdout.first, &efds); FD_SET(p_stderr.first, &rfds); FD_SET(p_stderr.first, &efds); int retval = select(std::max(sig_chld_pipe[0], std::max(p_stdout.first,p_stderr.first))+1, &rfds, NULL, &efds, NULL); if(FD_ISSET(sig_chld_pipe[0], &rfds)) { read(sig_chld_pipe[0],buffer,1); retcode=buffer[0]; break; } if(FD_ISSET(0,&rfds)) { int length=read(0,buffer,1023); if(length>0) { // FIXME: strip identifier from input channel and remember it. if(write(p_stdin.first,buffer,length)==-1) break; } } if(FD_ISSET(p_stdout.first,&rfds)) { int length=read(p_stdout.first,buffer,1023); if(length>0) { // FIXME: add identifier if(write(1,buffer,length)==-1) break; } else break; } if(FD_ISSET(p_stderr.first,&rfds)) { int length=read(p_stderr.first,buffer,1023); if(length>0) { // FIXME: add identifier if(write(2,buffer,length)==-1) break; } else break; } } while(1==1); if(retcode!=-1) { int length=0; while((length=read(p_stdout.first,buffer,1023))>0) { // FIXME: add identifier write(1,buffer,length); } while((length=read(p_stderr.first,buffer,1023))>0) { // FIXME: add identifier write(2,buffer,length); } } exit(retcode); } modglue-1.19/src/shell.cc000066400000000000000000000254101211224010400152720ustar00rootroot00000000000000/* Modglue shell. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include #include #include #include #include #include #include using namespace modglue; process_info::process_info(const std::string& name, const std::string& unique_name) : process(name), start_on_input(false), restart_after_exit(false), abort_on_failed_write(false), remove_after_exit(false), unique_name_(unique_name) { } // -------------- bond::bond(const std::string& nm) : name(nm) { } // -------------- void loader::print_prompt(void) { (*p_result) << ">" << std::flush; } void loader::print_jobs_(std::ostream& ss) { ss << "process list: (" << processes_.size() << " entries)" << std::endl; for(unsigned int i=0; iprocess.name(); if(processes_[i]->process.get_pid()==0) ss << " (standby)" << std::endl; else ss << " (running)" << std::endl; for(unsigned int j=0; jprocess.input_pipes().size(); ++j) { ss << " " << processes_[i]->process.name() << "::" << processes_[i]->process.input_pipes()[j] << std::endl; } for(unsigned int j=0; jprocess.output_pipes().size(); ++j) { ss << " " << processes_[i]->process.name() << "::" << processes_[i]->process.output_pipes()[j] << std::endl; } } } void loader::print_bonds_(std::ostream& ss) { for(unsigned int i=0; iname << ": " ; bond::iterator it=bonds_[i]->pipes.begin(); while(it!=bonds_[i]->pipes.end()) { // ss << (*it).first->get_name() << "::" // << (*it).first->pipes[(*it).second]->get_name() << " "; ++it; } ss << std::endl; } } bool loader::parse_(modglue::ipipe& p) { char c; while(p.get(c)) { switch(status_.back()) { case s_skipwhite: if(!isspace(c)) { p.unget(); status_.pop_back(); } break; case s_initial: assert(!isspace(c)); if(c=='|' || c=='^' || c=='&') { errors_.push_back("illegal character at begin of input"); return false; } else { status_.pop_back(); status_.push_back(s_skipwhite); status_.push_back(s_scan); p.unget(); break; } break; case s_scan: if(c=='{') { ingroup_=true; status_.push_back(s_groupscan); status_.push_back(s_skipwhite); break; } else { status_.push_back(s_command); p.unget(); } break; case s_groupscan: break; case s_command: if(c=='}') { if(!ingroup_) { errors_.push_back("encountered superfluous '}' character"); return false; } else { ingroup_=false; break; } } else if(isspace(c)) { status_.push_back(s_skipwhite); status_.push_back(s_arg_or_control); new_processes_.push_back(new process_info(current_, current_)); current_=""; break; } else if(c=='|' || c=='^' || c=='&') { p.unget(); status_.push_back(s_arg_or_control); new_processes_.push_back(new process_info(current_, current_)); current_=""; break; } else current_+=c; break; case s_arg_or_control: if(c=='>') { } if(c=='<') { } if(c=='&') { } if(c=='^') { } if(c=='|' || c=='^' || c=='&') { } break; } } p.clear(); return true; } /* Process connections (multiple pipes can be connected as one using the grouping symbols): viewer & ftp & cat "open ftp.somewhere.net\n" | ftp::stdin cat "binary\n get file -\n" | ftp::stdin { ftp::stdout, ftp::stderr } | viewer::stdin Pipe options (always written using a dot immediately following the pipe symbol; multiple options can be given by separating them with dots): ls ::stdout > out.txt |.discard (default) ls ::stdout > out.txt ::stderr |.keep Making connections and then starting (curly brackets denote grouping and lead, in the second case, to start of both processes before any other activities take place): { ls, grep } ^ ls::stdout | grep::stdin { ls, grep } @ Identical programs with different names: { ls:binls /bin, ls:tmpls /tmp } ^ binls::stdout | ::stdin grep file & tmpls::stdout | ::stdin grep dir & { binls, tmpls } @ Alternatively, use the automatically generated names (but beware that the numbers can change if you had other processes with the same name running already; see 'jobs' for the real names): { ls /bin, ls /tmp } ^ ls::stdout | ::stdin grep file & ls<2>::stdout | ::stdin grep dir & { ls, ls<2> } @ ::pipe refers to the pipe of the current program; a pipe symbol starts a new program group. If pipes are omitted, the default settings are used. These are searched from top to bottom, and search stops as soon as a match is found. default ::stdout | ::stdin default ::stdin | ::stdout default ::* |.discard ls > txt.out (behaves as usual) Curly braces group either processes or pipes, but not a combination. They can also not be used to group entire commands (ie. like round brackets do in sh). Curly braces cannot be nested. LOOK AT: http://www.holoweb.net/~simpl/ */ bool loader::accept_commands_old(std::istream& p) { return true; } bool loader::accept_commands(modglue::ipipe& p) { if(parse_(p)==false) { p.ignore(MAXINT); } if(errors_.size()>0) { for(unsigned int i=0; i0) { for(unsigned int i=0; iprocess.name() << std::endl; } } print_prompt(); return true; } loader::loader(modglue::main *mn, modglue::ipipe *p_c, modglue::opipe *p_r, modglue::opipe *p_e) : ingroup_(false), main_(mn), p_command(p_c), p_result(p_r), p_error(p_e) { status_.push_back(s_initial); status_.push_back(s_skipwhite); p_command->receiver.connect(SigC::slot(*this, &modglue::loader::accept_commands)); } void loader::quit(void) { } loader::~loader() { for(unsigned int i=0; ipipes.begin(); // while(mit!=bonds_[i]->pipes.end()) { // if((*mit).first==proc) { // set >::iterator it=bonds_[i]->pipes.begin(); // while(it!=bonds_[i]->pipes.end()) { // if(it!=mit) { // if((*it).first->pipes[(*it).second]->get_inout()==pipeinfo::input && // !((*it).first->pipes[(*it).second]->get_unix_style()) ) { // int totalwriters=0; // pair scanfor=(*it); // for(unsigned int k=0; kpipes.count(scanfor)>0) { // set >::iterator wr=bonds_[k]->pipes.begin(); // while(wr!=bonds_[k]->pipes.end()) { // if((*wr).first->get_pid()!=0 && // (*wr).first->pipes[(*wr).second]->get_inout()==pipeinfo::output) { // ++totalwriters; // } // ++wr; // } // } // } // if(totalwriters==0) { // write((*it).first->pipes[(*it).second]->get_fd(),"\004",1); // } // } // } // ++it; // } // } // ++mit; // } // } void loader::add_bond_(bond *b) { bonds_.push_back(b); } void loader::remove_bond_(bond *b) { std::vector::iterator it=bonds_.begin(); while(it!=bonds_.end()) { if((*it)==b) { bonds_.erase(it); return; } ++it; } assert(1==0); } /* pair loader::str2pipe(const string& str) { pair ret; ret.first=0; ret.second=-1; string::size_type loc=str.find("::"); if(locget_name()==procname) { ret.first=processes_[i]; break; } } if(ret.first) { for(unsigned int i=0; ipipes.size(); ++i) { if(ret.first->pipes[i]->get_name()==pipename) { ret.second=i; break; } } } } return ret; } vector args; // Setup a process entry and the associated loader pipes for the modshell // process, so that we don't have to use special cases for forwarding // to/from modshell pipes. // NOTE: the direction is a bit funny, because we should view this from // the point of view of someone connecting _to_ modshell. So stdout is input. modglue::process *proc=new modglue::process("_loader",args); loader_pipe *lp1=new loader_pipe(main_->pipes()[0]->get_name(), modglue::pipeinfo::output); lp1->set_fd(main_->pipes()[0]->get_fd()); lp1->set_unix_style(); // FIXME: this will make things fail when modshell is started from modshell. proc->pipes.push_back(lp1); loader_pipe *lp2=new loader_pipe(main_->pipes()[1]->get_name(), modglue::pipeinfo::input); lp2->set_fd(main_->pipes()[1]->get_fd()); lp2->set_unix_style(); proc->pipes.push_back(lp2); loader_pipe *lp3=new loader_pipe(main_->pipes()[2]->get_name(), modglue::pipeinfo::input); lp3->set_fd(main_->pipes()[2]->get_fd()); lp3->set_unix_style(); proc->pipes.push_back(lp3); proc->childpid_=getpid(); processes_.push_back(proc); fd_to_pipe_[lp1->get_fd()]=pair(proc,0); fd_to_pipe_[lp2->get_fd()]=pair(proc,1); fd_to_pipe_[lp3->get_fd()]=pair(proc,2); */ modglue-1.19/src/test_child_process.cc000066400000000000000000000031601211224010400200410ustar00rootroot00000000000000/* Testing the process class. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include using namespace std; int main(int argc, char **argv) { string result; modglue::child_process ls_proc("ls"); ls_proc << "-la" << "/tmp"; ls_proc.call("", result); std::cout << "result of ls call: |" << result << "|" << std::endl; // like libexecstream: http://libexecstream.sourceforge.net/ modglue::ext_process cat_proc("cat"); cat_proc.setup_pipes(); cat_proc.output_pipe("stdin")->set_blocking(); cat_proc.fork(); std::cout << cat_proc.output_pipe("stdin")->fd() << std::endl; *(cat_proc.output_pipe("stdin")) << "hi there" << std::endl; while(std::getline(*(cat_proc.input_pipe("stdout")), result)) { std::cout << "received: |" << result << "|" << std::endl; } cat_proc.terminate(); } modglue-1.19/src/test_ext_process.cc000066400000000000000000000043011211224010400175540ustar00rootroot00000000000000/* Test extended process class. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include #include #include using namespace std; modglue::ext_process ls_proc("ls"); modglue::ext_process mi_proc("examples/multi_io"); bool print(modglue::ipipe& p) { string str; while(getline(p,str)) { cerr << "from ls: |" << str << "|" << endl; // cerr << "forwarding to " // << mi_proc.output_pipe("foo")->name() << " " // << mi_proc.output_pipe("foo")->fd() << endl; *(mi_proc.output_pipe("foo")) << str << endl << flush; } p.clear(); return true; } bool printmio(modglue::ipipe& p) { string str; while(getline(p,str)) { cerr << "from mi: |" << str << "|" << endl; } p.clear(); return true; } int counter=1; bool died(modglue::ext_process& pr) { cerr << "********process " << pr.name() << " died" << endl; if(counter<2) { ++counter; pr.fork(); return false; } return true; } int main(int argc, char **argv) { modglue::main mm(argc, argv); try { ls_proc.setup_pipes(); mi_proc.setup_pipes(); mm.add(&ls_proc); mm.add(&mi_proc); ls_proc.input_pipe("stdout")->receiver.connect(sigc::ptr_fun(print)); mi_proc.input_pipe("bar")->receiver.connect(sigc::ptr_fun(printmio)); mm.process_died.connect(sigc::ptr_fun(died)); ls_proc.fork(); mi_proc.fork(); mm.run(0); } catch(exception& ex) { cerr << ex.what() << endl; } } modglue-1.19/src/test_pipe.cc000066400000000000000000000026041211224010400161570ustar00rootroot00000000000000/* Simple tests of pipes. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include using namespace std; modglue::ipipe ip("input"); modglue::opipe op("input"); bool inp(modglue::ipipe& p) { string kasper; while(p>>kasper) { op << "received: " << kasper << endl; } p.clear(); op << "--" << endl; return true; } int main(int argc, char **argv) { /* modglue::main::init(argc, argv); */ modglue::main mm(argc, argv); mm.add(&ip,0); mm.add(&op,1); if(mm.check()) { ip.receiver.connect(sigc::ptr_fun(inp)); mm.run(1); } // Also test that creation of pipes does not leak memory. } modglue-1.19/src/test_pipe_gtk.cc000066400000000000000000000027421211224010400170270ustar00rootroot00000000000000/* Pipe tester using gtk. Copyright (C) 2001-2009 Kasper Peeters 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. */ /* This is the same program as test_pipe.cc, but now using an external event loop (for this particular example, we use the Gtk event loop). */ #include #include modglue::ipipe ip("input"); modglue::opipe op("input"); bool inp(modglue::ipipe& p) { string kasper; while(p>>kasper) { op << "received: " << kasper << endl; } p.clear(); op << "--" << endl; return true; } int main(int argc, char **argv) { // Gtk::Main modglue::main mm(argc, argv); mm.add(&ip,0); mm.add(&op,1); if(mm.check()) { ip.receiver.connect(SigC::slot(inp)); mm.run(); } // Also test that creation of pipes does not leak memory. } modglue-1.19/src/test_writes.cc000066400000000000000000000041001211224010400165300ustar00rootroot00000000000000/* Testing writes. Copyright (C) 2001-2009 Kasper Peeters 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. */ #include #include #include using namespace std; modglue::ipipe ip("stdin"); modglue::opipe op("stdout"); modglue::opipe op2("stderr"); std::ofstream out("test_writes.out"); bool inp(modglue::ipipe& p) { static bool done=false; if(!done) { std::ifstream inp("out"); char buffer[2024]; int num; for(;;) { inp.read(buffer, 2023); num=inp.gcount(); if(num>0) { op.write(buffer,num); } else break; } op << std::flush; done=true; } /* char buffer[1024]; streamsize num; for(;;) { p.read(buffer,1016); // CHECKED: if we do it this way, all characters get received num=p.gcount(); if(num>0) { std::cerr << "recv " << num << std::endl; op.write(buffer, num); out.write(buffer, num); // cerr.write(buffer, num); } else break; } p.clear(); return true; std::string lng; for(unsigned int i=0; i<500; ++i) lng+="testing 1 2 3 4 5 "; for(;;) { op << lng << std::endl; } p.clear(); */ return true; } int main(int argc, char **argv) { modglue::main mm(argc, argv); mm.add(&ip,0); mm.add(&op,1); mm.add(&op2,2); if(mm.check()) { ip.receiver.connect(sigc::ptr_fun(inp)); mm.run(1); } // IMPORTANT: remember to flush before closing. op << std::flush; }