Patchwork libgo patch committed: Solaris specific syslog support

login
register
mail settings
Submitter Ian Taylor
Date March 9, 2011, 10:13 p.m.
Message ID <mcraah4kkn7.fsf@google.com>
Download mbox | patch
Permalink /patch/86161/
State New
Headers show

Comments

Ian Taylor - March 9, 2011, 10:13 p.m.
This libgo patch implements Solaris specific syslog support.  On Solaris
we call the libc function rather than worrying about STREAMS.  This
should fix PR go/48018.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Patch

diff -r 08dcb2e2c1d2 libgo/Makefile.am
--- a/libgo/Makefile.am	Wed Mar 09 11:16:48 2011 -0800
+++ b/libgo/Makefile.am	Wed Mar 09 13:58:30 2011 -0800
@@ -787,8 +787,15 @@ 
 go_sync_c_files = \
 	go/sync/cas.c
 
+if LIBGO_IS_SOLARIS
+go_syslog_file = go/syslog/syslog_solaris.go
+else
+go_syslog_file = go/syslog/syslog_unix.go
+endif
+
 go_syslog_files = \
-	go/syslog/syslog.go
+	go/syslog/syslog.go \
+	$(go_syslog_file)
 
 go_tabwriter_files = \
 	go/tabwriter/tabwriter.go
@@ -1785,10 +1792,14 @@ 
 	$(CHECK)
 .PHONY: sync/check
 
-syslog/libsyslog.$(OBJEXT): $(go_syslog_files) fmt.gox log.gox net.gox os.gox
-	$(BUILDPACKAGE)
-syslog/libsyslog.lo: syslog/libsyslog.$(OBJEXT)
-syslog/libsyslog.la: syslog/libsyslog.lo
+syslog/syslog.$(OBJEXT): $(go_syslog_files) fmt.gox log.gox net.gox os.gox \
+		syscall.gox
+	test -d syslog || $(MKDIR_P) syslog
+	$(LTGOCOMPILE) -I . -c -o $@ -fgo-prefix=libgo_syslog $(srcdir)/go/syslog/syslog.go $(srcdir)/$(go_syslog_file)
+syslog/syslog_c.$(OBJEXT): $(srcdir)/go/syslog/syslog_c.c syslog/syslog.$(OBJEXT)
+	$(LTCOMPILE) -c -o $@ $(srcdir)/go/syslog/syslog_c.c
+syslog/libsyslog.la: syslog/syslog.$(OBJEXT) syslog/syslog_c.$(OBJEXT)
+	$(LINK) syslog/syslog.lo syslog/syslog_c.lo
 syslog/check: $(CHECK_DEPS)
 	$(CHECK)
 .PHONY: syslog/check
@@ -2733,7 +2744,7 @@ 
 	$(BUILDGOX)
 sync.gox: sync/mutex.$(OBJEXT)
 	$(BUILDGOX)
-syslog.gox: syslog/libsyslog.$(OBJEXT)
+syslog.gox: syslog/syslog.$(OBJEXT)
 	$(BUILDGOX)
 syscall.gox: syscalls/syscall.$(OBJEXT)
 	$(BUILDGOX)
diff -r 08dcb2e2c1d2 libgo/go/syslog/syslog.go
--- a/libgo/go/syslog/syslog.go	Wed Mar 09 11:16:48 2011 -0800
+++ b/libgo/go/syslog/syslog.go	Wed Mar 09 13:58:30 2011 -0800
@@ -34,7 +34,17 @@ 
 type Writer struct {
 	priority Priority
 	prefix   string
-	conn     net.Conn
+	conn     serverConn
+}
+
+type serverConn interface {
+	writeBytes(p Priority, prefix string, b []byte) (int, os.Error)
+	writeString(p Priority, prefix string, s string) (int, os.Error)
+	close() os.Error
+}
+
+type netConn struct {
+	conn net.Conn
 }
 
 // New establishes a new connection to the system log daemon.
@@ -52,46 +62,30 @@ 
 	if prefix == "" {
 		prefix = os.Args[0]
 	}
-	var conn net.Conn
+	var conn serverConn
 	if network == "" {
 		conn, err = unixSyslog()
 	} else {
-		conn, err = net.Dial(network, "", raddr)
+		var c net.Conn
+		c, err = net.Dial(network, "", raddr)
+		conn = netConn{c}
 	}
 	return &Writer{priority, prefix, conn}, err
 }
 
