]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: implement getwd on Solaris
authorShawn Walker-Salas <shawn.walker@oracle.com>
Fri, 4 Sep 2015 23:53:19 +0000 (16:53 -0700)
committerAram Hăvărneanu <aram@mgk.ro>
Wed, 9 Sep 2015 19:58:33 +0000 (19:58 +0000)
In support of the changes required for #8609, it was suggested that
syscall.getwd() be updated to work on Solaris first since the runtime
uses it and today it's unimplemented.

Fixes #12507

Change-Id: Ifb58ac9db8540936d5685c2c58bdc465dbc836cb
Reviewed-on: https://go-review.googlesource.com/14420
Reviewed-by: Aram Hăvărneanu <aram@mgk.ro>
src/syscall/mkerrors.sh
src/syscall/mksyscall_solaris.pl
src/syscall/syscall_solaris.go
src/syscall/types_solaris.go
src/syscall/zsyscall_solaris_amd64.go
src/syscall/ztypes_solaris_amd64.go

index 438de6e5d83ec49f9d6aa7cad3f806bc28073bcb..b59a46b18f777ab7819fcc190f9e22fd7793abe5 100755 (executable)
@@ -13,6 +13,11 @@ export LC_CTYPE=C
 
 CC=${CC:-gcc}
 
+if [[ "$GOOS" -eq "solaris" ]]; then
+       # Assumes GNU versions of utilities in PATH.
+       export PATH=/usr/gnu/bin:$PATH
+fi
+
 uname=$(uname)
 
 includes_Darwin='
@@ -195,6 +200,7 @@ includes_OpenBSD='
 '
 
 includes_SunOS='
+#include <limits.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
index f5eb4b36e8fb52fda1e8838f1b2037ab34819d6a..cd69ebc8a2f58bf716c542435105b6304dbea07e 100755 (executable)
@@ -38,6 +38,11 @@ if($ARGV[0] =~ /^-/) {
        exit 1;
 }
 
