On Tue, Jan 15, 2008 at 12:28:55AM +0100, Bruno Haible wrote:
> You fixed the first portability problem: the function is missing on some
> platforms. But there is another one.
> 
> I want to use the replacement in GNU clisp, so I did "man strsignal", and it
> says:
> 
>        "On some systems (but not on Linux), a NULL pointer may be returned
>         instead for an invalid signal number."
> 
> And it's even worse than that: for negative or out-of-range signal numbers,
> 
>   * Solaris strsignal returns NULL,
>   * AIX 5.1 strsignal returns (char*)(-1) !
> 
> As a user of this function, I don't want to special case these return values.
> The function should always return a reasonable pointer.

Thanks for pointing this out.

> So I propose to change the module so that, on these two platforms, it
> overrides the system function. Do you agree? May I do this? Do you want to
> do it?

I think the attached patch is right (I tested it with LIBS=-lstrsignal
after installing a bogus /usr/lib/libstrsignal.a with a strsignal
function that always returns NULL), but would appreciate review from
those more fluent in Autoconf than I am.

Is it sufficient to test a single value? It's been some time since I had
convenient access to either Solaris or AIX systems.

Cheers,

-- 
Colin Watson                                       [EMAIL PROTECTED]
diff --git a/lib/string.in.h b/lib/string.in.h
index 3354d20..7e6bd08 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -542,7 +542,10 @@ extern char *strerror (int);
 #endif
 
 #if @GNULIB_STRSIGNAL@
-# if ! @HAVE_DECL_STRSIGNAL@
+# if @REPLACE_STRSIGNAL@
+#  define strsignal rpl_strsignal
+# endif
+# if ! @HAVE_DECL_STRSIGNAL@ || @REPLACE_STRSIGNAL@
 extern char *strsignal (int __sig);
 # endif
 #elif defined GNULIB_POSIXCHECK
diff --git a/m4/string_h.m4 b/m4/string_h.m4
index 69761d7..12fa1bf 100644
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -80,6 +80,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
   HAVE_DECL_STRERROR=1;		AC_SUBST([HAVE_DECL_STRERROR])
   HAVE_DECL_STRSIGNAL=1;	AC_SUBST([HAVE_DECL_STRSIGNAL])
   REPLACE_STRERROR=0;		AC_SUBST([REPLACE_STRERROR])
+  REPLACE_STRSIGNAL=0;		AC_SUBST([REPLACE_STRSIGNAL])
   REPLACE_MEMMEM=0;		AC_SUBST([REPLACE_MEMMEM])
   REPLACE_STRSTR=0;		AC_SUBST([REPLACE_STRSTR])
 ])
diff --git a/m4/strsignal.m4 b/m4/strsignal.m4
index 9bcd374..e6f275b 100644
--- a/m4/strsignal.m4
+++ b/m4/strsignal.m4
@@ -12,10 +12,34 @@ AC_DEFUN([gl_FUNC_STRSIGNAL],
   AC_REQUIRE([AC_DECL_SYS_SIGLIST])
 
   AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
-  AC_REPLACE_FUNCS([strsignal])
+
   AC_CHECK_DECLS_ONCE([strsignal])
   if test $ac_cv_have_decl_strsignal = no; then
     HAVE_DECL_STRSIGNAL=0
+  fi
+
+  AC_CHECK_FUNCS([strsignal])
+  if test $ac_cv_func_strsignal = yes; then
+    dnl Check if strsignal behaves reasonably for out-of-range signal numbers.
+    dnl Solaris returns NULL; AIX 5.1 returns (char *) -1.
+    AC_CACHE_CHECK([for working strsignal function],
+      [gl_cv_func_working_strsignal],
+      [AC_RUN_IFELSE(
+	 [AC_LANG_PROGRAM(
+	    [[#include <string.h>
+	    ]],
+	    [[char *s = strsignal (-1);
+	      return !(s != (char *) 0 && s != (char *) -1);]])],
+	 [gl_cv_func_working_strsignal=yes],
+	 [gl_cv_func_working_strsignal=no],
+	 [gl_cv_func_working_strsignal=cross-compiling])])
+  else
+    gl_cv_func_working_strsignal=no
+  fi
+
+  if test $gl_cv_func_working_strsignal != yes; then
+    REPLACE_STRSIGNAL=1
+    AC_LIBOBJ([strsignal])
     gl_PREREQ_STRSIGNAL
   fi
 ])
diff --git a/modules/string b/modules/string
index 0a2fd71..f59a11e 100644
--- a/modules/string
+++ b/modules/string
@@ -72,6 +72,7 @@ string.h: string.in.h
 	      -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
 	      -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \
 	      -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \
+	      -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \
 	      -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
 	      < $(srcdir)/string.in.h; \
 	} > [EMAIL PROTECTED]
diff --git a/tests/test-strsignal.c b/tests/test-strsignal.c
index 16544f2..fa4c70f 100644
--- a/tests/test-strsignal.c
+++ b/tests/test-strsignal.c
@@ -65,5 +65,9 @@ main (int argc, char **argv)
   ASSERT_DESCRIPTION (str, "Interrupt");
 #endif
 
+  str = strsignal (-1);
+  ASSERT (str);
+  ASSERT (str != (char *) -1);
+
   return 0;
 }

Reply via email to