diff options
| author | Joshua M. Clulow <jmc@joyent.com> | 2015-03-05 10:35:32 -0800 |
|---|---|---|
| committer | Joshua M. Clulow <jmc@joyent.com> | 2015-03-06 07:33:59 +0000 |
| commit | a903d81a6a1064d056ff85dd0ff490cc2687755e (patch) | |
| tree | 11893b919e7fe49475e1f175c806e9e47777f173 /usr/src | |
| parent | f50b0b2da0a5a431d4c2e027843710e4f8f2853b (diff) | |
| download | illumos-joyent-a903d81a6a1064d056ff85dd0ff490cc2687755e.tar.gz | |
OS-3892 lxbrand mispronounces ENOLCK and ENOSTR
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/common/brand/lx/lx_errno.c | 206 | ||||
| -rw-r--r-- | usr/src/common/brand/lx/lx_errno.h | 29 | ||||
| -rw-r--r-- | usr/src/common/brand/lx/lx_signum.c | 10 | ||||
| -rw-r--r-- | usr/src/common/brand/lx/tools/Makefile | 42 | ||||
| -rw-r--r-- | usr/src/common/brand/lx/tools/README.md | 39 | ||||
| -rw-r--r-- | usr/src/common/brand/lx/tools/gen_errno.c | 450 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/Makefile.com | 3 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/lx_brand.c | 16 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/signal.c | 2 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/socket.c | 2 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h | 3 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_syscall.c | 15 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_brand.h | 27 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_wait.c | 5 | ||||
| -rw-r--r-- | usr/src/uts/intel/Makefile.files | 1 | ||||
| -rw-r--r-- | usr/src/uts/intel/brand/lx/lx_archdep.c | 3 |
16 files changed, 782 insertions, 71 deletions
diff --git a/usr/src/common/brand/lx/lx_errno.c b/usr/src/common/brand/lx/lx_errno.c new file mode 100644 index 0000000000..269ed470dc --- /dev/null +++ b/usr/src/common/brand/lx/lx_errno.c @@ -0,0 +1,206 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Joyent, Inc. + */ + +/* + * This file contains a mapping table and lookup function for converting + * illumos native error numbers into error numbers appropriate for Linux + * emulation. + * + * The translation table is generated by the "gen_errno", built from and + * documented in "usr/src/common/brand/lx/tools". + */ + +#include <sys/debug.h> + +const int +lx_stol_errno[] = { + 0, /* 0: No Error */ + 1, /* 1: EPERM --> 1: EPERM */ + 2, /* 2: ENOENT --> 2: ENOENT */ + 3, /* 3: ESRCH --> 3: ESRCH */ + 4, /* 4: EINTR --> 4: EINTR */ + 5, /* 5: EIO --> 5: EIO */ + 6, /* 6: ENXIO --> 6: ENXIO */ + 7, /* 7: E2BIG --> 7: E2BIG */ + 8, /* 8: ENOEXEC --> 8: ENOEXEC */ + 9, /* 9: EBADF --> 9: EBADF */ + 10, /* 10: ECHILD --> 10: ECHILD */ + 11, /* 11: EAGAIN --> 11: EAGAIN */ + 12, /* 12: ENOMEM --> 12: ENOMEM */ + 13, /* 13: EACCES --> 13: EACCES */ + 14, /* 14: EFAULT --> 14: EFAULT */ + 15, /* 15: ENOTBLK --> 15: ENOTBLK */ + 16, /* 16: EBUSY --> 16: EBUSY */ + 17, /* 17: EEXIST --> 17: EEXIST */ + 18, /* 18: EXDEV --> 18: EXDEV */ + 19, /* 19: ENODEV --> 19: ENODEV */ + 20, /* 20: ENOTDIR --> 20: ENOTDIR */ + 21, /* 21: EISDIR --> 21: EISDIR */ + 22, /* 22: EINVAL --> 22: EINVAL */ + 23, /* 23: ENFILE --> 23: ENFILE */ + 24, /* 24: EMFILE --> 24: EMFILE */ + 25, /* 25: ENOTTY --> 25: ENOTTY */ + 26, /* 26: ETXTBSY --> 26: ETXTBSY */ + 27, /* 27: EFBIG --> 27: EFBIG */ + 28, /* 28: ENOSPC --> 28: ENOSPC */ + 29, /* 29: ESPIPE --> 29: ESPIPE */ + 30, /* 30: EROFS --> 30: EROFS */ + 31, /* 31: EMLINK --> 31: EMLINK */ + 32, /* 32: EPIPE --> 32: EPIPE */ + 33, /* 33: EDOM --> 33: EDOM */ + 34, /* 34: ERANGE --> 34: ERANGE */ + 42, /* 35: ENOMSG --> 42: ENOMSG */ + 43, /* 36: EIDRM --> 43: EIDRM */ + 44, /* 37: ECHRNG --> 44: ECHRNG */ + 45, /* 38: EL2NSYNC --> 45: EL2NSYNC */ + 46, /* 39: EL3HLT --> 46: EL3HLT */ + 47, /* 40: EL3RST --> 47: EL3RST */ + 48, /* 41: ELNRNG --> 48: ELNRNG */ + 49, /* 42: EUNATCH --> 49: EUNATCH */ + 50, /* 43: ENOCSI --> 50: ENOCSI */ + 51, /* 44: EL2HLT --> 51: EL2HLT */ + 35, /* 45: EDEADLK --> 35: EDEADLK */ + 37, /* 46: ENOLCK --> 37: ENOLCK */ + 125, /* 47: ECANCELED --> 125: ECANCELED */ + 38, /* 48: ENOTSUP --> 38: ENOSYS */ + 122, /* 49: EDQUOT --> 122: EDQUOT */ + 52, /* 50: EBADE --> 52: EBADE */ + 53, /* 51: EBADR --> 53: EBADR */ + 54, /* 52: EXFULL --> 54: EXFULL */ + 55, /* 53: ENOANO --> 55: ENOANO */ + 56, /* 54: EBADRQC --> 56: EBADRQC */ + 57, /* 55: EBADSLT --> 57: EBADSLT */ + 35, /* 56: EDEADLOCK --> 35: EDEADLK */ + 59, /* 57: EBFONT --> 59: EBFONT */ + 130, /* 58: EOWNERDEAD --> 130: EOWNERDEAD */ + 131, /* 59: ENOTRECOVERABLE --> 131: ENOTRECOVERABLE */ + 60, /* 60: ENOSTR --> 60: ENOSTR */ + 61, /* 61: ENODATA --> 61: ENODATA */ + 62, /* 62: ETIME --> 62: ETIME */ + 63, /* 63: ENOSR --> 63: ENOSR */ + 64, /* 64: ENONET --> 64: ENONET */ + 65, /* 65: ENOPKG --> 65: ENOPKG */ + 66, /* 66: EREMOTE --> 66: EREMOTE */ + 67, /* 67: ENOLINK --> 67: ENOLINK */ + 68, /* 68: EADV --> 68: EADV */ + 69, /* 69: ESRMNT --> 69: ESRMNT */ + 70, /* 70: ECOMM --> 70: ECOMM */ + 71, /* 71: EPROTO --> 71: EPROTO */ + -2, /* 72: ELOCKUNMAPPED --> -2: No Analogue */ + -2, /* 73: ENOTACTIVE --> -2: No Analogue */ + 72, /* 74: EMULTIHOP --> 72: EMULTIHOP */ + -1, /* 75: Unused Number */ + -1, /* 76: Unused Number */ + 74, /* 77: EBADMSG --> 74: EBADMSG */ + 36, /* 78: ENAMETOOLONG --> 36: ENAMETOOLONG */ + 75, /* 79: EOVERFLOW --> 75: EOVERFLOW */ + 76, /* 80: ENOTUNIQ --> 76: ENOTUNIQ */ + 77, /* 81: EBADFD --> 77: EBADFD */ + 78, /* 82: EREMCHG --> 78: EREMCHG */ + 79, /* 83: ELIBACC --> 79: ELIBACC */ + 80, /* 84: ELIBBAD --> 80: ELIBBAD */ + 81, /* 85: ELIBSCN --> 81: ELIBSCN */ + 82, /* 86: ELIBMAX --> 82: ELIBMAX */ + 83, /* 87: ELIBEXEC --> 83: ELIBEXEC */ + 84, /* 88: EILSEQ --> 84: EILSEQ */ + 38, /* 89: ENOSYS --> 38: ENOSYS */ + 40, /* 90: ELOOP --> 40: ELOOP */ + 85, /* 91: ERESTART --> 85: ERESTART */ + 86, /* 92: ESTRPIPE --> 86: ESTRPIPE */ + 39, /* 93: ENOTEMPTY --> 39: ENOTEMPTY */ + 87, /* 94: EUSERS --> 87: EUSERS */ + 88, /* 95: ENOTSOCK --> 88: ENOTSOCK */ + 89, /* 96: EDESTADDRREQ --> 89: EDESTADDRREQ */ + 90, /* 97: EMSGSIZE --> 90: EMSGSIZE */ + 91, /* 98: EPROTOTYPE --> 91: EPROTOTYPE */ + 92, /* 99: ENOPROTOOPT --> 92: ENOPROTOOPT */ + -1, /* 100: Unused Number */ + -1, /* 101: Unused Number */ + -1, /* 102: Unused Number */ + -1, /* 103: Unused Number */ + -1, /* 104: Unused Number */ + -1, /* 105: Unused Number */ + -1, /* 106: Unused Number */ + -1, /* 107: Unused Number */ + -1, /* 108: Unused Number */ + -1, /* 109: Unused Number */ + -1, /* 110: Unused Number */ + -1, /* 111: Unused Number */ + -1, /* 112: Unused Number */ + -1, /* 113: Unused Number */ + -1, /* 114: Unused Number */ + -1, /* 115: Unused Number */ + -1, /* 116: Unused Number */ + -1, /* 117: Unused Number */ + -1, /* 118: Unused Number */ + -1, /* 119: Unused Number */ + 93, /* 120: EPROTONOSUPPORT --> 93: EPROTONOSUPPORT */ + 94, /* 121: ESOCKTNOSUPPORT --> 94: ESOCKTNOSUPPORT */ + 95, /* 122: EOPNOTSUPP --> 95: EOPNOTSUPP */ + 96, /* 123: EPFNOSUPPORT --> 96: EPFNOSUPPORT */ + 97, /* 124: EAFNOSUPPORT --> 97: EAFNOSUPPORT */ + 98, /* 125: EADDRINUSE --> 98: EADDRINUSE */ + 99, /* 126: EADDRNOTAVAIL --> 99: EADDRNOTAVAIL */ + 100, /* 127: ENETDOWN --> 100: ENETDOWN */ + 101, /* 128: ENETUNREACH --> 101: ENETUNREACH */ + 102, /* 129: ENETRESET --> 102: ENETRESET */ + 103, /* 130: ECONNABORTED --> 103: ECONNABORTED */ + 104, /* 131: ECONNRESET --> 104: ECONNRESET */ + 105, /* 132: ENOBUFS --> 105: ENOBUFS */ + 106, /* 133: EISCONN --> 106: EISCONN */ + 107, /* 134: ENOTCONN --> 107: ENOTCONN */ + -1, /* 135: Unused Number */ + -1, /* 136: Unused Number */ + -1, /* 137: Unused Number */ + -1, /* 138: Unused Number */ + -1, /* 139: Unused Number */ + -1, /* 140: Unused Number */ + -1, /* 141: Unused Number */ + -1, /* 142: Unused Number */ + 108, /* 143: ESHUTDOWN --> 108: ESHUTDOWN */ + 109, /* 144: ETOOMANYREFS --> 109: ETOOMANYREFS */ + 110, /* 145: ETIMEDOUT --> 110: ETIMEDOUT */ + 111, /* 146: ECONNREFUSED --> 111: ECONNREFUSED */ + 112, /* 147: EHOSTDOWN --> 112: EHOSTDOWN */ + 113, /* 148: EHOSTUNREACH --> 113: EHOSTUNREACH */ + 114, /* 149: EALREADY --> 114: EALREADY */ + 115, /* 150: EINPROGRESS --> 115: EINPROGRESS */ + 116 /* 151: ESTALE --> 116: ESTALE */ +}; + +/* + * Convert an illumos native error number to a Linux error number and return + * it. If no valid conversion is possible, the function fails back to the + * value of "defval". In userland, passing a default error number of "-1" + * will abort the program if the error number could not be converted. + */ +int +lx_errno(int native_errno, int defval) +{ +#ifdef _KERNEL + VERIFY3S(defval, >=, 0); +#endif + + if (native_errno < 0 || native_errno >= (sizeof (lx_stol_errno) / + sizeof (lx_stol_errno[0]))) { +#ifndef _KERNEL + VERIFY3S(defval, >=, 0); +#endif + + return (defval); + } + + return (lx_stol_errno[native_errno]); +} diff --git a/usr/src/common/brand/lx/lx_errno.h b/usr/src/common/brand/lx/lx_errno.h new file mode 100644 index 0000000000..10b6b3066c --- /dev/null +++ b/usr/src/common/brand/lx/lx_errno.h @@ -0,0 +1,29 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Joyent, Inc. + */ + +#ifndef _LX_ERRNO_H +#define _LX_ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern int lx_errno(int, int); + +#ifdef __cplusplus +} +#endif + +#endif /* _LX_ERRNO_H */ diff --git a/usr/src/common/brand/lx/lx_signum.c b/usr/src/common/brand/lx/lx_signum.c index 22afb99ac7..4a8560a411 100644 --- a/usr/src/common/brand/lx/lx_signum.c +++ b/usr/src/common/brand/lx/lx_signum.c @@ -28,11 +28,7 @@ #include <sys/signal.h> #include <sys/lx_siginfo.h> #include <lx_signum.h> -#ifdef _KERNEL #include <sys/debug.h> -#else -#include <assert.h> -#endif /* * Delivering signals to a Linux process is complicated by differences in @@ -261,14 +257,12 @@ lx_stol_signo(int signo, int defsig) int rval; #ifdef _KERNEL - VERIFY(defsig != -1); + VERIFY3S(defsig, >=, 0); #endif if (signo < 0 || signo >= NSIG || (rval = stol_signo[signo]) < 1) { #ifndef _KERNEL - if (defsig == -1) { - assert(0); - } + VERIFY3S(defsig, >=, 0); #endif return (defsig); } diff --git a/usr/src/common/brand/lx/tools/Makefile b/usr/src/common/brand/lx/tools/Makefile new file mode 100644 index 0000000000..5ad1240c55 --- /dev/null +++ b/usr/src/common/brand/lx/tools/Makefile @@ -0,0 +1,42 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2015 Joyent, Inc. +# + +PROG = gen_errno + +include ../../../../cmd/Makefile.cmd + +OBJS = gen_errno.o + +CLOBBERFILES += $(PROG) + +NATIVECC_CFLAGS += $(CFLAGS) $(CCVERBOSE) +NATIVECC_LDLIBS += -lcmdutils -lnvpair + +.KEEP_STATE: + +all: $(PROG) + +install: all + +lint: lint_PROG + +clean: + $(RM) $(OBJS) + +$(PROG): $(OBJS) + $(NATIVECC) $(NATIVECC_CFLAGS) $(NATIVECC_LDLIBS) $(OBJS) -o $@ + $(POST_PROCESS) + +include ../../../../cmd/Makefile.targ diff --git a/usr/src/common/brand/lx/tools/README.md b/usr/src/common/brand/lx/tools/README.md new file mode 100644 index 0000000000..5e4976f200 --- /dev/null +++ b/usr/src/common/brand/lx/tools/README.md @@ -0,0 +1,39 @@ +# Updating Error Number Translations + +To create an updated error number translation table, you can use the +`gen_errno` tool. This tool requires, as input: + +* the illumos native `errno.h` file +* a set of foreign operating system `errno.h` files + +The output is a set of translation table entries suitable for inclusion in a +cstyled C array. The index of the array is the native error number and the +value at each index is the translated error number for use with the foreign +operating system. + +## Example + +To generate a translation table for the LX Brand, you will require two files +from the current Linux source: + +* `include/uapi/asm-generic/errno-base.h` (low-valued, or base, error numbers) +* `include/uapi/asm-generic/errno.h` (extended error numbers) + +Assuming the files are in the current directory, you should run the tool as +follows: + + $ dmake + ... + $ ./gen_errno -F errno-base.h -F errno.h \ + -N $SRC/uts/common/sys/errno.h + 0, /* 0: No Error */ + 1, /* 1: EPERM --> 1: EPERM */ + 2, /* 2: ENOENT --> 2: ENOENT */ + 3, /* 3: ESRCH --> 3: ESRCH */ + 4, /* 4: EINTR --> 4: EINTR */ + 5, /* 5: EIO --> 5: EIO */ + 6, /* 6: ENXIO --> 6: ENXIO */ + 7, /* 7: E2BIG --> 7: E2BIG */ + ... + +The output may be used in the `$SRC/common/brand/lx/lx_errno.c` file. diff --git a/usr/src/common/brand/lx/tools/gen_errno.c b/usr/src/common/brand/lx/tools/gen_errno.c new file mode 100644 index 0000000000..1edd924edf --- /dev/null +++ b/usr/src/common/brand/lx/tools/gen_errno.c @@ -0,0 +1,450 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Joyent, Inc. + */ + +/* + * Take the error number definitions from a foreign system and generate a + * translation table that converts illumos native error numbers to foreign + * system error numbers. + */ + +#include <ctype.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <err.h> +#include <sys/sysmacros.h> +#include <libcmdutils.h> +#include <libnvpair.h> + +nvlist_t *native_errors; +nvlist_t *foreign_errors; + +struct override { + const char *ovr_from; + const char *ovr_to; +} overrides[] = { + { "ENOTSUP", "ENOSYS" }, + { 0 } +}; + +static const char * +lookup_override(const char *from) +{ + int i; + + for (i = 0; overrides[i].ovr_from != NULL; i++) { + if (strcmp(overrides[i].ovr_from, from) == 0) { + return (overrides[i].ovr_to); + } + } + + return (NULL); +} + +static int +parse_int(const char *number, int *rval) +{ + long n; + char *endpos; + + errno = 0; + if ((n = strtol(number, &endpos, 10)) == 0 && errno != 0) { + return (-1); + } + + if (endpos != NULL && *endpos != '\0') { + errno = EINVAL; + return (-1); + } + + if (n > INT_MAX || n < INT_MIN) { + errno = EOVERFLOW; + return (-1); + } + + *rval = (int)n; + return (0); +} + +static int +errnum_add(nvlist_t *nvl, const char *name, const char *number) +{ + int val; + + if (nvlist_exists(nvl, name)) { + (void) fprintf(stderr, "ERROR: duplicate definition: %s -> " + "%s\n", name, number); + errno = EEXIST; + return (-1); + } + + /* + * Try and parse the error number: + */ + if (parse_int(number, &val) == 0) { + /* + * The name refers to a number. + */ + if (nvlist_add_int32(nvl, name, val) != 0) { + (void) fprintf(stderr, "ERROR: nvlist_add_int32: %s\n", + strerror(errno)); + return (-1); + } + } else { + /* + * The name refers to another definition. + */ + if (nvlist_add_string(nvl, name, number) != 0) { + (void) fprintf(stderr, "ERROR: nvlist_add_string: %s\n", + strerror(errno)); + return (-1); + } + } + + return (0); +} + +static int +errnum_max(nvlist_t *nvl) +{ + int max = 0; + nvpair_t *nvp = NULL; + + while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { + if (nvpair_type(nvp) != DATA_TYPE_INT32) { + continue; + } + + max = MAX(fnvpair_value_int32(nvp), max); + } + + return (max); +} + +static int +errname_by_num(nvlist_t *nvl, int num, const char **name) +{ + nvpair_t *nvp = NULL; + + while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { + if (nvpair_type(nvp) != DATA_TYPE_INT32) { + continue; + } + + if (fnvpair_value_int32(nvp) == num) { + *name = nvpair_name(nvp); + return (0); + } + } + + errno = ENOENT; + return (-1); +} + +static int +errno_by_name(nvlist_t *nvl, const char *name, int *rval, const char **rname) +{ + nvpair_t *nvp = NULL; + + if (nvlist_lookup_nvpair(nvl, name, &nvp) != 0) { + errno = ENOENT; + return (-1); + } + + if (nvpair_type(nvp) == DATA_TYPE_STRING) { + return (errno_by_name(nvl, fnvpair_value_string(nvp), rval, + rname)); + } else { + *rval = fnvpair_value_int32(nvp); + if (rname != NULL) { + *rname = name; + } + return (0); + } +} + +static int +process_line(const char *line, nvlist_t *nvl) +{ + custr_t *nam = NULL, *num = NULL; + const char *c = line; + + if (custr_alloc(&nam) != 0 || custr_alloc(&num) != 0) { + int en = errno; + + if (nam != NULL) { + custr_free(nam); + } + if (num != NULL) { + custr_free(num); + } + + errno = en; + return (-1); + } + + /* + * Valid lines begin with "#define": + */ + if (*c++ != '#' || *c++ != 'd' || *c++ != 'e' || *c++ != 'f' || + *c++ != 'i' || *c++ != 'n' || *c++ != 'e') { + return (0); + } + + /* + * Eat whitespace: + */ + for (;;) { + if (*c == '\0') { + return (0); + } + + if (*c != ' ' && *c != '\t') { + break; + } + + c++; + } + + /* + * Read error number token: + */ + for (;;) { + if (*c == '\0') { + return (0); + } + + if (*c == ' ' || *c == '\t') { + break; + } + + if (custr_appendc(nam, *c) != 0) { + return (-1); + } + + c++; + } + + /* + * Eat whitespace: + */ + for (;;) { + if (*c == '\0') { + return (0); + } + + if (*c != ' ' && *c != '\t') { + break; + } + + c++; + } + + /* + * Read error number token: + */ + for (;;) { + if (*c == '\0') { + break; + } + + if (*c == ' ' || *c == '\t') { + break; + } + + if (custr_appendc(num, *c) != 0) { + return (-1); + } + + c++; + } + + return (errnum_add(nvl, custr_cstr(nam), custr_cstr(num))); +} + +static int +read_file_into_list(const char *path, nvlist_t *nvl) +{ + int rval = 0, en = 0; + FILE *f; + custr_t *cu = NULL; + + if (custr_alloc(&cu) != 0 || custr_append(cu, "") != 0) { + if (cu != NULL) { + custr_free(cu); + } + return (-1); + } + + if ((f = fopen(path, "r")) == NULL) { + return (-1); + } + + for (;;) { + int c; + + errno = 0; + switch (c = fgetc(f)) { + case '\n': + case EOF: + if (errno != 0) { + en = errno; + rval = -1; + goto out; + } + if (process_line(custr_cstr(cu), nvl) != 0) { + en = errno; + rval = -1; + goto out; + } + custr_reset(cu); + if (c == EOF) { + goto out; + } + break; + + case '\r': + case '\0': + /* + * Ignore these characters. + */ + break; + + default: + if (custr_appendc(cu, c) != 0) { + en = errno; + rval = -1; + goto out; + } + break; + } + } + +out: + (void) fclose(f); + custr_free(cu); + errno = en; + return (rval); +} + +int +main(int argc, char **argv) +{ + int max; + int fval; + int c; + + if (nvlist_alloc(&native_errors, NV_UNIQUE_NAME, 0) != 0 || + nvlist_alloc(&foreign_errors, NV_UNIQUE_NAME, 0) != 0) { + err(1, "could not allocate memory"); + } + + while ((c = getopt(argc, argv, ":N:F:")) != -1) { + switch (c) { + case 'N': + if (read_file_into_list(optarg, native_errors) != 0) { + err(1, "could not read file: %s", optarg); + } + break; + + case 'F': + if (read_file_into_list(optarg, foreign_errors) != 0) { + err(1, "could not read file: %s", optarg); + } + break; + + case ':': + errx(1, "option -%c requires an operand", c); + break; + + case '?': + errx(1, "option -%c unrecognised", c); + break; + } + } + + /* + * Print an array entry for each error number: + */ + max = errnum_max(native_errors); + for (fval = 0; fval <= max; fval++) { + const char *fname; + const char *tname = NULL; + int32_t tval; + const char *msg = NULL; + const char *comma = (fval != max) ? "," : ""; + + if (errname_by_num(native_errors, fval, &fname) == -1) { + fname = NULL; + } + + if (fval == 0) { + /* + * The error number "0" is special: it means no worries. + */ + msg = "No Error"; + tval = 0; + } else if (fname == NULL) { + /* + * There is no defined name for this error number; it + * is unused. + */ + msg = "Unused Number"; + tval = -1; + } else { + /* + * Check if we want to override the name of this error + * in the foreign error number lookup: + */ + const char *oname = lookup_override(fname); + + /* + * Do the lookup: + */ + if (errno_by_name(foreign_errors, oname != NULL ? + oname : fname, &tval, &tname) != 0) { + /* + * There was no foreign error number by that + * name. + */ + tname = "No Analogue"; + tval = -2; + } + } + + if (msg == NULL) { + size_t flen = strlen(fname); + size_t tlen = strlen(tname); + const char *t = flen > 7 ? "\t" : "\t\t"; + const char *tt = tlen < 7 ? "\t\t\t" : tlen < 15 ? + "\t\t" : "\t"; + + (void) fprintf(stdout, "\t%d%s\t/* %3d: %s%s--> %3d: " + "%s%s*/\n", tval, comma, fval, fname, t, tval, + tname, tt); + } else { + const char *t = "\t\t\t\t\t"; + + (void) fprintf(stdout, "\t%d%s\t/* %3d: %s%s*/\n", tval, + comma, fval, msg, t); + } + } + + (void) nvlist_free(native_errors); + (void) nvlist_free(foreign_errors); + + return (0); +} diff --git a/usr/src/lib/brand/lx/lx_brand/Makefile.com b/usr/src/lib/brand/lx/lx_brand/Makefile.com index 804dccfce7..9c3b7b142c 100644 --- a/usr/src/lib/brand/lx/lx_brand/Makefile.com +++ b/usr/src/lib/brand/lx/lx_brand/Makefile.com @@ -63,7 +63,8 @@ COBJS = aio.o \ time.o \ truncate.o -CMNOBJS = lx_signum.o +CMNOBJS = lx_errno.o \ + lx_signum.o ASOBJS = lx_handler.o lx_crt.o OBJECTS = $(CMNOBJS) $(COBJS) $(ASOBJS) diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c index edbb51b1f2..6f3f1248ce 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c +++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c @@ -88,11 +88,6 @@ * function should return -errno back to the Linux caller. */ -/* - * Map Illumos errno to the Linux equivalent. - */ -static int stol_errno[] = LX_STOL_ERRNO_INIT; - char lx_release[LX_VERS_MAX]; char lx_cmd_name[MAXNAMLEN]; @@ -145,17 +140,6 @@ pid_t zoneinit_pid; /* zone init PID */ thread_key_t lx_tsd_key; int -lx_errno(int err) -{ - if (err >= sizeof (stol_errno) / sizeof (stol_errno[0])) { - lx_debug("invalid errno %d\n", err); - assert(0); - } - - return (stol_errno[err]); -} - -int uucopy_unsafe(const void *src, void *dst, size_t n) { bcopy(src, dst, n); diff --git a/usr/src/lib/brand/lx/lx_brand/common/signal.c b/usr/src/lib/brand/lx/lx_brand/common/signal.c index 7591be5792..48efd24eeb 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/signal.c +++ b/usr/src/lib/brand/lx/lx_brand/common/signal.c @@ -1451,7 +1451,7 @@ lx_call_user_handler(int sig, siginfo_t *sip, void *p) if (lxsap->lxsa_flags & LX_SA_RESTART) { uintptr_t flags = (uintptr_t)ucp->uc_brand_data[0]; long ret = (long)LX_REG(ucp, REG_R0); - boolean_t interrupted = (ret == -lx_errno(EINTR)); + boolean_t interrupted = (ret == -lx_errno(EINTR, -1)); /* * If the system call returned EINTR, and the system diff --git a/usr/src/lib/brand/lx/lx_brand/common/socket.c b/usr/src/lib/brand/lx/lx_brand/common/socket.c index b8c2c31582..9a2e7fd845 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/socket.c +++ b/usr/src/lib/brand/lx/lx_brand/common/socket.c @@ -2088,7 +2088,7 @@ lx_getsockopt(int sockfd, int level, int optname, void *optval, int *optlenp) break; case SO_ERROR: - *(int *)optval = lx_errno(*(int *)optval); + *(int *)optval = lx_errno(*(int *)optval, -1); break; } } diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h b/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h index bed6a8da4b..c4edfc0b1a 100644 --- a/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h +++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h @@ -41,6 +41,8 @@ #include <sys/lx_brand.h> #include <sys/lx_thread.h> +#include <lx_errno.h> + #ifdef __cplusplus extern "C" { #endif @@ -168,7 +170,6 @@ struct ucontext; extern ucontext_t *lx_syscall_regs(void); extern uintptr_t lx_find_brand_sp(void); extern const ucontext_t *lx_find_brand_uc(void); -extern int lx_errno(int); extern char *lx_fd_to_path(int fd, char *buf, int buf_size); extern int lx_lpid_to_spair(pid_t, pid_t *, lwpid_t *); diff --git a/usr/src/uts/common/brand/lx/os/lx_syscall.c b/usr/src/uts/common/brand/lx/os/lx_syscall.c index c8b8560555..da6447ec9a 100644 --- a/usr/src/uts/common/brand/lx/os/lx_syscall.c +++ b/usr/src/uts/common/brand/lx/os/lx_syscall.c @@ -42,6 +42,7 @@ #include <sys/lx_brand.h> #include <sys/lx_impl.h> #include <sys/lx_misc.h> +#include <lx_errno.h> /* @@ -95,11 +96,6 @@ int lx_nsysent64; lx_sysent_t lx_sysent32[LX_NSYSCALLS + 1]; int lx_nsysent32; -/* - * Map Illumos errno to the Linux equivalent. - */ -int lx_stol_errno[] = LX_STOL_ERRNO_INIT; - #if defined(_LP64) struct lx_vsyscall { @@ -232,14 +228,7 @@ lx_syscall_return(klwp_t *lwp, int syscall_num, long ret) /* * Convert from illumos to Linux errno: */ - if (error < 1 || error >= (sizeof (lx_stol_errno) / - sizeof (lx_stol_errno[0]))) { - /* - * The provided error number is not valid. - */ - error = EINVAL; - } - ret = -lx_stol_errno[error]; + ret = -lx_errno(error, EINVAL); } /* diff --git a/usr/src/uts/common/brand/lx/sys/lx_brand.h b/usr/src/uts/common/brand/lx/sys/lx_brand.h index f3c46dd7fd..473bbd8917 100644 --- a/usr/src/uts/common/brand/lx/sys/lx_brand.h +++ b/usr/src/uts/common/brand/lx/sys/lx_brand.h @@ -158,31 +158,6 @@ typedef enum lx_ptrace_options { #define AT_SYSINFO_EHDR 33 /* - * This table initialiser maps errno values from illumos to Linux numbers. - * It is presently used in both the usermode and kernel emulation code, - * so it is defined here. - */ -/* BEGIN CSTYLED */ -#define LX_STOL_ERRNO_INIT { \ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \ - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, \ - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, \ - 30, 31, 32, 33, 34, 42, 43, 44, 45, 46, \ - 47, 48, 49, 50, 51, 35, 47, 22, 38, 22, /* 49 */ \ - 52, 53, 54, 55, 56, 57, 58, 59, 22, 22, \ - 61, 61, 62, 63, 64, 65, 66, 67, 68, 69, \ - 70, 71, 22, 22, 72, 22, 22, 74, 36, 75, \ - 76, 77, 78, 79, 80, 81, 82, 83, 84, 38, \ - 40, 85, 86, 39, 87, 88, 89, 90, 91, 92, /* 99 */ \ - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, \ - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, \ - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, \ - 103, 104, 105, 106, 107, 22, 22, 22, 22, 22, \ - 22, 22, 22, 108, 109, 110, 111, 112, 113, 114, /* 149 */ \ - 115, 116 } -/* END CSTYLED */ - -/* * Usermode emulation routines are run on an alternate stack allocated by * the brand library. Every LWP in a process will incur this overhead beyond * the regular thread stack: @@ -640,8 +615,6 @@ extern void lx_emulate_user32(klwp_t *, int, uintptr_t *); extern int lx_debug; #define lx_print if (lx_debug) printf -extern int lx_stol_errno[]; - /* * In-Kernel Linux System Call Description. */ diff --git a/usr/src/uts/common/brand/lx/syscall/lx_wait.c b/usr/src/uts/common/brand/lx/syscall/lx_wait.c index 7b10d2f90b..e6c5607e43 100644 --- a/usr/src/uts/common/brand/lx/syscall/lx_wait.c +++ b/usr/src/uts/common/brand/lx/syscall/lx_wait.c @@ -72,6 +72,7 @@ #include <sys/lx_types.h> #include <sys/lx_siginfo.h> #include <lx_signum.h> +#include <lx_errno.h> #include <lx_syscall.h> /* @@ -332,7 +333,7 @@ stol_ksiginfo(k_siginfo_t *sip, uintptr_t lxsip) bzero(&lsi, sizeof (lsi)); lsi.lsi_signo = lx_stol_signo(sip->si_signo, SIGCLD); lsi.lsi_code = lx_stol_sigcode(sip->si_code); - lsi.lsi_errno = lx_stol_errno[sip->si_errno]; + lsi.lsi_errno = lx_errno(sip->si_errno, EINVAL); switch (lsi.lsi_signo) { case LX_SIGPOLL: @@ -380,7 +381,7 @@ stol_ksiginfo32(k_siginfo_t *sip, uintptr_t lxsip) bzero(&lsi, sizeof (lsi)); lsi.lsi_signo = lx_stol_signo(sip->si_signo, SIGCLD); lsi.lsi_code = lx_stol_sigcode(sip->si_code); - lsi.lsi_errno = lx_stol_errno[sip->si_errno]; + lsi.lsi_errno = lx_errno(sip->si_errno, EINVAL); switch (lsi.lsi_signo) { case LX_SIGPOLL: diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files index b8127194ad..1f2cddbd61 100644 --- a/usr/src/uts/intel/Makefile.files +++ b/usr/src/uts/intel/Makefile.files @@ -282,6 +282,7 @@ LX_BRAND_OBJS = \ lx_chmod.o \ lx_chown.o \ lx_clone.o \ + lx_errno.o \ lx_futex.o \ lx_getpid.o \ lx_id.o \ diff --git a/usr/src/uts/intel/brand/lx/lx_archdep.c b/usr/src/uts/intel/brand/lx/lx_archdep.c index 49f2f12172..008044842d 100644 --- a/usr/src/uts/intel/brand/lx/lx_archdep.c +++ b/usr/src/uts/intel/brand/lx/lx_archdep.c @@ -28,6 +28,7 @@ #include <sys/stack.h> #include <sys/sdt.h> #include <sys/sysmacros.h> +#include <lx_errno.h> #define LX_REG(ucp, r) ((ucp)->uc_mcontext.gregs[(r)]) @@ -563,7 +564,7 @@ lx_regs_to_userregs(lx_lwp_data_t *lwpd, void *uregsp) switch (lwpd->br_ptrace_whatstop) { case LX_PR_SYSENTRY: orig_r0 = lwpd->br_syscall_num; - r0 = -lx_stol_errno[ENOTSUP]; + r0 = -lx_errno(ENOTSUP, EINVAL); break; case LX_PR_SYSEXIT: orig_r0 = lwpd->br_syscall_num; |
