Commit af7c9a42 authored by Shawn Walker-Salas's avatar Shawn Walker-Salas Committed by Aram Hăvărneanu

syscall: implement getwd on Solaris

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/14420Reviewed-by: 's avatarAram Hăvărneanu <aram@mgk.ro>
parent cf3134a0
......@@ -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>
......
......@@ -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;
......@@ -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
......
......@@ -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
......
......@@ -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)
......
......@@ -11,6 +11,7 @@ const (
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
PathMax = 0x400
)
type (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment