diff mbox

[libgo] Provide strerror_r replacement (PR go/47515)

Message ID yddbp13833u.fsf@manam.CeBiTec.Uni-Bielefeld.DE
State New
Headers show

Commit Message

Rainer Orth March 22, 2011, 5:41 p.m. UTC
Apart from the lack of wait4, libgo on IRIX 6.5 contained an undefined
reference to strerror_r.  This patch provides a replacement, based on
gnulib/lib/strerror_r.c, but massively simplified.

This allowed me to link with libgo, and has been tested on
i386-pc-solaris2.11 with the result of the configure test manually
inverted.

	Rainer


2011-01-30  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR go/47515
	* configure.ac: Check for strerror_r.
	* configure: Regenerate.
	* config.h.in: Regenerate.
	* syscalls/strerror_r.c: New file.
	* Makefile.am (go_syscall_c_files): Use it.
	(syscalls/strerror_r.lo): New target.
	* Makefile.in: Regenerate.

Comments

Jakub Jelinek March 22, 2011, 5:46 p.m. UTC | #1
On Tue, Mar 22, 2011 at 06:41:25PM +0100, Rainer Orth wrote:
> Apart from the lack of wait4, libgo on IRIX 6.5 contained an undefined
> reference to strerror_r.  This patch provides a replacement, based on
> gnulib/lib/strerror_r.c, but massively simplified.

gnulib strerror_r.c is GPLv3+ licensed, you can't just relicense it
as BSD.

> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
> +++ b/libgo/syscalls/strerror_r.c	Sat Mar 19 21:55:54 2011 +0100
> @@ -0,0 +1,38 @@
> +/* strerror_r.c -- strerror_r replacement for systems with strerror only
> +
> +   Copyright 2011 The Go Authors. All rights reserved.
> +   Use of this source code is governed by a BSD-style
> +   license that can be found in the LICENSE file.  */
> +
> +#include "config.h"
> +#ifndef HAVE_STRERROR_R
> +#include <errno.h>
> +#include <string.h>
> +#include <pthread.h>
> +
> +/* This lock protects the buffer returned by strerror().  We assume that
> +   no other uses of strerror() exist in the program.  */
> +static pthread_mutex_t strerror_lock = PTHREAD_MUTEX_INITIALIZER;;
> +
> +int
> +strerror_r (int errnum, char *buf, size_t buflen)
> +{
> +  char *errmsg = strerror (errnum);
> +  size_t len = strlen (errmsg);
> +  int ret;
> +
> +  pthread_mutex_lock (&strerror_lock);
> +
> +  if (len < buflen)
> +    {
> +      memcpy (buf, errmsg, len + 1);
> +      ret = 0;
> +    }
> +  else
> +    ret = ERANGE;
> +
> +  pthread_mutex_unlock (&strerror_lock);
> +
> +  return ret;
> +}
> +#endif /* HAVE_STRERROR_R */

	Jakub
Rainer Orth March 23, 2011, 12:45 p.m. UTC | #2
Jakub Jelinek <jakub@redhat.com> writes:

> On Tue, Mar 22, 2011 at 06:41:25PM +0100, Rainer Orth wrote:
>> Apart from the lack of wait4, libgo on IRIX 6.5 contained an undefined
>> reference to strerror_r.  This patch provides a replacement, based on
>> gnulib/lib/strerror_r.c, but massively simplified.
>
> gnulib strerror_r.c is GPLv3+ licensed, you can't just relicense it
> as BSD.

From my understanding, this is only an issue if the code is actually
copyrightable, i.e. the idea can reasonably expressed in different
ways.  I doubt that for the case at hand, but am not certain.

	Rainer