+if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
+       print STDERR "GOARCH or GOOS not defined in environment\n";
+       exit 1;
+}
+
 sub parseparamlist($) {
        my ($list) = @_;
        $list =~ s/^\s*//;
@@ -60,9 +65,9 @@ sub parseparam($) {
 
 my $package = "";
 my $text = "";
-my $vars = "";
 my $dynimports = "";
 my $linknames = "";
+my @vars = ();
 while(<>) {
        chomp;
        s/\s+/ /g;
@@ -100,20 +105,19 @@ while(<>) {
        }
 
        # System call pointer variable name.
-       my $sysvarname = "libc_$sysname";
+       my $sysvarname = "libc_${sysname}";
 
        my $strconvfunc = "BytePtrFromString";
        my $strconvtype = "*byte";
 
-       # Library proc address variable.
        $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
-       if($vars eq "") {
-               $vars .= "\t$sysvarname";
-       } else {
-               $vars .= ",\n\t$sysvarname";
-       }
-       $dynimports .= "//go:cgo_import_dynamic $sysvarname $sysname \"$modname.so\"\n";
-       $linknames .= "//go:linkname $sysvarname $sysvarname\n";
+
+       # Runtime import of function to allow cross-platform builds.
+       $dynimports .= "//go:cgo_import_dynamic ${sysvarname} ${sysname} \"$modname.so\"\n";
+       # Link symbol to proc address variable.
+       $linknames .= "//go:linkname ${sysvarname} ${sysvarname}\n";
+       # Library proc address variable.
+       push @vars, $sysvarname;
 
        # Go function header.
        $out = join(', ', @out);
@@ -264,6 +268,8 @@ print <<EOF;
 // $cmdline
 // MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
 
+// +build $ENV{'GOARCH'},$ENV{'GOOS'}
+
 package $package
 
 import "unsafe"
@@ -271,17 +277,20 @@ EOF
 
 print "import \"syscall\"\n" if $package ne "syscall";
 
-print <<EOF;
+my $vardecls = "\t" . join(",\n\t", @vars);
+$vardecls .= " libcFunc";
+
+chomp($_=<<EOF);
 
 $dynimports
 $linknames
 type libcFunc uintptr
 
 var (
-$vars libcFunc
+$vardecls
 )
 
 $text
-
 EOF
+print $_;
 exit 0;
index 0f60e2161868b2d6d0fc2755249baf264566da48..2f68760ed1518b9f9f6865f0068fd236af145a3e 100644 (file)
@@ -142,12 +142,23 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
        return anyToSockaddr(&rsa)
 }
 
-// The const provides a compile-time constant so clients
-// can adjust to whether there is a working Getwd and avoid
-// even linking this function into the binary.  See ../os/getwd.go.
-const ImplementsGetwd = false
+const ImplementsGetwd = true
 
-func Getwd() (string, error) { return "", ENOTSUP }
+//sys  Getcwd(buf []byte) (n int, err error)
+
+func Getwd() (wd string, err error) {
+       var buf [PathMax]byte
+       // Getcwd will return an error if it failed for any reason.
+       _, err = Getcwd(buf[0:])
+       if err != nil {
+               return "", err
+       }
+       n := clen(buf[:])
+       if n < 1 {
+               return "", EINVAL
+       }
+       return string(buf[:n]), nil
+}
 
 /*
  * Wrapped
index 53fa35068fc4fd0bb10ba3ab977d258cf8867fef..7246434223f0888ae0b3ccc3552f4bb873180fc6 100644 (file)
@@ -15,8 +15,14 @@ package syscall
 
 /*
 #define KERNEL
+// These defines ensure that builds done on newer versions of Solaris are
+// backwards-compatible with older versions of Solaris and
+// OpenSolaris-based derivatives.
+#define __USE_SUNOS_SOCKETS__          // msghdr
+#define __USE_LEGACY_PROTOTYPES__      // iovec
 #include <dirent.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <signal.h>
 #include <termios.h>
 #include <stdio.h>
@@ -69,6 +75,7 @@ const (
        sizeofInt      = C.sizeof_int
        sizeofLong     = C.sizeof_long
        sizeofLongLong = C.sizeof_longlong
+       PathMax        = C.PATH_MAX
 )
 
 // Basic types
index cabab7ece36046f28f62b08d6f5f42b11089c04f..ebdeb92bfb4ad2585f1f26d65ebb97f1b91e9845 100644 (file)
@@ -7,6 +7,7 @@ package syscall
 
 import "unsafe"
 
+//go:cgo_import_dynamic libc_Getcwd getcwd "libc.so"
 //go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
 //go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
 //go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
@@ -89,6 +90,7 @@ import "unsafe"
 //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so"
 //go:cgo_import_dynamic libc_recvmsg recvmsg "libsocket.so"
 
+//go:linkname libc_Getcwd libc_Getcwd
 //go:linkname libc_getgroups libc_getgroups
 //go:linkname libc_setgroups libc_setgroups
 //go:linkname libc_fcntl libc_fcntl
@@ -174,6 +176,7 @@ import "unsafe"
 type libcFunc uintptr
 
 var (
+       libc_Getcwd,
        libc_getgroups,
        libc_setgroups,
        libc_fcntl,
@@ -257,6 +260,19 @@ var (
        libc_recvmsg libcFunc
 )
 
+func Getcwd(buf []byte) (n int, err error) {
+       var _p0 *byte
+       if len(buf) > 0 {
+               _p0 = &buf[0]
+       }
+       r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_Getcwd)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0, 0, 0, 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
        r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&libc_getgroups)), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0)
        n = int(r0)
index 2471519aded6baec419ab7279a6cbb0c7fb65fa7..4cf07ed496d1e62cd19c5c91641eb8c8140adac6 100644 (file)
@@ -11,6 +11,7 @@ const (
        sizeofInt      = 0x4
        sizeofLong     = 0x8
        sizeofLongLong = 0x8
+       PathMax        = 0x400
 )
 
 type (