You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rs...@hyperreal.org on 1998/04/28 10:42:13 UTC

cvs commit: apache-1.3/src/support httpd.exp

rse         98/04/28 01:42:13

  Modified:    .        STATUS INSTALL
               src      CHANGES Configure README.DSO
               src/modules/standard mod_so.c
               src/os/unix os.c
  Added:       src/os/unix os-aix-dso.c
               src/support httpd.exp
  Log:
  After the third interaction now we have it:
  
  Dynamic Shared Object (DSO) support for IBM's AIX.
  
  This is accomplished by using DSO emulation code because AIX <= 4.2 don't have
  dlopen() and AIX 4.2 has a broken one.  But with the emulation code it works
  great.
  
  Revision  Changes    Path
  1.341     +1 -0      apache-1.3/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/STATUS,v
  retrieving revision 1.340
  retrieving revision 1.341
  diff -u -r1.340 -r1.341
  --- STATUS	1998/04/28 08:19:47	1.340
  +++ STATUS	1998/04/28 08:42:06	1.341
  @@ -75,6 +75,7 @@
       * Roy's bugfixes for select() handling
       * Martin's suppress "error(0)" messages for ap_log_error()
       * Ralf's fixes for compiler warnings under AIX 4.2 (NET_SIZE_T is size_t)
  +    * Ralf's DSO support for AIX
   
   Available Patches:
   
  
  
  
  1.22      +5 -4      apache-1.3/INSTALL
  
  Index: INSTALL
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/INSTALL,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- INSTALL	1998/04/27 16:11:40	1.21
  +++ INSTALL	1998/04/28 08:42:06	1.22
  @@ -75,13 +75,14 @@
           platform-dependend. The current state is this:
   
           o Out-of-the-box supported platforms are:
  -           - Linux     - SunOS    - IRIX
  -           - FreeBSD   - Solaris  - HPUX
  -           - OpenBSD   - OSF1     - UnixWare
  +           - Linux     - IRIX
  +           - FreeBSD   - HPUX
  +           - OpenBSD   - OSF1
  +           - SunOS     - UnixWare
  +           - Solaris   - AIX
   
           o Entirely unsupported platforms are:
              - Ultrix (because no dlopen-style interface)
  -           - AIX    (although it has dlopen it is a braindead one)
   
           If your system is not on these lists but has the dlopen-style
           interface, you either have to provide the appropriate compiler and
  
  
  
  1.803     +6 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.802
  retrieving revision 1.803
  diff -u -r1.802 -r1.803
  --- CHANGES	1998/04/28 08:19:47	1.802
  +++ CHANGES	1998/04/28 08:42:07	1.803
  @@ -1,4 +1,10 @@
   Changes with Apache 1.3b7
  +
  +  *) Add Dynamic Shared Object (DSO) support for AIX (at least 4.2 but older
  +     AIX variants should work fine, too. Even AIX 3.x should work). This is
  +     accomplished by using the free DSO emulation code from Jens-Uwe Mager
  +     which we put into a os/unix/os-dso-aix.c file.
  +     [Ralf S. Engelschall]
     
     *) PORT: Fix compiler warnings under AIX >= 4.2 where the manual pages imply
        that we should use NET_SIZE_T == int but the include files force size_t.
  
  
  
  1.249     +24 -0     apache-1.3/src/Configure
  
  Index: Configure
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/Configure,v
  retrieving revision 1.248
  retrieving revision 1.249
  diff -u -r1.248 -r1.249
  --- Configure	1998/04/28 08:19:48	1.248
  +++ Configure	1998/04/28 08:42:08	1.249
  @@ -763,6 +763,7 @@
   if [ "x$using_shlib" = "x1" ] ; then
       DEF_SHARED_CORE=no
       SHLIB_SUFFIX_DEPTH=all
  +    SHLIB_EXPORT_FILES=no
       case "$PLAT" in
           *-linux1)
               CFLAGS_SHLIB="-fpic"
  @@ -899,6 +900,25 @@
               LDFLAGS_SHLIB="-b"
               LDFLAGS_SHLIB_EXPORT="-Wl,-E -Wl,-B,deferred"
               ;;
  +        *-ibm-aix*)
  +            case $CC in
  +                */gcc|gcc ) CFLAGS_SHLIB="-fpic" ;;
  +                */cc|cc   ) CFLAGS_SHLIB="" ;;
  +            esac
  +            case $PLAT in
  +                *-ibm-aix4*)
  +                    LDFLAGS_SHLIB="-H512 -T512 -bhalt:4 -bM:SRE -bnoentry"
  +                    ;;
  +                *-ibm-aix*)
  +                    LDFLAGS_SHLIB="-H512 -T512 -bhalt:4 -bM:SRE -e _nostart"
  +                    ;;
  +            esac
  +            LDFLAGS_SHLIB="$LDFLAGS_SHLIB -bI:\$(SRCDIR)/support/httpd.exp "
  +            LDFLAGS_SHLIB="$LDFLAGS_SHLIB -bE:\`echo \$@|sed -e 's:\.so\$\$:.exp:'\`"
  +            LDFLAGS_SHLIB="$LDFLAGS_SHLIB -lc"
  +            LDFLAGS_SHLIB_EXPORT="-Wl,-bE:\$(SRCDIR)/support/httpd.exp"
  +            SHLIB_EXPORT_FILES=yes
  +            ;;
           *)
               ##  ok, no known explict support for shared objects
               ##  on this platform, but we give not up immediately.
  @@ -1248,6 +1268,10 @@
   	fi
   	if [ $ext != so ]; then
   		echo "Module $modname $modbase.$ext" >>$tmpfile
  +	fi
  +	#   optionally generate export file for some linkers 
  +	if [ $ext = so -a .$SHLIB_EXPORT_FILES = .yes ]; then
  +		echo "$modname" >$modbase.exp
   	fi
   done
   # $tmpfile now contains Module lines for all the modules we want
  
  
  
  1.6       +1 -4      apache-1.3/src/README.DSO
  
  Index: README.DSO
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/README.DSO,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- README.DSO	1998/04/27 16:11:41	1.5
  +++ README.DSO	1998/04/28 08:42:08	1.6
  @@ -150,6 +150,7 @@
      o  IRIX               (6.2)
      o  HP/UX              (10.20)
      o  UnixWare           (2.01, 2.1.2)
  +   o  AIX                (4.2)
      o  ReliantUNIX/SINIX  (5.43)
      o  SVR4               (-)
   
  @@ -157,10 +158,6 @@
   
      o  Ultrix: There is no dlopen-style interface under this platform.
   
  -   o  AIX: Under AIX 3.x there is no dlopen-style interface and under AIX 4.2
  -      although there is one the linker (ld) is such braindead that it is a
  -      horrible mess to get the DSO mechanism working.
  -   
    Usage Summary
    -------------
   
  
  
  
  1.23      +12 -5     apache-1.3/src/modules/standard/mod_so.c
  
  Index: mod_so.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_so.c,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- mod_so.c	1998/04/14 10:58:24	1.22
  +++ mod_so.c	1998/04/28 08:42:10	1.23
  @@ -135,11 +135,18 @@
   	:
       else
           DL_LIB=""
  -        if ./helpers/TestCompile lib dl; then
  -	    DL_LIB="-ldl"
  -        fi
  -        LIBS="$LIBS $DL_LIB"
  -        if [ "X$DL_LIB" != "X" ]; then
  +        case $PLAT in
  +             *-ibm-aix* )
  +                 DL_LIB="-lld"
  +                 ;;
  +             * )
  +                 if ./helpers/TestCompile lib dl; then
  +	             DL_LIB="-ldl"
  +                 fi
  +                 ;;
  +        esac 
  +        if [ ".$DL_LIB" != . ]; then
  +	    LIBS="$LIBS $DL_LIB"
    	    echo " + using $DL_LIB for DSO support"
           fi
       fi
  
  
  
  1.11      +7 -0      apache-1.3/src/os/unix/os.c
  
  Index: os.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/os/unix/os.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- os.c	1998/04/19 12:25:22	1.10
  +++ os.c	1998/04/28 08:42:11	1.11
  @@ -14,6 +14,13 @@
   void ap_is_not_here(void) {}
   
   /*
  + * Insert the DSO emulation code for AIX
  + */
  +#ifdef AIX
  +#include "os-aix-dso.c"
  +#endif
  +
  +/*
    *  Abstraction layer for loading
    *  Apache modules under run-time via 
    *  dynamic shared object (DSO) mechanism
  
  
  
  1.1                  apache-1.3/src/os/unix/os-aix-dso.c
  
  Index: os-aix-dso.c
  ===================================================================
  /* ====================================================================
   * Copyright (c) 1998 The Apache Group.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * 4. The names "Apache Server" and "Apache Group" must not be used to
   *    endorse or promote products derived from this software without
   *    prior written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Group and was originally based
   * on public domain software written at the National Center for
   * Supercomputing Applications, University of Illinois, Urbana-Champaign.
   * For more information on the Apache Group and the Apache HTTP server
   * project, please see <http://www.apache.org/>.
   *
   */
  
  /*
  **  os-aix-dso.c -- DSO system function emulation for AIX
   */
  
  /*
  **  Based on libdl (dlfcn.c/dlfcn.h) which is
  **  Copyright (c) 1992,1993,1995,1996,1997,1988
  **  Jens-Uwe Mager, Helios Software GmbH, Hannover, Germany.
  **
  **  Not derived from licensed software.
  **
  **  Permission is granted to freely use, copy, modify, and redistribute
  **  this software, provided that the author is not construed to be liable
  **  for any results of using the software, alterations are clearly marked
  **  as such, and this notice is not modified.
  **
  **  Changes marked with `--jwe' were made on April 7 1996 by
  **  John W. Eaton <jw...@bevo.che.wisc.edu> to support g++ 
  **
  **  Bundled, stripped and adjusted on April 1998 as one single source file 
  **  for inclusion into the Apache HTTP server by 
  **  Ralf S. Engelschall <rs...@apache.org>
  */
  
  #include <stdio.h>
  #include <errno.h>
  #include <string.h>
  #include <stdlib.h>
  #include <sys/types.h>
  #include <sys/ldr.h>
  #include <a.out.h>
  
  #undef FREAD
  #undef FWRITE
  #include <ldfcn.h>
  
  /*
   * Mode flags for the dlopen routine.
   */
  #undef  RTLD_LAZY
  #define RTLD_LAZY	1	/* lazy function call binding */
  #undef  RTLD_NOW
  #define RTLD_NOW	2	/* immediate function call binding */
  #undef  RTLD_GLOBAL
  #define RTLD_GLOBAL	0x100	/* allow symbols to be global */
  
  /*
   * To be able to intialize, a library may provide a dl_info structure
   * that contains functions to be called to initialize and terminate.
   */
  struct dl_info {
      void (*init) (void);
      void (*fini) (void);
  };
  
  
  /*
   *  Forward declarations
   */
  void *dlopen(const char *path, int mode);
  void *dlsym(void *handle, const char *symbol);
  const char *dlerror(void);
  int dlclose(void *handle);
  
  /*
   * We simulate dlopen() et al. through a call to load. Because AIX has
   * no call to find an exported symbol we read the loader section of the
   * loaded module and build a list of exported symbols and their virtual
   * address.
   */
  
  typedef struct {
      char *name;			/* the symbols's name */
      void *addr;			/* its relocated virtual address */
  } Export, *ExportPtr;
  
  /*
   * xlC uses the following structure to list its constructors and
   * destructors. This is gleaned from the output of munch.
   */
  typedef struct {
      void (*init) (void);	/* call static constructors */
      void (*term) (void);	/* call static destructors */
  } Cdtor, *CdtorPtr;
  
  typedef void (*GccCDtorPtr) (void);
  
  /*
   * The void * handle returned from dlopen is actually a ModulePtr.
   */
  typedef struct Module {
      struct Module *next;
      char *name;			/* module name for refcounting */
      int refCnt;			/* the number of references */
      void *entry;		/* entry point from load */
      struct dl_info *info;	/* optional init/terminate functions */
      CdtorPtr cdtors;		/* optional C++ constructors */
      GccCDtorPtr gcc_ctor;	/* g++ constructors  --jwe */
      GccCDtorPtr gcc_dtor;	/* g++ destructors  --jwe */
      int nExports;		/* the number of exports found */
      ExportPtr exports;		/* the array of exports */
  } Module, *ModulePtr;
  
  /*
   * We keep a list of all loaded modules to be able to call the fini
   * handlers and destructors at atexit() time.
   */
  static ModulePtr modList;
  
  /*
   * The last error from one of the dl* routines is kept in static
   * variables here. Each error is returned only once to the caller.
   */
  static char errbuf[BUFSIZ];
  static int errvalid;
  
  /*
   * The `fixed' gcc header files on AIX 3.2.5 provide a prototype for
   * strdup().  --jwe
   */
  extern char *strdup(const char *);
  static void caterr(char *);
  static int readExports(ModulePtr);
  static void terminate(void);
  static void *findMain(void);
  
  void *dlopen(const char *path, int mode)
  {
      register ModulePtr mp;
      static void *mainModule;
  
      /*
       * Upon the first call register a terminate handler that will
       * close all libraries. Also get a reference to the main module
       * for use with loadbind.
       */
      if (!mainModule) {
  	if ((mainModule = findMain()) == NULL)
  	    return NULL;
  	atexit(terminate);
      }
      /*
       * Scan the list of modules if we have the module already loaded.
       */
      for (mp = modList; mp; mp = mp->next)
  	if (strcmp(mp->name, path) == 0) {
  	    mp->refCnt++;
  	    return mp;
  	}
      if ((mp = (ModulePtr) calloc(1, sizeof(*mp))) == NULL) {
  	errvalid++;
  	strcpy(errbuf, "calloc: ");
  	strcat(errbuf, strerror(errno));
  	return NULL;
      }
      if ((mp->name = strdup(path)) == NULL) {
  	errvalid++;
  	strcpy(errbuf, "strdup: ");
  	strcat(errbuf, strerror(errno));
  	free(mp);
  	return NULL;
      }
      /*
       * load should be declared load(const char *...). Thus we
       * cast the path to a normal char *. Ugly.
       */
      if ((mp->entry = (void *) load((char *) path, L_NOAUTODEFER, NULL)) == NULL) {
  	free(mp->name);
  	free(mp);
  	errvalid++;
  	strcpy(errbuf, "dlopen: ");
  	strcat(errbuf, path);
  	strcat(errbuf, ": ");
  	/*
  	 * If AIX says the file is not executable, the error
  	 * can be further described by querying the loader about
  	 * the last error.
  	 */
  	if (errno == ENOEXEC) {
  	    char *tmp[BUFSIZ / sizeof(char *)];
  	    if (loadquery(L_GETMESSAGES, tmp, sizeof(tmp)) == -1)
  		strcpy(errbuf, strerror(errno));
  	    else {
  		char **p;
  		for (p = tmp; *p; p++)
  		    caterr(*p);
  	    }
  	}
  	else
  	    strcat(errbuf, strerror(errno));
  	return NULL;
      }
      mp->refCnt = 1;
      mp->next = modList;
      modList = mp;
      if (loadbind(0, mainModule, mp->entry) == -1) {
  	dlclose(mp);
  	errvalid++;
  	strcpy(errbuf, "loadbind: ");
  	strcat(errbuf, strerror(errno));
  	return NULL;
      }
      /*
       * If the user wants global binding, loadbind against all other
       * loaded modules.
       */
      if (mode & RTLD_GLOBAL) {
  	register ModulePtr mp1;
  	for (mp1 = mp->next; mp1; mp1 = mp1->next)
  	    if (loadbind(0, mp1->entry, mp->entry) == -1) {
  		dlclose(mp);
  		errvalid++;
  		strcpy(errbuf, "loadbind: ");
  		strcat(errbuf, strerror(errno));
  		return NULL;
  	    }
      }
      if (readExports(mp) == -1) {
  	dlclose(mp);
  	return NULL;
      }
      /*
       * If there is a dl_info structure, call the init function.
       */
      if (mp->info = (struct dl_info *) dlsym(mp, "dl_info")) {
  	if (mp->info->init)
  	    (*mp->info->init) ();
      }
      else
  	errvalid = 0;
      /*
       * If the shared object was compiled using xlC we will need
       * to call static constructors (and later on dlclose destructors).
       */
      if (mp->cdtors = (CdtorPtr) dlsym(mp, "__cdtors")) {
  	CdtorPtr cp = mp->cdtors;
  	while (cp->init || cp->term) {
  	    if (cp->init && cp->init != (void (*)(void)) 0xffffffff)
  		(*cp->init) ();
  	    cp++;
  	}
  	/*
  	 * If the shared object was compiled using g++, we will need
  	 * to call global constructors using the _GLOBAL__DI function,
  	 * and later, global destructors using the _GLOBAL_DD
  	 * funciton.  --jwe
  	 */
      }
      else if (mp->gcc_ctor = (GccCDtorPtr) dlsym(mp, "_GLOBAL__DI")) {
  	(*mp->gcc_ctor) ();
  	mp->gcc_dtor = (GccCDtorPtr) dlsym(mp, "_GLOBAL__DD");
      }
      else
  	errvalid = 0;
      return mp;
  }
  
  /*
   * Attempt to decipher an AIX loader error message and append it
   * to our static error message buffer.
   */
  static void caterr(char *s)
  {
      register char *p = s;
  
      while (*p >= '0' && *p <= '9')
  	p++;
      switch (atoi(s)) {
      case L_ERROR_TOOMANY:
  	strcat(errbuf, "to many errors");
  	break;
      case L_ERROR_NOLIB:
  	strcat(errbuf, "can't load library");
  	strcat(errbuf, p);
  	break;
      case L_ERROR_UNDEF:
  	strcat(errbuf, "can't find symbol");
  	strcat(errbuf, p);
  	break;
      case L_ERROR_RLDBAD:
  	strcat(errbuf, "bad RLD");
  	strcat(errbuf, p);
  	break;
      case L_ERROR_FORMAT:
  	strcat(errbuf, "bad exec format in");
  	strcat(errbuf, p);
  	break;
      case L_ERROR_ERRNO:
  	strcat(errbuf, strerror(atoi(++p)));
  	break;
      default:
  	strcat(errbuf, s);
  	break;
      }
  }
  
  void *dlsym(void *handle, const char *symbol)
  {
      register ModulePtr mp = (ModulePtr) handle;
      register ExportPtr ep;
      register int i;
  
      /*
       * Could speed up the search, but I assume that one assigns
       * the result to function pointers anyways.
       */
      for (ep = mp->exports, i = mp->nExports; i; i--, ep++)
  	if (strcmp(ep->name, symbol) == 0)
  	    return ep->addr;
      errvalid++;
      strcpy(errbuf, "dlsym: undefined symbol ");
      strcat(errbuf, symbol);
      return NULL;
  }
  
  const char *dlerror(void)
  {
      if (errvalid) {
  	errvalid = 0;
  	return errbuf;
      }
      return NULL;
  }
  
  int dlclose(void *handle)
  {
      register ModulePtr mp = (ModulePtr) handle;
      int result;
      register ModulePtr mp1;
  
      if (--mp->refCnt > 0)
  	return 0;
      if (mp->info && mp->info->fini)
  	(*mp->info->fini) ();
      if (mp->cdtors) {
  	CdtorPtr cp = mp->cdtors;
  	while (cp->init || cp->term) {
  	    if (cp->term && cp->init != (void (*)(void)) 0xffffffff)
  		(*cp->term) ();
  	    cp++;
  	}
  	/*
  	 * If the function to handle global destructors for g++
  	 * exists, call it.  --jwe
  	 */
      }
      else if (mp->gcc_dtor) {
  	(*mp->gcc_dtor) ();
      }
      result = unload(mp->entry);
      if (result == -1) {
  	errvalid++;
  	strcpy(errbuf, strerror(errno));
      }
      if (mp->exports) {
  	register ExportPtr ep;
  	register int i;
  	for (ep = mp->exports, i = mp->nExports; i; i--, ep++)
  	    if (ep->name)
  		free(ep->name);
  	free(mp->exports);
      }
      if (mp == modList)
  	modList = mp->next;
      else {
  	for (mp1 = modList; mp1; mp1 = mp1->next)
  	    if (mp1->next == mp) {
  		mp1->next = mp->next;
  		break;
  	    }
      }
      free(mp->name);
      free(mp);
      return result;
  }
  
  static void terminate(void)
  {
      while (modList)
  	dlclose(modList);
  }
  
  /*
   * Build the export table from the XCOFF .loader section.
   */
  static int readExports(ModulePtr mp)
  {
      LDFILE *ldp = NULL;
      SCNHDR sh, shdata;
      LDHDR *lhp;
      char *ldbuf;
      LDSYM *ls;
      int i;
      ExportPtr ep;
      struct ld_info *lp;
      char *buf;
      int size = 4 * 1024;
      void *dataorg;
  
      /*
       * The module might be loaded due to the LIBPATH
       * environment variable. Search for the loaded
       * module using L_GETINFO.
       */
      if ((buf = malloc(size)) == NULL) {
  	errvalid++;
  	strcpy(errbuf, "readExports: ");
  	strcat(errbuf, strerror(errno));
  	return -1;
      }
      while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
  	free(buf);
  	size += 4 * 1024;
  	if ((buf = malloc(size)) == NULL) {
  	    errvalid++;
  	    strcpy(errbuf, "readExports: ");
  	    strcat(errbuf, strerror(errno));
  	    return -1;
  	}
      }
      if (i == -1) {
  	errvalid++;
  	strcpy(errbuf, "readExports: ");
  	strcat(errbuf, strerror(errno));
  	free(buf);
  	return -1;
      }
      /*
       * Traverse the list of loaded modules. The entry point
       * returned by load() does actually point to the TOC
       * entry contained in the data segment.
       */
      lp = (struct ld_info *) buf;
      while (lp) {
  	if ((unsigned long) mp->entry >= (unsigned long) lp->ldinfo_dataorg &&
  	    (unsigned long) mp->entry < (unsigned long) lp->ldinfo_dataorg +
  	    lp->ldinfo_datasize) {
  	    dataorg = lp->ldinfo_dataorg;
  	    ldp = ldopen(lp->ldinfo_filename, ldp);
  	    break;
  	}
  	if (lp->ldinfo_next == 0)
  	    lp = NULL;
  	else
  	    lp = (struct ld_info *) ((char *) lp + lp->ldinfo_next);
      }
      free(buf);
      if (!ldp) {
  	errvalid++;
  	strcpy(errbuf, "readExports: ");
  	strcat(errbuf, strerror(errno));
  	return -1;
      }
      if (TYPE(ldp) != U802TOCMAGIC) {
  	errvalid++;
  	strcpy(errbuf, "readExports: bad magic");
  	while (ldclose(ldp) == FAILURE);
  	return -1;
      }
      /*
       * Get the padding for the data section. This is needed for
       * AIX 4.1 compilers. This is used when building the final
       * function pointer to the exported symbol.
       */
      if (ldnshread(ldp, _DATA, &shdata) != SUCCESS) {
  	errvalid++;
  	strcpy(errbuf, "readExports: cannot read data section header");
  	while (ldclose(ldp) == FAILURE);
  	return -1;
      }
      if (ldnshread(ldp, _LOADER, &sh) != SUCCESS) {
  	errvalid++;
  	strcpy(errbuf, "readExports: cannot read loader section header");
  	while (ldclose(ldp) == FAILURE);
  	return -1;
      }
      /*
       * We read the complete loader section in one chunk, this makes
       * finding long symbol names residing in the string table easier.
       */
      if ((ldbuf = (char *) malloc(sh.s_size)) == NULL) {
  	errvalid++;
  	strcpy(errbuf, "readExports: ");
  	strcat(errbuf, strerror(errno));
  	while (ldclose(ldp) == FAILURE);
  	return -1;
      }
      if (FSEEK(ldp, sh.s_scnptr, BEGINNING) != OKFSEEK) {
  	errvalid++;
  	strcpy(errbuf, "readExports: cannot seek to loader section");
  	free(ldbuf);
  	while (ldclose(ldp) == FAILURE);
  	return -1;
      }
      if (FREAD(ldbuf, sh.s_size, 1, ldp) != 1) {
  	errvalid++;
  	strcpy(errbuf, "readExports: cannot read loader section");
  	free(ldbuf);
  	while (ldclose(ldp) == FAILURE);
  	return -1;
      }
      lhp = (LDHDR *) ldbuf;
      ls = (LDSYM *) (ldbuf + LDHDRSZ);
      /*
       * Count the number of exports to include in our export table.
       */
      for (i = lhp->l_nsyms; i; i--, ls++) {
  	if (!LDR_EXPORT(*ls))
  	    continue;
  	mp->nExports++;
      }
      if ((mp->exports = (ExportPtr) calloc(mp->nExports, sizeof(*mp->exports))) == NULL) {
  	errvalid++;
  	strcpy(errbuf, "readExports: ");
  	strcat(errbuf, strerror(errno));
  	free(ldbuf);
  	while (ldclose(ldp) == FAILURE);
  	return -1;
      }
      /*
       * Fill in the export table. All entries are relative to
       * the beginning of the data origin.
       */
      ep = mp->exports;
      ls = (LDSYM *) (ldbuf + LDHDRSZ);
      for (i = lhp->l_nsyms; i; i--, ls++) {
  	char *symname;
  	char tmpsym[SYMNMLEN + 1];
  	if (!LDR_EXPORT(*ls))
  	    continue;
  	if (ls->l_zeroes == 0)
  	    symname = ls->l_offset + lhp->l_stoff + ldbuf;
  	else {
  	    /*
  	     * The l_name member is not zero terminated, we
  	     * must copy the first SYMNMLEN chars and make
  	     * sure we have a zero byte at the end.
  	     */
  	    strncpy(tmpsym, ls->l_name, SYMNMLEN);
  	    tmpsym[SYMNMLEN] = '\0';
  	    symname = tmpsym;
  	}
  	ep->name = strdup(symname);
  	ep->addr = (void *) ((unsigned long) dataorg +
  			     ls->l_value - shdata.s_vaddr);
  	ep++;
      }
      free(ldbuf);
      while (ldclose(ldp) == FAILURE);
      return 0;
  }
  
  /*
   * Find the main modules data origin. This is used as export pointer
   * for loadbind() to be able to resolve references to the main part.
   */
  static void *findMain(void)
  {
      struct ld_info *lp;
      char *buf;
      int size = 4 * 1024;
      int i;
      void *ret;
  
      if ((buf = malloc(size)) == NULL) {
  	errvalid++;
  	strcpy(errbuf, "findMain: ");
  	strcat(errbuf, strerror(errno));
  	return NULL;
      }
      while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
  	free(buf);
  	size += 4 * 1024;
  	if ((buf = malloc(size)) == NULL) {
  	    errvalid++;
  	    strcpy(errbuf, "findMain: ");
  	    strcat(errbuf, strerror(errno));
  	    return NULL;
  	}
      }
      if (i == -1) {
  	errvalid++;
  	strcpy(errbuf, "findMain: ");
  	strcat(errbuf, strerror(errno));
  	free(buf);
  	return NULL;
      }
      /*
       * The first entry is the main module. The data segment
       * starts with the TOC entries for all exports, so the
       * data segment origin works as argument for loadbind.
       */
      lp = (struct ld_info *) buf;
      ret = lp->ldinfo_dataorg;
      free(buf);
      return ret;
  }
  
  
  
  1.1                  apache-1.3/src/support/httpd.exp
  
  Index: httpd.exp
  ===================================================================
  #!
  ap_MD5Final
  ap_MD5Init
  ap_MD5Update
  ap_add_cgi_vars
  ap_add_common_vars
  ap_add_module
  ap_add_named_module
  ap_add_per_dir_conf
  ap_add_per_url_conf
  ap_allow_options
  ap_allow_overrides
  ap_append_arrays
  ap_array_cat
  ap_auth_name
  ap_auth_type
  ap_basic_http_header
  ap_bclose
  ap_bcreate
  ap_bfilbuf
  ap_bfileno
  ap_bflsbuf
  ap_bflush
  ap_bgetopt
  ap_bgets
  ap_bhalfduplex
  ap_bind_address
  ap_block_alarms
  ap_blookc
  ap_bnonblock
  ap_bonerror
  ap_bprintf
  ap_bpushfd
  ap_bputs
  ap_bread
  ap_bsetflag
  ap_bsetopt
  ap_bskiplf
  ap_bvputs
  ap_bwrite
  ap_bytes_in_free_blocks
  ap_bytes_in_pool
  ap_call_exec
  ap_can_exec
  ap_cfg_closefile
  ap_cfg_getc
  ap_cfg_getline
  ap_chdir_file
  ap_check_access
  ap_check_auth
  ap_check_cmd_context
  ap_check_user_id
  ap_checkmask
  ap_child_exit_modules
  ap_child_init_modules
  ap_child_terminate
  ap_cleanup_for_exec
  ap_clear_module_list
  ap_clear_pool
  ap_clear_table
  ap_close_piped_log
  ap_construct_server
  ap_construct_url
  ap_copy_array
  ap_copy_array_hdr
  ap_copy_table
  ap_core_reorder_directories
  ap_coredump_dir
  ap_count_dirs
  ap_cpystrn
  ap_create_environment
  ap_create_per_dir_config
  ap_create_request_config
  ap_daemons_limit
  ap_daemons_max_free
  ap_daemons_min_free
  ap_daemons_to_start
  ap_day_snames
  ap_default_port_for_request
  ap_default_port_for_scheme
  ap_default_type
  ap_destroy_pool
  ap_destroy_sub_req
  ap_die
  ap_discard_request_body
  ap_document_root
  ap_dummy_mutex
  ap_each_byterange
  ap_error_log2stderr
  ap_escape_html
  ap_escape_path_segment
  ap_escape_quotes
  ap_escape_shell_cmd
  ap_excess_requests_per_child
  ap_exists_scoreboard_image
  ap_finalize_request_protocol
  ap_finalize_sub_req_protocol
  ap_find_command
  ap_find_command_in_modules
  ap_find_last_token
  ap_find_linked_module
  ap_find_module_name
  ap_find_path_info
  ap_find_token
  ap_find_types
  ap_fini_vhost_config
  ap_fnmatch
  ap_force_library_loading
  ap_get_basic_auth_pw
  ap_get_client_block
  ap_get_gmtoff
  ap_get_local_host
  ap_get_module_config
  ap_get_remote_host
  ap_get_remote_logname
  ap_get_server_built
  ap_get_server_name
  ap_get_server_port
  ap_get_server_version
  ap_get_time
  ap_get_token
  ap_get_virthost_addr
  ap_getparents
  ap_getword
  ap_getword_conf
  ap_getword_conf_nc
  ap_getword_nc
  ap_getword_nulls
  ap_getword_nulls_nc
  ap_getword_white
  ap_getword_white_nc
  ap_gm_timestr_822
  ap_gname2id
  ap_group_id
  ap_handle_command
  ap_hard_timeout
  ap_header_parse
  ap_ht_time
  ap_ind
  ap_index_of_response
  ap_init_alloc
  ap_init_modules
  ap_init_vhost_config
  ap_init_virtual_host
  ap_internal_redirect
  ap_internal_redirect_handler
  ap_invoke_handler
  ap_is_directory
  ap_is_fnmatch
  ap_is_initial_req
  ap_is_matchexp
  ap_is_url
  ap_keepalive_timeout
  ap_kill_cleanup
  ap_kill_cleanups_for_fd
  ap_kill_cleanups_for_socket
  ap_kill_timeout
  ap_limit_section
  ap_listenbacklog
  ap_listeners
  ap_lock_fname
  ap_log_assert
  ap_log_error
  ap_log_error_old
  ap_log_pid
  ap_log_printf
  ap_log_reason
  ap_log_transaction
  ap_log_unixerr
  ap_make_array
  ap_make_dirstr
  ap_make_dirstr_parent
  ap_make_dirstr_prefix
  ap_make_full_path
  ap_make_sub_pool
  ap_make_table
  ap_matches_request_vhost
  ap_max_requests_per_child
  ap_md5
  ap_md5contextTo64
  ap_md5digest
  ap_meets_conditions
  ap_merge_per_dir_configs
  ap_month_snames
  ap_no2slash
  ap_note_auth_failure
  ap_note_basic_auth_failure
  ap_note_cleanups_for_fd
  ap_note_cleanups_for_file
  ap_note_cleanups_for_socket
  ap_note_digest_auth_failure
  ap_note_subprocess
  ap_null_cleanup
  ap_open_logs
  ap_open_piped_log
  ap_os_escape_path
  ap_os_is_path_absolute
  ap_overlay_tables
  ap_palloc
  ap_parseHTTPdate
  ap_parse_hostinfo_components
  ap_parse_htaccess
  ap_parse_uri
  ap_parse_uri_components
  ap_parse_vhost_addrs
  ap_pcalloc
  ap_pcfg_open_custom
  ap_pcfg_openfile
  ap_pclosedir
  ap_pclosef
  ap_pclosesocket
  ap_pduphostent
  ap_pfclose
  ap_pfdopen
  ap_pfopen
  ap_pgethostbyname
  ap_pid_fname
  ap_popendir
  ap_popenf
  ap_pregcomp
  ap_pregfree
  ap_pregsub
  ap_prelinked_modules
  ap_preloaded_modules
  ap_process_request
  ap_process_resource_config
  ap_psignature
  ap_psocket
  ap_psprintf
  ap_pstrcat
  ap_pstrdup
  ap_pstrndup
  ap_push_array
  ap_pvsprintf
  ap_rationalize_mtime
  ap_read_config
  ap_read_request
  ap_register_cleanup
  ap_register_other_child
  ap_remove_module
  ap_requires
  ap_reset_timeout
  ap_response_code_string
  ap_restart_time
  ap_rfc1413
  ap_rfc1413_timeout
  ap_rflush
  ap_rind
  ap_rprintf
  ap_rputc
  ap_rputs
  ap_run_cleanup
  ap_run_fixups
  ap_run_post_read_request
  ap_run_sub_req
  ap_rvputs
  ap_rwrite
  ap_satisfies
  ap_scan_script_header_err
  ap_scan_script_header_err_buff
  ap_scoreboard_fname
  ap_scoreboard_image
  ap_send_error_response
  ap_send_fb
  ap_send_fb_length
  ap_send_fd
  ap_send_fd_length
  ap_send_header_field
  ap_send_http_header
  ap_send_http_options
  ap_send_http_trace
  ap_send_mmap
  ap_send_size
  ap_server_argv0
  ap_server_confname
  ap_server_post_read_config
  ap_server_pre_read_config
  ap_server_root
  ap_server_root_relative
  ap_set_byterange
  ap_set_callback_and_alarm
  ap_set_content_length
  ap_set_etag
  ap_set_file_slot
  ap_set_flag_slot
  ap_set_keepalive
  ap_set_last_modified
  ap_set_module_config
  ap_set_name_virtual_host
  ap_set_string_slot
  ap_set_string_slot_lower
  ap_set_sub_req_protocol
  ap_setup_client_block
  ap_setup_prelinked_modules
  ap_should_client_block
  ap_show_directives
  ap_show_modules
  ap_signal
  ap_slack
  ap_snprintf
  ap_soft_timeout
  ap_some_auth_required
  ap_spawn_child_err
  ap_spawn_child_err_buff
  ap_srm_command_loop
  ap_standalone
  ap_start_restart
  ap_start_shutdown
  ap_str_tolower
  ap_strcasecmp_match
  ap_strcmp_match
  ap_sub_req_lookup_file
  ap_sub_req_lookup_uri
  ap_suexec_enabled
  ap_sync_scoreboard_image
  ap_table_add
  ap_table_addn
  ap_table_do
  ap_table_get
  ap_table_merge
  ap_table_mergen
  ap_table_set
  ap_table_setn
  ap_table_unset
  ap_threads_per_child
  ap_tm2sec
  ap_translate_name
  ap_uname2id
  ap_unblock_alarms
  ap_unescape_url
  ap_unparse_uri_components
  ap_unregister_other_child
  ap_update_child_status
  ap_update_mtime
  ap_update_vhost_from_headers
  ap_update_vhost_given_ip
  ap_user_id
  ap_user_name
  ap_util_init
  ap_util_uri_init
  ap_uudecode
  ap_vbprintf
  ap_vformatter
  ap_vsnprintf
  core_module
  top_module
  
  
  

Re: cvs commit: apache-1.3/src/support httpd.exp

Posted by Brian Behlendorf <br...@hyperreal.org>.
At 08:42 AM 4/28/98 -0000, rse@hyperreal.org wrote:
>rse         98/04/28 01:42:13
>
>  Modified:    .        STATUS INSTALL
>               src      CHANGES Configure README.DSO
>               src/modules/standard mod_so.c
>               src/os/unix os.c
>  Added:       src/os/unix os-aix-dso.c
>               src/support httpd.exp
>  Log:
>  After the third interaction now we have it:
>  
>  Dynamic Shared Object (DSO) support for IBM's AIX.
>  
>  This is accomplished by using DSO emulation code because AIX <= 4.2
don't have
>  dlopen() and AIX 4.2 has a broken one.  But with the emulation code it
works
>  great.

Excellent work, Ralf.  We'll have to figure out some way to keep httpd.exp
up to date though.

	Brian


--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
pure chewing satisfaction                                  brian@apache.org
                                                        brian@hyperreal.org