Ian Lance Taylor March 23, 2011, 1:48 p.m. UTC | #3
Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> Jakub Jelinek <jakub@redhat.com> writes:
>
>> On Tue, Mar 22, 2011 at 06:41:25PM +0100, Rainer Orth wrote:
>>> Apart from the lack of wait4, libgo on IRIX 6.5 contained an undefined
>>> reference to strerror_r.  This patch provides a replacement, based on
>>> gnulib/lib/strerror_r.c, but massively simplified.
>>
>> gnulib strerror_r.c is GPLv3+ licensed, you can't just relicense it
>> as BSD.
>
>>From my understanding, this is only an issue if the code is actually
> copyrightable, i.e. the idea can reasonably expressed in different
> ways.  I doubt that for the case at hand, but am not certain.

I think we should just have Go code that calls strerror anyhow.  There's
no reason to drop into C here.  I'll get to that at some point if nobody
else does.

Ian
Rainer Orth March 23, 2011, 1:56 p.m. UTC | #4
Ian Lance Taylor <iant@google.com> writes:

> I think we should just have Go code that calls strerror anyhow.  There's
> no reason to drop into C here.  I'll get to that at some point if nobody
> else does.

Fine with me.  I've just noticed that not only IRIX 6.5 is affected, but
Solaris 8 and 9, too.

	Rainer
diff mbox

Patch

diff -r 4fb11b32a76a libgo/Makefile.am
--- a/libgo/Makefile.am	Sat Mar 19 10:51:23 2011 +0100
+++ b/libgo/Makefile.am	Sat Mar 19 21:55:54 2011 +0100
@@ -1301,7 +1309,8 @@ 
 	sysinfo.go \
 	syscall_arch.go
 go_syscall_c_files = \
-	syscalls/errno.c
+	syscalls/errno.c \
+	syscalls/strerror_r.c
 
 if LIBGO_IS_LINUX
 # os_lib_inotify_lo = os/inotify.lo
@@ -2511,6 +2520,8 @@ 
 	$(BUILDPACKAGE)
 syscalls/errno.lo: $(go_syscall_c_files) syscalls/syscall.lo
 	$(LTCOMPILE) -c -o $@ $(srcdir)/syscalls/errno.c
+syscalls/strerror_r.lo: $(go_syscall_c_files) syscalls/syscall.lo
+	$(LTCOMPILE) -c -o $@ $(srcdir)/syscalls/strerror_r.c
 
 # How to build a .gox file from a .lo file.
 BUILDGOX = \
diff -r 4fb11b32a76a libgo/configure.ac
--- a/libgo/configure.ac	Sat Mar 19 10:51:23 2011 +0100
+++ b/libgo/configure.ac	Sat Mar 19 21:55:54 2011 +0100
@@ -380,7 +392,7 @@ 
 
 AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h)
 AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes)
-AC_CHECK_FUNCS(srandom random strsignal)
+AC_CHECK_FUNCS(srandom random strerror_r strsignal)
 
 AC_CACHE_CHECK([for __sync_bool_compare_and_swap_4],
 [libgo_cv_func___sync_bool_compare_and_swap_4],
diff -r 4fb11b32a76a libgo/syscalls/strerror_r.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/syscalls/strerror_r.c	Sat Mar 19 21:55:54 2011 +0100
@@ -0,0 +1,38 @@ 
+/* strerror_r.c -- strerror_r replacement for systems with strerror only
+
+   Copyright 2011 The Go Authors. All rights reserved.
+   Use of this source code is governed by a BSD-style
+   license that can be found in the LICENSE file.  */
+
+#include "config.h"
+#ifndef HAVE_STRERROR_R
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+
+/* This lock protects the buffer returned by strerror().  We assume that
+   no other uses of strerror() exist in the program.  */
+static pthread_mutex_t strerror_lock = PTHREAD_MUTEX_INITIALIZER;;
+
+int
+strerror_r (int errnum, char *buf, size_t buflen)
+{
+  char *errmsg = strerror (errnum);
+  size_t len = strlen (errmsg);
+  int ret;
+
+  pthread_mutex_lock (&strerror_lock);
+
+  if (len < buflen)
+    {
+      memcpy (buf, errmsg, len + 1);
+      ret = 0;
+    }
+  else
+    ret = ERANGE;
+
+  pthread_mutex_unlock (&strerror_lock);
+
+  return ret;
+}
+#endif /* HAVE_STRERROR_R */