-func unixSyslog() (conn net.Conn, err os.Error) {
-	logTypes := []string{"unixgram", "unix"}
-	logPaths := []string{"/dev/log", "/var/run/syslog"}
-	var raddr string
-	for _, network := range logTypes {
-		for _, path := range logPaths {
-			raddr = path
-			conn, err := net.Dial(network, "", raddr)
-			if err != nil {
-				continue
-			} else {
-				return conn, nil
-			}
-		}
-	}
-	return nil, os.ErrorString("Unix syslog delivery error")
-}
-
 // Write sends a log message to the syslog daemon.
 func (w *Writer) Write(b []byte) (int, os.Error) {
 	if w.priority > LOG_DEBUG || w.priority < LOG_EMERG {
 		return 0, os.EINVAL
 	}
-	return fmt.Fprintf(w.conn, "<%d>%s: %s\n", w.priority, w.prefix, b)
+	return w.conn.writeBytes(w.priority, w.prefix, b)
 }
 
 func (w *Writer) writeString(p Priority, s string) (int, os.Error) {
-	return fmt.Fprintf(w.conn, "<%d>%s: %s\n", p, w.prefix, s)
+	return w.conn.writeString(p, w.prefix, s)
 }
 
-func (w *Writer) Close() os.Error { return w.conn.Close() }
+func (w *Writer) Close() os.Error { return w.conn.close() }
 
 // Emerg logs a message using the LOG_EMERG priority.
 func (w *Writer) Emerg(m string) (err os.Error) {
@@ -131,6 +125,18 @@ 
 	return err
 }
 
+func (n netConn) writeBytes(p Priority, prefix string, b []byte) (int, os.Error) {
+	return fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, b)
+}
+
+func (n netConn) writeString(p Priority, prefix string, s string) (int, os.Error) {
+	return fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, s)
+}
+
+func (n netConn) close() os.Error {
+	return n.conn.Close()
+}
+
 // NewLogger provides an object that implements the full log.Logger interface,
 // but sends messages to Syslog instead; flag is passed as is to Logger;
 // priority will be used for all messages sent using this interface.
diff -r 08dcb2e2c1d2 libgo/go/syslog/syslog_c.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/go/syslog/syslog_c.c	Wed Mar 09 13:58:30 2011 -0800
@@ -0,0 +1,19 @@ 
+/* syslog_c.c -- call syslog for Go.
+
+   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 <syslog.h>
+
+/* We need to use a C function to call the syslog function, because we
+   can't represent a C varargs function in Go.  */
+
+void syslog_c(int, const char*)
+  asm ("libgo_syslog.syslog.syslog_c");
+
+void
+syslog_c (int priority, const char *msg)
+{
+  syslog (priority, "%s", msg);
+}
diff -r 08dcb2e2c1d2 libgo/go/syslog/syslog_solaris.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/go/syslog/syslog_solaris.go	Wed Mar 09 13:58:30 2011 -0800
@@ -0,0 +1,37 @@ 
+// 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.
+
+// gccgo specific implementation of syslog for Solaris.  Solaris uses
+// STREAMS to communicate with syslogd.  That is enough of a pain that
+// we just call the libc function.
+
+package syslog
+
+import (
+	"fmt"
+	"os"
+	"syscall"
+)
+
+func unixSyslog() (conn serverConn, err os.Error) {
+	return libcConn(0), nil
+}
+
+type libcConn int
+
+func syslog_c(int, *byte)
+
+func (libcConn) writeBytes(p Priority, prefix string, b []byte) (int, os.Error) {
+	syslog_c(int(p), syscall.StringBytePtr(fmt.Sprintf("%s: %s", prefix, b)))
+	return len(b), nil
+}
+
+func (libcConn) writeString(p Priority, prefix string, s string) (int, os.Error) {
+	syslog_c(int(p), syscall.StringBytePtr(fmt.Sprintf("%s: %s", prefix, s)))
+	return len(s), nil
+}
+
+func (libcConn) close() os.Error {
+	return nil
+}
diff -r 08dcb2e2c1d2 libgo/go/syslog/syslog_unix.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/go/syslog/syslog_unix.go	Wed Mar 09 13:58:30 2011 -0800
@@ -0,0 +1,31 @@ 
+// Copyright 2009 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.
+
+package syslog
+
+import (
+	"net"
+	"os"
+)
+
+// unixSyslog opens a connection to the syslog daemon running on the
+// local machine using a Unix domain socket.
+
+func unixSyslog() (conn serverConn, err os.Error) {
+	logTypes := []string{"unixgram", "unix"}
+	logPaths := []string{"/dev/log", "/var/run/syslog"}
+	var raddr string
+	for _, network := range logTypes {
+		for _, path := range logPaths {
+			raddr = path
+			conn, err := net.Dial(network, "", raddr)
+			if err != nil {
+				continue
+			} else {
+				return netConn{conn}, nil
+			}
+		}
+	}
+	return nil, os.ErrorString("Unix syslog delivery error")
+}