# Linux Configuration Support for ACE

levine@cs.wustl.edu

##

RedHat 5.1 is distributed with glibc-2.0.7-13 and egcs-1.0.2-8. ACE and TAO work just fine with it.

With RedHat 5.0 distributions of Linux, it's best to upgrade the distribution with these:

- glibc-2.0.7-7 or later, or
  glibc-2.0.6 (at ftp://sunsite.unc.edu/pub/gnu/glibc-2.0.6.tar.gz) plus Torbjörn's patch, below
- egcs 1.0.2 (from ftp://ftp.cygnus.com/pub/egcs/releases/)

Thanks to James CE Johnson <jjohnson@lads.com>, Torbjörn Lindgren <tl@funcom.com>, Oleg Krivosheev <kriol@fnal.gov>, and Chanaka Liyanaarachchi <chanakal@ittc.ukans.edu> for this information. With the above configurations, ACE compiles and runs cleanly on Intel platforms. It compiles and runs cleanly on Alpha platforms with the patches listed below.

WARNING: There is a bug in `getsockname ()` on versions of Linux through 2.0.34. `getsockname ()` returns an Internet host address of 127.0.0.1 (localhost) instead of 0.0.0.0 for sockets that aren't connected. This bug prevents TAO servers from working correctly. To fix it, comment out these two lines in function `inet_getname ()` in `/usr/src/linux/net/ipv4/af_inet.c`:

    	} else {
    		__u32 addr = sk->rcv_saddr;
    		if (!addr) {
    			addr = sk->saddr;
    /* comment out this line:  if (!addr) */
    /* comment out this line:  	addr = ip_my_addr(); */
    		}
    		sin->sin_port = sk->dummy_th.source;
    		sin->sin_addr.s_addr = addr;
    	}

and rebuild your kernel. This fix has been implemented in 2.1.x versions of the kernel.

Without the following patch from Scott Snyder <sss@d0linux01.fnal.gov>, egcs 1.0.1 on Linux won't be able to compile netsvcs/lib/Server_Logging_Handler.cpp:

    1997-12-10  scott snyder  <sss@d0linux01.fnal.gov>

    	* method.c (make_thunk): Avoid name buffer overflow.

    Index: gcc/cp/method.c
    ===================================================================
    RCS file: /d0sgi0/usr0/snyder/CVSROOT/egcs/gcc/cp/method.c,v
    retrieving revision 1.1.1.5
    diff -c -r1.1.1.5 method.c
    *** method.c    1997/12/08 21:06:03     1.1.1.5
    --- method.c    1997/12/11 05:40:37
    ***************
    *** 1811,1817 ****
           tree function;
           int delta;
      {
    !   char buffer[250];
        tree thunk_id;
        tree thunk;
        char *func_name;
    --- 1811,1817 ----
           tree function;
           int delta;
      {
    !   char *buffer;
        tree thunk_id;
        tree thunk;
        char *func_name;
    ***************
    *** 1822,1827 ****
    --- 1822,1828 ----
        if (TREE_CODE (func_decl) != FUNCTION_DECL)
          abort ();
        func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func_decl));
    +   buffer = (char *)alloca (strlen (func_name) + 32);
        if (delta<=0)
          sprintf (buffer, "__thunk_%d_%s", -delta, func_name);
        else

With RedHat 5.0 on Alpha CPUs, two system patches and one glibc-2.0.6/linuxthreads patch are necessary in addition to the above. The first patch is for the GNU assembler, gas. It is only necessary on Alphas, and only when `-g` is used. If you don't want to patch the assembler, you can enable the SUPPRESS_DASH_G option in the `platform_linux.GNu`. Otherwise, this patch can be applied to the binutils gas source. Then, rebuild and install as. The file to be patched is binutils-2.8.1/gas/config/tc-alpha.h:

NOTE: this patch isn't necessary with binutils-2.9.1.

    --- tc-alpha.h.orig	Mon May 26 12:32:38 1997
    +++ tc-alpha.h	Sat Feb 28 06:45:41 1998
    @@ -25,6 +25,8 @@

     #define TARGET_ARCH			bfd_arch_alpha

    +#define PAGE_SIZE 8192
    +
     #define TARGET_FORMAT (OUTPUT_FLAVOR == bfd_target_ecoff_flavour	\
     		       ? "ecoff-littlealpha"				\
     		       : OUTPUT_FLAVOR == bfd_target_elf_flavour	\

In addition, you'll need to patch `/usr/src/linux/include/linux/posix_types.h` as follows to avoid compilation errors:

    --- posix_types.h.ORIGINAL	Wed Nov 12 12:01:56 1997
    +++ posix_types.h	Fri Feb 27 14:13:16 1998
    @@ -41,9 +41,14 @@
     #undef __FDMASK
     #define	__FDMASK(d)	(1UL << ((d) % __NFDBITS))

    +#if defined (__KERNEL__)
     typedef struct fd_set {
     	unsigned long fds_bits [__FDSET_LONGS];
     } __kernel_fd_set;
    +#else  /* ! __KERNEL__ */
    +#include <gnu/types.h>
    +typedef __fd_set __kernel_fd_set;
    +#endif /* ! __KERNEL__ */

     /* Type of a signal handler.  */
     typedef void (*__kernel_sighandler_t)(int);

Finally, on Alpha only, I removed wrapsyscall from the LinuxThreads library by patching linuxthreads/Makefile:

    36c36
    <                      semaphore wrapsyscall
    ---
    >                      semaphore # wrapsyscall

With that and the above configuration/pathes, all ACE tests run perfectly cleanly on Alpha!

### Old Patches

If you use glibc-2.0.6, you'll need to apply Torbjörn Lindgren's <tl@funcom.com> patch to glibc-2.0.6's LinuxThreads:

    --- signals.c.old	Wed Jan 14 01:09:02 1998
    +++ signals.c	Wed Jan 14 01:11:37 1998
    @@ -82,7 +82,7 @@
       pthread_mutex_lock(&sigwaited_mut);
       /* Make sure no other thread is waiting on our signals */
     test_again:
    -  for (s = 0; s < NSIG; s++) {
    +  for (s = 1; s < NSIG; s++) {
         if (sigismember(set, s) && sigismember(&sigwaited, s)) {
           pthread_cond_wait(&sigwaited_changed, &sigwaited_mut);
           goto test_again;
    @@ -96,7 +96,7 @@
       /* Install our signal handler on all signals in set,
          and unblock them in mask.
          Also mark those signals as being sigwaited on */
    -  for (s = 1; s <= NSIG; s++) {
    +  for (s = 1; s < NSIG; s++) {
         if (sigismember(set, s) && s != PTHREAD_SIG_CANCEL) {
           sigdelset(&mask, s);
           action.sa_handler = __pthread_sighandler;
    @@ -121,7 +121,7 @@
       self->p_cancel_jmp = NULL;
       /* The signals are now reblocked. Restore the sighandlers. */
       pthread_mutex_lock(&sigwaited_mut);
    -  for (s = 1; s <= NSIG; s++) {
    +  for (s = 1; s < NSIG; s++) {
         if (sigismember(set, s) && s != PTHREAD_SIG_CANCEL) {
           sigaction(s, &(saved_signals[s]), NULL);
           sigdelset(&sigwaited, s);