1
0
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:
Alex Brainman 2010-03-16 23:10:07 -07:00 committed by Russ Cox
parent 9d930040d7
commit 5e6203d28b
8 changed files with 376 additions and 84 deletions

View File

@ -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) {

View File

@ -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

View 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;

View File

@ -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

View File

@ -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

View File

@ -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
} }

View File

@ -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")
)

View File

@ -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