syscall: make sure go error numbers do not clash with windows system errors

R=rsc
CC=golang-dev
https://golang.org/cl/1857049
This commit is contained in:
Alex Brainman 2010-08-03 12:04:41 +10:00
parent 5443bbe292
commit a79a9098da
7 changed files with 457 additions and 143 deletions

View file

@ -154,7 +154,7 @@ windows_386)
mksyscall="./mksyscall_windows.sh -l32"
mksysnum=
mktypes=
mkerrors=
mkerrors="./mkerrors_windows.sh -f -m32"
;;
*)
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2

View file

@ -0,0 +1,165 @@
#!/usr/bin/env bash
# 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.
# Generate Go code listing errors and other #defined constant
# values (ENAMETOOLONG etc.), by asking the preprocessor
# about the definitions.
unset LANG
export LC_ALL=C
export LC_CTYPE=C
case "$GOARCH" in
arm)
GCC=arm-gcc
;;
*)
GCC=gcc
;;
esac
uname=$(uname)
includes_Linux='
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/epoll.h>
#include <linux/ptrace.h>
#include <linux/wait.h>
'
includes_Darwin='
#define __DARWIN_UNIX03 0
#define KERNEL
#define _DARWIN_USE_64_BIT_INODE
#include <sys/wait.h>
#include <sys/event.h>
'
includes_FreeBSD='
#include <sys/wait.h>
#include <sys/event.h>
'
includes='
#include <sys/types.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <errno.h>
#include <sys/signal.h>
#include <signal.h>
'
ccflags=""
next=false
for i
do
if $next; then
ccflags="$ccflags $i"
next=false
elif [ "$i" = "-f" ]; then
next=true
fi
done
# Pull out just the error names for later.
errors=$(
echo '#include <errno.h>' | $GCC -x c - -E -dM $ccflags |
awk '
$1 != "#define" || $2 ~ /\(/ {next}
$2 ~ /^ENOTDIR$/ {next}
$2 ~ /^E[A-Z0-9_]+$/ { print $2 }
{next}
' | sort
)
echo '// mkerrors_windows.sh' "$@"
echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
echo
echo 'package syscall'
# Run C program to print error strings.
(
/bin/echo "
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
struct {
char *name;
int value;
} errors[] = {
"
for i in $errors
do
/bin/echo ' {"'$i'",' $i'},'
done
# Use /bin/echo to avoid builtin echo,
# which interprets \n itself
/bin/echo '
};
int
main(void)
{
int i, j, e, iota = 1;
char buf[1024];
printf("\nconst (\n");
for(i=0; i<nelem(errors); i++) {
e = errors[i].value;
strcpy(buf, strerror(e));
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
buf[0] += a - A;
printf("\t%s", errors[i].name);
if(iota) {
printf(" = APPLICATION_ERROR + iota");
iota = !iota;
}
printf("\n");
}
printf("\tEWINDOWS\n");
printf(")\n");
printf("\n// Error table\n");
printf("var errors = [...]string {\n");
for(i=0; i<nelem(errors); i++) {
e = errors[i].value;
for(j=0; j<i; j++)
if(errors[j].value == e) // duplicate value
goto next;
strcpy(buf, strerror(e));
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
buf[0] += a - A;
printf("\t%s - APPLICATION_ERROR: \"%s\",\n", errors[i].name, buf);
next:;
}
printf("\tEWINDOWS - APPLICATION_ERROR: \"not supported by windows\",\n");
printf("}\n\n");
return 0;
}
'
) >_errors.c
$GCC $ccflags -static -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors

View file

@ -216,8 +216,10 @@ while(<>) {
$ret[$i] = sprintf("r%d", $i);
$ret[$i+1] = sprintf("r%d", $i+1);
}
my $rettype = $type;
if($type =~ /^\*/) {
$reg = "unsafe.Pointer($reg)";
$rettype = "($rettype)";
}
if($i == 0) {
if($type eq "bool") {
@ -241,7 +243,7 @@ while(<>) {
$body .= "\t\t$name = 0;\n";
$body .= "\t}\n";
} else {
$body .= "\t$name = ($type)($reg);\n";
$body .= "\t$name = $rettype($reg);\n";
}
push @pout, sprintf "\"%s=\", %s, ", $name, $name;
}

View file

@ -147,9 +147,12 @@ func getSysProcAddr(m uint32, pname string) uintptr {
// syscall interface implementation for other packages
func Errstr(errno int) string {
if errno == EWINDOWS {
return "not supported by windows"
// deal with special go errors
e := errno - APPLICATION_ERROR
if 0 <= e && e < len(errors) {
return errors[e]
}
// ask windows for the remaining errors
var flags uint32 = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS
b := make([]uint16, 300)
n, err := FormatMessage(flags, 0, uint32(errno), 0, b, nil)

View file

@ -1,144 +1,272 @@
// mkerrors_nacl.sh /home/rsc/pub/nacl/native_client/src/trusted/service_runtime/include/sys/errno.h
// mkerrors_windows.sh -f -m32
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package syscall
// TODO(brainman): populate errors in zerrors_windows.go
const (
ERROR_FILE_NOT_FOUND = 2
ERROR_NO_MORE_FILES = 18
ERROR_BROKEN_PIPE = 109
ERROR_INSUFFICIENT_BUFFER = 122
ERROR_MOD_NOT_FOUND = 126
ERROR_PROC_NOT_FOUND = 127
ERROR_DIRECTORY = 267
ERROR_IO_PENDING = 997
// TODO(brainman): should use value for EWINDOWS that does not clashes with anything else
EWINDOWS = 99999 /* otherwise unused */
E2BIG = APPLICATION_ERROR + iota
EACCES
EADDRINUSE
EADDRNOTAVAIL
EADV
EAFNOSUPPORT
EAGAIN
EALREADY
EBADE
EBADF
EBADFD
EBADMSG
EBADR
EBADRQC
EBADSLT
EBFONT
EBUSY
ECANCELED
ECHILD
ECHRNG
ECOMM
ECONNABORTED
ECONNREFUSED
ECONNRESET
EDEADLK
EDEADLOCK
EDESTADDRREQ
EDOM
EDOTDOT
EDQUOT
EEXIST
EFAULT
EFBIG
EHOSTDOWN
EHOSTUNREACH
EIDRM
EILSEQ
EINPROGRESS
EINTR
EINVAL
EIO
EISCONN
EISDIR
EISNAM
EKEYEXPIRED
EKEYREJECTED
EKEYREVOKED
EL2HLT
EL2NSYNC
EL3HLT
EL3RST
ELIBACC
ELIBBAD
ELIBEXEC
ELIBMAX
ELIBSCN
ELNRNG
ELOOP
EMEDIUMTYPE
EMFILE
EMLINK
EMSGSIZE
EMULTIHOP
ENAMETOOLONG
ENAVAIL
ENETDOWN
ENETRESET
ENETUNREACH
ENFILE
ENOANO
ENOBUFS
ENOCSI
ENODATA
ENODEV
ENOENT
ENOEXEC
ENOKEY
ENOLCK
ENOLINK
ENOMEDIUM
ENOMEM
ENOMSG
ENONET
ENOPKG
ENOPROTOOPT
ENOSPC
ENOSR
ENOSTR
ENOSYS
ENOTBLK
ENOTCONN
ENOTEMPTY
ENOTNAM
ENOTRECOVERABLE
ENOTSOCK
ENOTSUP
ENOTTY
ENOTUNIQ
ENXIO
EOPNOTSUPP
EOVERFLOW
EOWNERDEAD
EPERM
EPFNOSUPPORT
EPIPE
EPROTO
EPROTONOSUPPORT
EPROTOTYPE
ERANGE
EREMCHG
EREMOTE
EREMOTEIO
ERESTART
EROFS
ESHUTDOWN
ESOCKTNOSUPPORT
ESPIPE
ESRCH
ESRMNT
ESTALE
ESTRPIPE
ETIME
ETIMEDOUT
ETOOMANYREFS
ETXTBSY
EUCLEAN
EUNATCH
EUSERS
EWOULDBLOCK
EXDEV
EXFULL
EWINDOWS
)
// TODO(brainman): fix all needed for os
const (
EPERM = 1
ENOENT = 2
ESRCH = 3
EINTR = 4
EIO = 5
ENXIO = 6
E2BIG = 7
ENOEXEC = 8
EBADF = 9
ECHILD = 10
EAGAIN = 11
ENOMEM = 12
EACCES = 13
EFAULT = 14
EBUSY = 16
EEXIST = 17
EXDEV = 18
ENODEV = 19
ENOTDIR = ERROR_DIRECTORY
EISDIR = 21
EINVAL = 22
ENFILE = 23
EMFILE = 24
ENOTTY = 25
EFBIG = 27
ENOSPC = 28
ESPIPE = 29
EROFS = 30
EMLINK = 31
EPIPE = 32
ENAMETOOLONG = 36
ENOSYS = 38
EDQUOT = 122
EDOM = 33
ERANGE = 34
ENOMSG = 35
ECHRNG = 37
EL3HLT = 39
EL3RST = 40
ELNRNG = 41
EUNATCH = 42
ENOCSI = 43
EL2HLT = 44
EDEADLK = 45
ENOLCK = 46
EBADE = 50
EBADR = 51
EXFULL = 52
ENOANO = 53
EBADRQC = 54
EBADSLT = 55
EBFONT = 57
ENOSTR = 60
ENODATA = 61
ETIME = 62
ENOSR = 63
ENONET = 64
ENOPKG = 65
EREMOTE = 66
ENOLINK = 67
EADV = 68
ESRMNT = 69
ECOMM = 70
EPROTO = 71
EMULTIHOP = 74
ELBIN = 75
EDOTDOT = 76
EBADMSG = 77
EFTYPE = 79
ENOTUNIQ = 80
EBADFD = 81
EREMCHG = 82
ELIBACC = 83
ELIBBAD = 84
ELIBSCN = 85
ELIBMAX = 86
ELIBEXEC = 87
ENMFILE = 89
ENOTEMPTY = 90
ELOOP = 92
EOPNOTSUPP = 95
EPFNOSUPPORT = 96
ECONNRESET = 104
ENOBUFS = 105
EAFNOSUPPORT = 106
EPROTOTYPE = 107
ENOTSOCK = 108
ENOPROTOOPT = 109
ESHUTDOWN = 110
ECONNREFUSED = 111
EADDRINUSE = 112
ECONNABORTED = 113
ENETUNREACH = 114
ENETDOWN = 115
ETIMEDOUT = 116
EHOSTDOWN = 117
EHOSTUNREACH = 118
EINPROGRESS = 119
EALREADY = 120
EDESTADDRREQ = 121
EPROTONOSUPPORT = 123
ESOCKTNOSUPPORT = 124
EADDRNOTAVAIL = 125
ENETRESET = 126
EISCONN = 127
ENOTCONN = 128
ETOOMANYREFS = 129
EPROCLIM = 130
EUSERS = 131
EWOULDBLOCK = 141
ESTALE = 133
ENOMEDIUM = 135
ENOSHARE = 136
ECASECLASH = 137
EILSEQ = 138
EOVERFLOW = 139
ECANCELED = 140
EL2NSYNC = 88
EIDRM = 91
EMSGSIZE = 132
)
// Error table
var errors = [...]string{
E2BIG - APPLICATION_ERROR: "argument list too long",
EACCES - APPLICATION_ERROR: "permission denied",
EADDRINUSE - APPLICATION_ERROR: "address already in use",
EADDRNOTAVAIL - APPLICATION_ERROR: "cannot assign requested address",
EADV - APPLICATION_ERROR: "advertise error",
EAFNOSUPPORT - APPLICATION_ERROR: "address family not supported by protocol",
EAGAIN - APPLICATION_ERROR: "resource temporarily unavailable",
EALREADY - APPLICATION_ERROR: "operation already in progress",
EBADE - APPLICATION_ERROR: "invalid exchange",
EBADF - APPLICATION_ERROR: "bad file descriptor",
EBADFD - APPLICATION_ERROR: "file descriptor in bad state",
EBADMSG - APPLICATION_ERROR: "bad message",
EBADR - APPLICATION_ERROR: "invalid request descriptor",
EBADRQC - APPLICATION_ERROR: "invalid request code",
EBADSLT - APPLICATION_ERROR: "invalid slot",
EBFONT - APPLICATION_ERROR: "bad font file format",
EBUSY - APPLICATION_ERROR: "device or resource busy",
ECANCELED - APPLICATION_ERROR: "operation canceled",
ECHILD - APPLICATION_ERROR: "no child processes",
ECHRNG - APPLICATION_ERROR: "channel number out of range",
ECOMM - APPLICATION_ERROR: "communication error on send",
ECONNABORTED - APPLICATION_ERROR: "software caused connection abort",
ECONNREFUSED - APPLICATION_ERROR: "connection refused",
ECONNRESET - APPLICATION_ERROR: "connection reset by peer",
EDEADLK - APPLICATION_ERROR: "resource deadlock avoided",
EDESTADDRREQ - APPLICATION_ERROR: "destination address required",
EDOM - APPLICATION_ERROR: "numerical argument out of domain",
EDOTDOT - APPLICATION_ERROR: "RFS specific error",
EDQUOT - APPLICATION_ERROR: "disk quota exceeded",
EEXIST - APPLICATION_ERROR: "file exists",
EFAULT - APPLICATION_ERROR: "bad address",
EFBIG - APPLICATION_ERROR: "file too large",
EHOSTDOWN - APPLICATION_ERROR: "host is down",
EHOSTUNREACH - APPLICATION_ERROR: "no route to host",
EIDRM - APPLICATION_ERROR: "identifier removed",
EILSEQ - APPLICATION_ERROR: "invalid or incomplete multibyte or wide character",
EINPROGRESS - APPLICATION_ERROR: "operation now in progress",
EINTR - APPLICATION_ERROR: "interrupted system call",
EINVAL - APPLICATION_ERROR: "invalid argument",
EIO - APPLICATION_ERROR: "input/output error",
EISCONN - APPLICATION_ERROR: "transport endpoint is already connected",
EISDIR - APPLICATION_ERROR: "is a directory",
EISNAM - APPLICATION_ERROR: "is a named type file",
EKEYEXPIRED - APPLICATION_ERROR: "key has expired",
EKEYREJECTED - APPLICATION_ERROR: "key was rejected by service",
EKEYREVOKED - APPLICATION_ERROR: "key has been revoked",
EL2HLT - APPLICATION_ERROR: "level 2 halted",
EL2NSYNC - APPLICATION_ERROR: "level 2 not synchronized",
EL3HLT - APPLICATION_ERROR: "level 3 halted",
EL3RST - APPLICATION_ERROR: "level 3 reset",
ELIBACC - APPLICATION_ERROR: "can not access a needed shared library",
ELIBBAD - APPLICATION_ERROR: "accessing a corrupted shared library",
ELIBEXEC - APPLICATION_ERROR: "cannot exec a shared library directly",
ELIBMAX - APPLICATION_ERROR: "attempting to link in too many shared libraries",
ELIBSCN - APPLICATION_ERROR: ".lib section in a.out corrupted",
ELNRNG - APPLICATION_ERROR: "link number out of range",
ELOOP - APPLICATION_ERROR: "too many levels of symbolic links",
EMEDIUMTYPE - APPLICATION_ERROR: "wrong medium type",
EMFILE - APPLICATION_ERROR: "too many open files",
EMLINK - APPLICATION_ERROR: "too many links",
EMSGSIZE - APPLICATION_ERROR: "message too long",
EMULTIHOP - APPLICATION_ERROR: "multihop attempted",
ENAMETOOLONG - APPLICATION_ERROR: "file name too long",
ENAVAIL - APPLICATION_ERROR: "no XENIX semaphores available",
ENETDOWN - APPLICATION_ERROR: "network is down",
ENETRESET - APPLICATION_ERROR: "network dropped connection on reset",
ENETUNREACH - APPLICATION_ERROR: "network is unreachable",
ENFILE - APPLICATION_ERROR: "too many open files in system",
ENOANO - APPLICATION_ERROR: "no anode",
ENOBUFS - APPLICATION_ERROR: "no buffer space available",
ENOCSI - APPLICATION_ERROR: "no CSI structure available",
ENODATA - APPLICATION_ERROR: "no data available",
ENODEV - APPLICATION_ERROR: "no such device",
ENOENT - APPLICATION_ERROR: "no such file or directory",
ENOEXEC - APPLICATION_ERROR: "exec format error",
ENOKEY - APPLICATION_ERROR: "required key not available",
ENOLCK - APPLICATION_ERROR: "no locks available",
ENOLINK - APPLICATION_ERROR: "link has been severed",
ENOMEDIUM - APPLICATION_ERROR: "no medium found",
ENOMEM - APPLICATION_ERROR: "cannot allocate memory",
ENOMSG - APPLICATION_ERROR: "no message of desired type",
ENONET - APPLICATION_ERROR: "machine is not on the network",
ENOPKG - APPLICATION_ERROR: "package not installed",
ENOPROTOOPT - APPLICATION_ERROR: "protocol not available",
ENOSPC - APPLICATION_ERROR: "no space left on device",
ENOSR - APPLICATION_ERROR: "out of streams resources",
ENOSTR - APPLICATION_ERROR: "device not a stream",
ENOSYS - APPLICATION_ERROR: "function not implemented",
ENOTBLK - APPLICATION_ERROR: "block device required",
ENOTCONN - APPLICATION_ERROR: "transport endpoint is not connected",
ENOTEMPTY - APPLICATION_ERROR: "directory not empty",
ENOTNAM - APPLICATION_ERROR: "not a XENIX named type file",
ENOTRECOVERABLE - APPLICATION_ERROR: "state not recoverable",
ENOTSOCK - APPLICATION_ERROR: "socket operation on non-socket",
ENOTSUP - APPLICATION_ERROR: "operation not supported",
ENOTTY - APPLICATION_ERROR: "inappropriate ioctl for device",
ENOTUNIQ - APPLICATION_ERROR: "name not unique on network",
ENXIO - APPLICATION_ERROR: "no such device or address",
EOVERFLOW - APPLICATION_ERROR: "value too large for defined data type",
EOWNERDEAD - APPLICATION_ERROR: "owner died",
EPERM - APPLICATION_ERROR: "operation not permitted",
EPFNOSUPPORT - APPLICATION_ERROR: "protocol family not supported",
EPIPE - APPLICATION_ERROR: "broken pipe",
EPROTO - APPLICATION_ERROR: "protocol error",
EPROTONOSUPPORT - APPLICATION_ERROR: "protocol not supported",
EPROTOTYPE - APPLICATION_ERROR: "protocol wrong type for socket",
ERANGE - APPLICATION_ERROR: "numerical result out of range",
EREMCHG - APPLICATION_ERROR: "remote address changed",
EREMOTE - APPLICATION_ERROR: "object is remote",
EREMOTEIO - APPLICATION_ERROR: "remote I/O error",
ERESTART - APPLICATION_ERROR: "interrupted system call should be restarted",
EROFS - APPLICATION_ERROR: "read-only file system",
ESHUTDOWN - APPLICATION_ERROR: "cannot send after transport endpoint shutdown",
ESOCKTNOSUPPORT - APPLICATION_ERROR: "socket type not supported",
ESPIPE - APPLICATION_ERROR: "illegal seek",
ESRCH - APPLICATION_ERROR: "no such process",
ESRMNT - APPLICATION_ERROR: "srmount error",
ESTALE - APPLICATION_ERROR: "stale NFS file handle",
ESTRPIPE - APPLICATION_ERROR: "streams pipe error",
ETIME - APPLICATION_ERROR: "timer expired",
ETIMEDOUT - APPLICATION_ERROR: "connection timed out",
ETOOMANYREFS - APPLICATION_ERROR: "too many references: cannot splice",
ETXTBSY - APPLICATION_ERROR: "text file busy",
EUCLEAN - APPLICATION_ERROR: "structure needs cleaning",
EUNATCH - APPLICATION_ERROR: "protocol driver not attached",
EUSERS - APPLICATION_ERROR: "too many users",
EXDEV - APPLICATION_ERROR: "invalid cross-device link",
EXFULL - APPLICATION_ERROR: "exchange full",
EWINDOWS - APPLICATION_ERROR: "not supported by windows",
}

View file

@ -887,13 +887,13 @@ func GetServByName(name string, proto string) (s *Servent, errno int) {
func Ntohs(netshort uint16) (u uint16) {
r0, _, _ := Syscall(procntohs, uintptr(netshort), 0, 0)
u = (uint16)(r0)
u = uint16(r0)
return
}
func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status uint32) {
r0, _, _ := Syscall6(procDnsQuery_W, uintptr(unsafe.Pointer(StringToUTF16Ptr(name))), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
status = (uint32)(r0)
status = uint32(r0)
return
}

View file

@ -17,6 +17,22 @@ const (
SizeofCmsghdr = 0xc
)
const (
// Windows errors.
ERROR_FILE_NOT_FOUND = 2
ERROR_NO_MORE_FILES = 18
ERROR_BROKEN_PIPE = 109
ERROR_INSUFFICIENT_BUFFER = 122
ERROR_MOD_NOT_FOUND = 126
ERROR_PROC_NOT_FOUND = 127
ERROR_DIRECTORY = 267
ERROR_IO_PENDING = 997
// Go names for Windows errors.
ENOTDIR = ERROR_DIRECTORY
// Windows reserves errors >= 1<<29 for application use.
APPLICATION_ERROR = 1 << 29
)
const (
// Invented values to support what package os expects.
O_RDONLY = 0x00000