mirror of
https://github.com/golang/go
synced 2024-11-26 04:07:59 -07:00
syscall: more changes to mingw version
- mkall now generates syscall stabs automatically - we can call unicode versions of winapi now - introduce GetErrstr function to fetch error text given errno - general cleanup R=rsc CC=golang-dev https://golang.org/cl/562041
This commit is contained in:
parent
9d930040d7
commit
5e6203d28b
@ -6,6 +6,18 @@ package syscall
|
|||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
static uintptr
|
||||||
|
stdcallerr(uintptr *lasterr, uintptr trap, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6, uintptr a7, uintptr a8, uintptr a9)
|
||||||
|
{
|
||||||
|
uintptr r;
|
||||||
|
|
||||||
|
·entersyscall();
|
||||||
|
r = (uintptr)stdcall_raw((void*)trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||||
|
*lasterr = (uintptr)stdcall_raw(GetLastError);
|
||||||
|
·exitsyscall();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
func loadlibraryex(filename uintptr) (handle uint32) {
|
func loadlibraryex(filename uintptr) (handle uint32) {
|
||||||
handle = (uint32)stdcall(LoadLibraryEx, filename, 0, 0);
|
handle = (uint32)stdcall(LoadLibraryEx, filename, 0, 0);
|
||||||
}
|
}
|
||||||
@ -15,19 +27,18 @@ func getprocaddress(handle uint32, procname uintptr) (proc uintptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Syscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
|
func Syscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
|
||||||
·entersyscall();
|
r1 = stdcallerr(&err, trap, a1, a2, a3, 0, 0, 0, 0, 0, 0);
|
||||||
r1 = (uintptr)stdcall_raw((void*)trap, a1, a2, a3);
|
|
||||||
r2 = 0;
|
r2 = 0;
|
||||||
err = (uintptr)stdcall_raw(GetLastError);
|
|
||||||
·exitsyscall();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Syscall6(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
|
func Syscall6(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
|
||||||
·entersyscall();
|
r1 = stdcallerr(&err, trap, a1, a2, a3, a4, a5, a6, 0, 0, 0);
|
||||||
r1 = (uintptr)stdcall_raw((void*)trap, a1, a2, a3, a4, a5, a6);
|
r2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr) (r1 uintptr, r2 uintptr, lasterr uintptr) {
|
||||||
|
r1 = stdcallerr(&lasterr, trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||||
r2 = 0;
|
r2 = 0;
|
||||||
err = (uintptr)stdcall_raw(GetLastError);
|
|
||||||
·exitsyscall();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RawSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
|
func RawSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
|
||||||
|
@ -145,11 +145,10 @@ linux_arm)
|
|||||||
mkerrors="mkerrors.sh"
|
mkerrors="mkerrors.sh"
|
||||||
;;
|
;;
|
||||||
mingw_386)
|
mingw_386)
|
||||||
# TODO(brainman): create proper mksyscall / mksysnum / mktypes
|
mksyscall="mksyscall_mingw.sh -l32"
|
||||||
mksyscall="mksyscall.sh -l32"
|
mksysnum=
|
||||||
mksysnum="XXXXXX_mksysnum.sh"
|
mktypes=
|
||||||
mktypes="XXXXXX_godefs -gsyscall -f-m32"
|
mkerrors=
|
||||||
exit 1
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
||||||
@ -158,8 +157,8 @@ mingw_386)
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
(
|
(
|
||||||
echo "$mkerrors |gofmt >zerrors_$GOOSARCH.go"
|
if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >zerrors_$GOOSARCH.go"; fi
|
||||||
echo "$mksyscall syscall_$GOOS.go syscall_$GOOSARCH.go |gofmt >zsyscall_$GOOSARCH.go"
|
if [ -n "$mksyscall" ]; then echo "$mksyscall syscall_$GOOS.go syscall_$GOOSARCH.go |gofmt >zsyscall_$GOOSARCH.go"; fi
|
||||||
echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"
|
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
|
||||||
echo "$mktypes types_$GOOS.c |gofmt >ztypes_$GOOSARCH.go"
|
if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.c |gofmt >ztypes_$GOOSARCH.go"; fi
|
||||||
) | $run
|
) | $run
|
||||||
|
226
src/pkg/syscall/mksyscall_mingw.sh
Executable file
226
src/pkg/syscall/mksyscall_mingw.sh
Executable file
@ -0,0 +1,226 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# This program reads a file containing function prototypes
|
||||||
|
# (like syscall_darwin.go) and generates system call bodies.
|
||||||
|
# The prototypes are marked by lines beginning with "//sys"
|
||||||
|
# and read like func declarations if //sys is replaced by func, but:
|
||||||
|
# * The parameter lists must give a name for each argument.
|
||||||
|
# This includes return parameters.
|
||||||
|
# * The parameter lists must give a type for each argument:
|
||||||
|
# the (x, y, z int) shorthand is not allowed.
|
||||||
|
# * If the return parameter is an error number, it must be named errno.
|
||||||
|
# * If go func name needs to be different from it's winapi dll name,
|
||||||
|
# the winapi name could be specified at the end, after "=" sign, like
|
||||||
|
# //sys LoadLibrary(libname string) (handle uint32, errno int) = LoadLibraryA
|
||||||
|
# * Each function, that returns errno, needs to supply a number,
|
||||||
|
# that return value of winapi will be tested against to
|
||||||
|
# detect failure. This would set errno to windows "last-error",
|
||||||
|
# otherwise it will be 0. The value can be provided at
|
||||||
|
# the very end of //sys declaration, like
|
||||||
|
# //sys LoadLibrary(libname string) (handle uint32, errno int) = LoadLibraryA, 0xffffffff
|
||||||
|
# and is 0 by default.
|
||||||
|
|
||||||
|
$cmdline = "mksyscall_mingw.sh " . join(' ', @ARGV);
|
||||||
|
$errors = 0;
|
||||||
|
$_32bit = "";
|
||||||
|
|
||||||
|
if($ARGV[0] eq "-b32") {
|
||||||
|
$_32bit = "big-endian";
|
||||||
|
shift;
|
||||||
|
} elsif($ARGV[0] eq "-l32") {
|
||||||
|
$_32bit = "little-endian";
|
||||||
|
shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($ARGV[0] =~ /^-/) {
|
||||||
|
print STDERR "usage: mksyscall_mingw.sh [-b32 | -l32] [file ...]\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub parseparamlist($) {
|
||||||
|
my ($list) = @_;
|
||||||
|
$list =~ s/^\s*//;
|
||||||
|
$list =~ s/\s*$//;
|
||||||
|
if($list eq "") {
|
||||||
|
return ();
|
||||||
|
}
|
||||||
|
return split(/\s*,\s*/, $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub parseparam($) {
|
||||||
|
my ($p) = @_;
|
||||||
|
if($p !~ /^(\S*) (\S*)$/) {
|
||||||
|
print STDERR "$ARGV:$.: malformed parameter: $p\n";
|
||||||
|
$errors = 1;
|
||||||
|
return ("xx", "int");
|
||||||
|
}
|
||||||
|
return ($1, $2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$text = "";
|
||||||
|
$vars = "";
|
||||||
|
while(<>) {
|
||||||
|
chomp;
|
||||||
|
s/\s+/ /g;
|
||||||
|
s/^\s+//;
|
||||||
|
s/\s+$//;
|
||||||
|
next if !/^\/\/sys /;
|
||||||
|
|
||||||
|
# Line must be of the form
|
||||||
|
# func Open(path string, mode int, perm int) (fd int, errno int)
|
||||||
|
# Split into name, in params, out params.
|
||||||
|
if(!/^\/\/sys (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(\w*))?(?:\s*,\s*(\w+))?$/) {
|
||||||
|
print STDERR "$ARGV:$.: malformed //sys declaration\n";
|
||||||
|
$errors = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
my ($func, $in, $out, $sysname, $failretval) = ($1, $2, $3, $4, $5);
|
||||||
|
|
||||||
|
# Split argument lists on comma.
|
||||||
|
my @in = parseparamlist($in);
|
||||||
|
my @out = parseparamlist($out);
|
||||||
|
|
||||||
|
# System call name.
|
||||||
|
if($sysname eq "") {
|
||||||
|
$sysname = "$func";
|
||||||
|
}
|
||||||
|
|
||||||
|
# System call pointer variable name.
|
||||||
|
$sysvarname = "proc$sysname";
|
||||||
|
|
||||||
|
# Returned value when failed
|
||||||
|
if($failretval eq "") {
|
||||||
|
$failretval = "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Decide which version of api is used: ascii or unicode.
|
||||||
|
if($sysname !~ /W$/) {
|
||||||
|
$strconvfunc = "StringBytePtr";
|
||||||
|
} else {
|
||||||
|
$strconvfunc = "StringToUTF16Ptr";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Winapi proc address variable.
|
||||||
|
$vars .= sprintf "\t%s = getSysProcAddr(modKERNEL32, \"%s\")\n", $sysvarname, $sysname;
|
||||||
|
|
||||||
|
# Go function header.
|
||||||
|
$text .= sprintf "func %s(%s) (%s) {\n", $func, join(', ', @in), join(', ', @out);
|
||||||
|
|
||||||
|
# Prepare arguments to Syscall9.
|
||||||
|
my @args = ();
|
||||||
|
my $n = 0;
|
||||||
|
foreach my $p (@in) {
|
||||||
|
my ($name, $type) = parseparam($p);
|
||||||
|
if($type =~ /^\*/) {
|
||||||
|
push @args, "uintptr(unsafe.Pointer($name))";
|
||||||
|
} elsif($type eq "string") {
|
||||||
|
push @args, "uintptr(unsafe.Pointer($strconvfunc($name)))";
|
||||||
|
} elsif($type =~ /^\[\](.*)/) {
|
||||||
|
# Convert slice into pointer, length.
|
||||||
|
# Have to be careful not to take address of &a[0] if len == 0:
|
||||||
|
# pass nil in that case.
|
||||||
|
$text .= "\tvar _p$n *$1;\n";
|
||||||
|
$text .= "\tif len($name) > 0 { _p$n = \&${name}[0]; }\n";
|
||||||
|
push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
|
||||||
|
$n++;
|
||||||
|
} elsif($type eq "int64" && $_32bit ne "") {
|
||||||
|
if($_32bit eq "big-endian") {
|
||||||
|
push @args, "uintptr($name >> 32)", "uintptr($name)";
|
||||||
|
} else {
|
||||||
|
push @args, "uintptr($name)", "uintptr($name >> 32)";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
push @args, "uintptr($name)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine which form to use; pad args with zeros.
|
||||||
|
my $asm = "Syscall9";
|
||||||
|
if(@args <= 9) {
|
||||||
|
while(@args < 9) {
|
||||||
|
push @args, "0";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print STDERR "$ARGV:$.: too many arguments to system call\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Actual call.
|
||||||
|
my $args = join(', ', @args);
|
||||||
|
my $call = "$asm($sysvarname, $args)";
|
||||||
|
|
||||||
|
# Assign return values.
|
||||||
|
my $body = "";
|
||||||
|
my @ret = ("_", "_", "_");
|
||||||
|
for(my $i=0; $i<@out; $i++) {
|
||||||
|
my $p = $out[$i];
|
||||||
|
my ($name, $type) = parseparam($p);
|
||||||
|
my $reg = "";
|
||||||
|
if($name eq "errno") {
|
||||||
|
$reg = "e1";
|
||||||
|
$ret[2] = $reg;
|
||||||
|
} else {
|
||||||
|
$reg = sprintf("r%d", $i);
|
||||||
|
$ret[$i] = $reg;
|
||||||
|
}
|
||||||
|
if($type eq "bool") {
|
||||||
|
$reg = "$reg != 0";
|
||||||
|
}
|
||||||
|
if($type eq "int64" && $_32bit ne "") {
|
||||||
|
# 64-bit number in r1:r0 or r0:r1.
|
||||||
|
if($i+2 > @out) {
|
||||||
|
print STDERR "$ARGV:$.: not enough registers for int64 return\n";
|
||||||
|
}
|
||||||
|
if($_32bit eq "big-endian") {
|
||||||
|
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
|
||||||
|
} else {
|
||||||
|
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
|
||||||
|
}
|
||||||
|
$ret[$i] = sprintf("r%d", $i);
|
||||||
|
$ret[$i+1] = sprintf("r%d", $i+1);
|
||||||
|
}
|
||||||
|
if($name eq "errno") {
|
||||||
|
# Set errno to "last error" only if returned value indicate failure
|
||||||
|
$body .= "\tif uint32(r0) == $failretval {\n";
|
||||||
|
$body .= "\t\t$name = $type($reg);\n";
|
||||||
|
$body .= "\t} else {\n";
|
||||||
|
$body .= "\t\t$name = 0;\n";
|
||||||
|
$body .= "\t}\n";
|
||||||
|
} else {
|
||||||
|
$body .= "\t$name = $type($reg);\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
|
||||||
|
$text .= "\t$call;\n";
|
||||||
|
} else {
|
||||||
|
$text .= "\t$ret[0], $ret[1], $ret[2] := $call;\n";
|
||||||
|
}
|
||||||
|
$text .= $body;
|
||||||
|
|
||||||
|
$text .= "\treturn;\n";
|
||||||
|
$text .= "}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($errors) {
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
print <<EOF;
|
||||||
|
// $cmdline
|
||||||
|
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
var (
|
||||||
|
modKERNEL32 = loadDll("kernel32.dll")
|
||||||
|
$vars
|
||||||
|
)
|
||||||
|
|
||||||
|
$text
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 0;
|
@ -6,7 +6,10 @@
|
|||||||
|
|
||||||
package syscall
|
package syscall
|
||||||
|
|
||||||
import "unsafe"
|
import (
|
||||||
|
"unsafe"
|
||||||
|
"utf16"
|
||||||
|
)
|
||||||
|
|
||||||
const OS = "mingw"
|
const OS = "mingw"
|
||||||
|
|
||||||
@ -20,6 +23,10 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func abort(funcname string, err int) {
|
||||||
|
panic(funcname+" failed: (", err, ") ", syscall.GetErrstr(err), "\n")
|
||||||
|
}
|
||||||
|
|
||||||
func print_version(v uint32) {
|
func print_version(v uint32) {
|
||||||
major := byte(v)
|
major := byte(v)
|
||||||
minor := uint8(v >> 8)
|
minor := uint8(v >> 8)
|
||||||
@ -30,69 +37,90 @@ func print_version(v uint32) {
|
|||||||
func main() {
|
func main() {
|
||||||
h, err := syscall.LoadLibrary("kernel32.dll")
|
h, err := syscall.LoadLibrary("kernel32.dll")
|
||||||
if err != 0 {
|
if err != 0 {
|
||||||
panic("failed to LoadLibrary #", err, "\n")
|
abort("LoadLibrary", err)
|
||||||
}
|
}
|
||||||
defer syscall.FreeLibrary(h)
|
defer syscall.FreeLibrary(h)
|
||||||
proc, err := syscall.GetProcAddress(h, "GetVersion")
|
proc, err := syscall.GetProcAddress(h, "GetVersion")
|
||||||
if err != 0 {
|
if err != 0 {
|
||||||
panic("could not GetProcAddress #", err, "\n")
|
abort("GetProcAddress", err)
|
||||||
}
|
|
||||||
r, _, e := syscall.Syscall(uintptr(proc), 0, 0, 0)
|
|
||||||
err = int(e)
|
|
||||||
if err != 0 {
|
|
||||||
panic("GetVersion failed #", err, "\n")
|
|
||||||
}
|
}
|
||||||
|
r, _, _ := syscall.Syscall(uintptr(proc), 0, 0, 0)
|
||||||
print_version(uint32(r))
|
print_version(uint32(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//sys GetLastError() (lasterrno int)
|
// StringToUTF16 returns the UTF-16 encoding of the UTF-8 string s,
|
||||||
|
// with a terminating NUL added.
|
||||||
|
func StringToUTF16(s string) []uint16 { return utf16.Encode([]int(s + "\x00")) }
|
||||||
|
|
||||||
// TODO(brainman): probably should use LoadLibraryW here instead
|
// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
|
||||||
//sys LoadLibraryA(libname string) (handle Module, errno int)
|
// with a terminating NUL removed.
|
||||||
|
func UTF16ToString(s []uint16) string {
|
||||||
func LoadLibrary(libname string) (handle Module, errno int) {
|
if n := len(s); n > 0 && s[n-1] == 0 {
|
||||||
h, e := LoadLibraryA(libname)
|
s = s[0 : n-1]
|
||||||
if int(h) != 0 {
|
|
||||||
return h, 0
|
|
||||||
}
|
}
|
||||||
return h, e
|
return string(utf16.Decode(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(brainman): should handle errors like in LoadLibrary, otherwise will be returning 'old' errors
|
// StringToUTF16Ptr returns pointer to the UTF-16 encoding of
|
||||||
//sys FreeLibrary(handle Module) (ok Bool, errno int)
|
// the UTF-8 string s, with a terminating NUL added.
|
||||||
//sys GetProcAddress(module Module, procname string) (proc uint32, errno int)
|
func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
|
||||||
//sys GetVersion() (ver uint32, errno int)
|
|
||||||
|
|
||||||
// dll helpers
|
// dll helpers
|
||||||
|
|
||||||
// implemented in ../pkg/runtime/mingw/syscall.cgo
|
// implemented in ../pkg/runtime/mingw/syscall.cgo
|
||||||
|
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, lasterr uintptr)
|
||||||
func loadlibraryex(filename uintptr) (handle uint32)
|
func loadlibraryex(filename uintptr) (handle uint32)
|
||||||
func getprocaddress(handle uint32, procname uintptr) (proc uintptr)
|
func getprocaddress(handle uint32, procname uintptr) (proc uintptr)
|
||||||
|
|
||||||
func loadDll(fname string) Module {
|
func loadDll(fname string) uint32 {
|
||||||
m := loadlibraryex(uintptr(unsafe.Pointer(StringBytePtr(fname))))
|
m := loadlibraryex(uintptr(unsafe.Pointer(StringBytePtr(fname))))
|
||||||
if m == 0 {
|
if m == 0 {
|
||||||
panic("syscall: could not LoadLibraryEx ", fname)
|
panic("syscall: could not LoadLibraryEx ", fname)
|
||||||
}
|
}
|
||||||
return Module(m)
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSysProcAddr(m Module, pname string) uintptr {
|
func getSysProcAddr(m uint32, pname string) uintptr {
|
||||||
p := getprocaddress(uint32(m), uintptr(unsafe.Pointer(StringBytePtr(pname))))
|
p := getprocaddress(m, uintptr(unsafe.Pointer(StringBytePtr(pname))))
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
panic("syscall: could not GetProcAddress for ", pname)
|
panic("syscall: could not GetProcAddress for ", pname)
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// windows api calls
|
||||||
|
|
||||||
|
//sys GetLastError() (lasterrno int)
|
||||||
|
//sys LoadLibrary(libname string) (handle uint32, errno int) = LoadLibraryW
|
||||||
|
//sys FreeLibrary(handle uint32) (ok bool, errno int)
|
||||||
|
//sys GetProcAddress(module uint32, procname string) (proc uint32, errno int)
|
||||||
|
//sys GetVersion() (ver uint32, errno int)
|
||||||
|
//sys FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, errno int) = FormatMessageW
|
||||||
|
|
||||||
|
// TODO(brainman): maybe GetErrstr should replace Errstr alltogether
|
||||||
|
|
||||||
|
func GetErrstr(errno int) string {
|
||||||
|
if errno == EMINGW {
|
||||||
|
return errors[errno]
|
||||||
|
}
|
||||||
|
var b = make([]uint16, 300)
|
||||||
|
n, err := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ARGUMENT_ARRAY, 0, uint32(errno), 0, b, nil)
|
||||||
|
if err != 0 {
|
||||||
|
return "error " + str(errno) + " (FormatMessage failed with err=" + str(err) + ")"
|
||||||
|
}
|
||||||
|
return UTF16ToString(b[0 : n-1])
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(brainman): fix all this meaningless code, it is here to compile exec.go
|
// TODO(brainman): fix all this meaningless code, it is here to compile exec.go
|
||||||
|
|
||||||
func Pipe(p []int) (errno int) { return EMINGW }
|
func Pipe(p []int) (errno int) { return EMINGW }
|
||||||
|
|
||||||
//sys Close(fd int) (errno int)
|
func Close(fd int) (errno int) { return EMINGW }
|
||||||
//sys read(fd int, buf *byte, nbuf int) (n int, errno int)
|
func read(fd int, buf *byte, nbuf int) (n int, errno int) {
|
||||||
|
return 0, EMINGW
|
||||||
|
}
|
||||||
|
|
||||||
func fcntl(fd, cmd, arg int) (val int, errno int) {
|
func fcntl(fd, cmd, arg int) (val int, errno int) {
|
||||||
return 0, EMINGW
|
return 0, EMINGW
|
||||||
|
@ -6,7 +6,11 @@ package syscall
|
|||||||
// TODO(brainman): populate errors in zerrors_mingw.go
|
// TODO(brainman): populate errors in zerrors_mingw.go
|
||||||
|
|
||||||
const (
|
const (
|
||||||
EMINGW = 99 /* otherwise unused */
|
ERROR_INSUFFICIENT_BUFFER = 122
|
||||||
|
ERROR_MOD_NOT_FOUND = 126
|
||||||
|
ERROR_PROC_NOT_FOUND = 127
|
||||||
|
// TODO(brainman): should use value for EMINGW that does not clashes with anything else
|
||||||
|
EMINGW = 99999 /* otherwise unused */
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error table
|
// Error table
|
||||||
|
@ -1,53 +1,81 @@
|
|||||||
// mksyscall.sh -l32 syscall_mingw.go
|
// mksyscall_mingw.sh -l32 syscall_mingw.go syscall_mingw_386.go
|
||||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
|
|
||||||
package syscall
|
package syscall
|
||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
|
var (
|
||||||
|
modKERNEL32 = loadDll("kernel32.dll")
|
||||||
|
procGetLastError = getSysProcAddr(modKERNEL32, "GetLastError")
|
||||||
|
procLoadLibraryW = getSysProcAddr(modKERNEL32, "LoadLibraryW")
|
||||||
|
procFreeLibrary = getSysProcAddr(modKERNEL32, "FreeLibrary")
|
||||||
|
procGetProcAddress = getSysProcAddr(modKERNEL32, "GetProcAddress")
|
||||||
|
procGetVersion = getSysProcAddr(modKERNEL32, "GetVersion")
|
||||||
|
procFormatMessageW = getSysProcAddr(modKERNEL32, "FormatMessageW")
|
||||||
|
)
|
||||||
|
|
||||||
func GetLastError() (lasterrno int) {
|
func GetLastError() (lasterrno int) {
|
||||||
r0, _, _ := Syscall(SYS_GET_LAST_ERROR, 0, 0, 0)
|
r0, _, _ := Syscall9(procGetLastError, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||||
lasterrno = int(r0)
|
lasterrno = int(r0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadLibraryA(libname string) (handle Module, errno int) {
|
func LoadLibrary(libname string) (handle uint32, errno int) {
|
||||||
r0, _, e1 := Syscall(SYS_LOAD_LIBRARY_A, uintptr(unsafe.Pointer(StringBytePtr(libname))), 0, 0)
|
r0, _, e1 := Syscall9(procLoadLibraryW, uintptr(unsafe.Pointer(StringToUTF16Ptr(libname))), 0, 0, 0, 0, 0, 0, 0, 0)
|
||||||
handle = Module(r0)
|
handle = uint32(r0)
|
||||||
errno = int(e1)
|
if uint32(r0) == 0 {
|
||||||
|
errno = int(e1)
|
||||||
|
} else {
|
||||||
|
errno = 0
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func FreeLibrary(handle Module) (ok Bool, errno int) {
|
func FreeLibrary(handle uint32) (ok bool, errno int) {
|
||||||
r0, _, e1 := Syscall(SYS_FREE_LIBRARY, uintptr(handle), 0, 0)
|
r0, _, e1 := Syscall9(procFreeLibrary, uintptr(handle), 0, 0, 0, 0, 0, 0, 0, 0)
|
||||||
ok = Bool(r0)
|
ok = bool(r0 != 0)
|
||||||
errno = int(e1)
|
if uint32(r0) == 0 {
|
||||||
|
errno = int(e1)
|
||||||
|
} else {
|
||||||
|
errno = 0
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProcAddress(module Module, procname string) (proc uint32, errno int) {
|
func GetProcAddress(module uint32, procname string) (proc uint32, errno int) {
|
||||||
r0, _, e1 := Syscall(SYS_GET_PROC_ADDRESS, uintptr(module), uintptr(unsafe.Pointer(StringBytePtr(procname))), 0)
|
r0, _, e1 := Syscall9(procGetProcAddress, uintptr(module), uintptr(unsafe.Pointer(StringBytePtr(procname))), 0, 0, 0, 0, 0, 0, 0)
|
||||||
proc = uint32(r0)
|
proc = uint32(r0)
|
||||||
errno = int(e1)
|
if uint32(r0) == 0 {
|
||||||
|
errno = int(e1)
|
||||||
|
} else {
|
||||||
|
errno = 0
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetVersion() (ver uint32, errno int) {
|
func GetVersion() (ver uint32, errno int) {
|
||||||
r0, _, e1 := Syscall(SYS_GET_VERSION, 0, 0, 0)
|
r0, _, e1 := Syscall9(procGetVersion, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||||
ver = uint32(r0)
|
ver = uint32(r0)
|
||||||
errno = int(e1)
|
if uint32(r0) == 0 {
|
||||||
|
errno = int(e1)
|
||||||
|
} else {
|
||||||
|
errno = 0
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func Close(fd int) (errno int) {
|
func FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, errno int) {
|
||||||
_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
|
var _p0 *uint16
|
||||||
errno = int(e1)
|
if len(buf) > 0 {
|
||||||
return
|
_p0 = &buf[0]
|
||||||
}
|
}
|
||||||
|
r0, _, e1 := Syscall9(procFormatMessageW, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0)
|
||||||
func read(fd int, buf *byte, nbuf int) (n int, errno int) {
|
n = uint32(r0)
|
||||||
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
|
if uint32(r0) == 0 {
|
||||||
n = int(r0)
|
errno = int(e1)
|
||||||
errno = int(e1)
|
} else {
|
||||||
|
errno = 0
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,3 @@
|
|||||||
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
||||||
|
|
||||||
package syscall
|
package syscall
|
||||||
|
|
||||||
// TODO(brainman): autogenerate winapi proc pointers in zsysnum_mingw.go
|
|
||||||
|
|
||||||
var (
|
|
||||||
SYS_KERNEL32 = loadDll("kernel32.dll")
|
|
||||||
SYS_GET_LAST_ERROR = getSysProcAddr(SYS_KERNEL32, "GetLastError")
|
|
||||||
SYS_LOAD_LIBRARY_A = getSysProcAddr(SYS_KERNEL32, "LoadLibraryA")
|
|
||||||
SYS_FREE_LIBRARY = getSysProcAddr(SYS_KERNEL32, "FreeLibrary")
|
|
||||||
SYS_GET_PROC_ADDRESS = getSysProcAddr(SYS_KERNEL32, "GetProcAddress")
|
|
||||||
SYS_GET_VERSION = getSysProcAddr(SYS_KERNEL32, "GetVersion")
|
|
||||||
)
|
|
||||||
|
@ -25,6 +25,16 @@ const (
|
|||||||
SizeofCmsghdr = 0xc
|
SizeofCmsghdr = 0xc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER = 256
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS = 512
|
||||||
|
FORMAT_MESSAGE_FROM_STRING = 1024
|
||||||
|
FORMAT_MESSAGE_FROM_HMODULE = 2048
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM = 4096
|
||||||
|
FORMAT_MESSAGE_ARGUMENT_ARRAY = 8192
|
||||||
|
FORMAT_MESSAGE_MAX_WIDTH_MASK = 255
|
||||||
|
)
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
|
||||||
type _C_short int16
|
type _C_short int16
|
||||||
@ -35,9 +45,6 @@ type _C_long int32
|
|||||||
|
|
||||||
type _C_long_long int64
|
type _C_long_long int64
|
||||||
|
|
||||||
type Bool uint32
|
|
||||||
type Module uint32
|
|
||||||
|
|
||||||
type Timeval struct {
|
type Timeval struct {
|
||||||
Sec int32
|
Sec int32
|
||||||
Usec int32
|
Usec int32
|
||||||
|
Loading…
Reference in New Issue
Block a user