Index: Makefile
===================================================================
--- Makefile	(revision bdb8ba96ffd7821d1ddf4c8979d1b413e1771809)
+++ Makefile	(revision 3529fbf0dcb9c1b1a37194a16e000ee253b245a3)
@@ -44,4 +44,6 @@
 CONFIG_MAKEFILE = Makefile.config
 CONFIG_HEADER = config.h
+ERRNO_HEADER = abi/include/abi/errno.h
+ERRNO_INPUT = abi/include/abi/errno.in
 
 .PHONY: all precheck cscope cscope_parts autotool config_auto config_default config distclean clean check releasefile release common boot kernel uspace
@@ -50,5 +52,5 @@
 	$(MAKE) -r -C boot PRECHECK=$(PRECHECK)
 
-common: $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER)
+common: $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) $(ERRNO_HEADER)
 
 kernel: common
@@ -125,3 +127,8 @@
 	$(MAKE) -r -C doxygen clean
 
+$(ERRNO_HEADER): $(ERRNO_INPUT)
+	echo '/* Generated file. Edit errno.in instead. */' > $@.new
+	sed 's/__errno_entry(\([^,]*\),\([^,]*\),.*/#define \1 \2/' < $< >> $@.new
+	mv $@.new $@
+
 -include Makefile.local
Index: abi/include/abi/errno.h
===================================================================
--- abi/include/abi/errno.h	(revision bdb8ba96ffd7821d1ddf4c8979d1b413e1771809)
+++ abi/include/abi/errno.h	(revision 3529fbf0dcb9c1b1a37194a16e000ee253b245a3)
@@ -1,110 +1,38 @@
-/*
- * Copyright (c) 2005 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup generic
- * @{
- */
-/** @file
- */
-
-#ifndef ABI_ERRNO_H_
-#define ABI_ERRNO_H_
-
-/**
- * Values in the range [-1, -255] are kernel error codes,
- * values in the range [-256, -512] are user error codes.
- */
-
-typedef enum {
-	EOK           =  0,   /* No error */
-	ENOENT        = -1,   /* No such entry */
-	ENOMEM        = -2,   /* Not enough memory */
-	ELIMIT        = -3,   /* Limit exceeded */
-	EREFUSED      = -4,   /* Connection refused */
-	EFORWARD      = -5,   /* Forward error */
-	EPERM         = -6,   /* Permission denied */
-
-/*
- * Answerbox closed connection, call
- * sys_ipc_hangup() to close the connection.
- * Used by answerbox to close the connection.
- */
-	EHANGUP       = -7,
-
-/*
- * The other party encountered an error when
- * receiving the call.
- */
-	EPARTY        = -8,
-
-	EEXIST        = -9,   /* Entry already exists */
-	EBADMEM       = -10,  /* Bad memory pointer */
-	ENOTSUP       = -11,  /* Not supported */
-	EADDRNOTAVAIL = -12,  /* Address not available. */
-	ETIMEOUT      = -13,  /* Timeout expired */
-	EINVAL        = -14,  /* Invalid value */
-	EBUSY         = -15,  /* Resource is busy */
-	EOVERFLOW     = -16,  /* The result does not fit its size. */
-	EINTR         = -17,  /* Operation was interrupted. */
-
-	EMFILE        = -18,
-	ENAMETOOLONG  = -256,
-	EISDIR        = -257,
-	ENOTDIR       = -258,
-	ENOSPC        = -259,
-	ENOTEMPTY     = -261,
-	EBADF         = -262,
-	EDOM          = -263,
-	ERANGE        = -264,
-	EXDEV         = -265,
-	EIO           = -266,
-	EMLINK        = -267,
-	ENXIO         = -268,
-	ENOFS         = -269,
-
-/** Bad checksum. */
-	EBADCHECKSUM  = -300,
-
-/** USB: stalled operation. */
-	ESTALL        = -301,
-
-/** Empty resource (no data). */
-	EEMPTY        = -302,
-
-/** Negative acknowledgment. */
-	ENAK          = -303,
-
-/** The requested operation was not performed. Try again later. */
-	EAGAIN        = -11002,
-} errno_t;
-
-
-#endif
-
-/** @}
- */
+/* Generated file. Edit errno.in instead. */
+#define EOK                   0
+#define ENOENT               -1
+#define ENOMEM               -2
+#define ELIMIT               -3
+#define EREFUSED             -4
+#define EFORWARD             -5
+#define EPERM                -6
+#define EHANGUP              -7
+#define EPARTY               -8
+#define EEXIST               -9
+#define EBADMEM             -10
+#define ENOTSUP             -11
+#define EADDRNOTAVAIL       -12
+#define ETIMEOUT            -13
+#define EINVAL              -14
+#define EBUSY               -15
+#define EOVERFLOW           -16
+#define EINTR               -17
+#define EMFILE              -18
+#define ENAMETOOLONG       -256
+#define EISDIR             -257
+#define ENOTDIR            -258
+#define ENOSPC             -259
+#define ENOTEMPTY          -261
+#define EBADF              -262
+#define EDOM               -263
+#define ERANGE             -264
+#define EXDEV              -265
+#define EIO                -266
+#define EMLINK             -267
+#define ENXIO              -268
+#define ENOFS              -269
+#define EBADCHECKSUM       -300
+#define ESTALL             -301
+#define EEMPTY             -302
+#define ENAK               -303
+#define EAGAIN           -11002
Index: abi/include/abi/errno.in
===================================================================
--- abi/include/abi/errno.in	(revision 3529fbf0dcb9c1b1a37194a16e000ee253b245a3)
+++ abi/include/abi/errno.in	(revision 3529fbf0dcb9c1b1a37194a16e000ee253b245a3)
@@ -0,0 +1,37 @@
+__errno_entry(EOK            ,      0, "No error")
+__errno_entry(ENOENT         ,     -1, "No such entry")
+__errno_entry(ENOMEM         ,     -2, "Not enough memory")
+__errno_entry(ELIMIT         ,     -3, "Limit exceeded")
+__errno_entry(EREFUSED       ,     -4, "Connection refused")
+__errno_entry(EFORWARD       ,     -5, "Forwarding error")
+__errno_entry(EPERM          ,     -6, "Permission denied")
+__errno_entry(EHANGUP        ,     -7, "Answerbox closed connection")
+__errno_entry(EPARTY         ,     -8, "Other party encountered an error")
+__errno_entry(EEXIST         ,     -9, "Entry already exists")
+__errno_entry(EBADMEM        ,    -10, "Bad memory pointer")
+__errno_entry(ENOTSUP        ,    -11, "Operation not supported")
+__errno_entry(EADDRNOTAVAIL  ,    -12, "Address not available")
+__errno_entry(ETIMEOUT       ,    -13, "Timeout expired")
+__errno_entry(EINVAL         ,    -14, "Invalid value")
+__errno_entry(EBUSY          ,    -15, "Resource is busy")
+__errno_entry(EOVERFLOW      ,    -16, "Result does not fit its size")
+__errno_entry(EINTR          ,    -17, "Operation interrupted")
+__errno_entry(EMFILE         ,    -18, "Too many open files")
+__errno_entry(ENAMETOOLONG   ,   -256, "Name is too long")
+__errno_entry(EISDIR         ,   -257, "Entry is a directory")
+__errno_entry(ENOTDIR        ,   -258, "Entry is not a directory")
+__errno_entry(ENOSPC         ,   -259, "No space left")
+__errno_entry(ENOTEMPTY      ,   -261, "Directory is not empty")
+__errno_entry(EBADF          ,   -262, "Bad object handle")
+__errno_entry(EDOM           ,   -263, "Domain error")
+__errno_entry(ERANGE         ,   -264, "Value out of range")
+__errno_entry(EXDEV          ,   -265, "Prohibited cross-device link")
+__errno_entry(EIO            ,   -266, "Input/output error")
+__errno_entry(EMLINK         ,   -267, "Too many links")
+__errno_entry(ENXIO          ,   -268, "Device or address does not exist")
+__errno_entry(ENOFS          ,   -269, "No such file system type")
+__errno_entry(EBADCHECKSUM   ,   -300, "Bad checksum")
+__errno_entry(ESTALL         ,   -301, "USB: Operation stalled")
+__errno_entry(EEMPTY         ,   -302, "Resource is empty")
+__errno_entry(ENAK           ,   -303, "Negative acknowledgement")
+__errno_entry(EAGAIN         , -11002, "Operation could not proceed. Try again.")
Index: kernel/generic/include/errno.h
===================================================================
--- kernel/generic/include/errno.h	(revision bdb8ba96ffd7821d1ddf4c8979d1b413e1771809)
+++ kernel/generic/include/errno.h	(revision 3529fbf0dcb9c1b1a37194a16e000ee253b245a3)
@@ -36,4 +36,6 @@
 #define KERN_ERRNO_H_
 
+typedef int errno_t;
+
 #include <abi/errno.h>
 
Index: uspace/lib/c/generic/str_error.c
===================================================================
--- uspace/lib/c/generic/str_error.c	(revision bdb8ba96ffd7821d1ddf4c8979d1b413e1771809)
+++ uspace/lib/c/generic/str_error.c	(revision 3529fbf0dcb9c1b1a37194a16e000ee253b245a3)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2010 Martin Decky
+ * Copyright (c) 2017 CZ.NIC, z.s.p.o.
  * All rights reserved.
  *
@@ -38,73 +39,59 @@
 #include <fibril.h>
 
-#define MIN_ERRNO  -17
 #define NOERR_LEN  64
 
-// TODO: this file should be generated from errno declarations
+/* The arrays bellow are automatically generated from the same file that
+ * errno.h constants are generated from. Triple-include of the same list
+ * with redefinitions of __errno() macro are used to ensure that the
+ * information cannot get out of synch. This is inpired by musl libc.
+ */
+
+#undef __errno_entry
+#define __errno_entry(name, num, desc) num,
+
+static const int err_num[] = {
+#include <abi/errno.in>
+};
+
+#undef __errno_entry
+#define __errno_entry(name, num, desc) #name,
 
 static const char* err_name[] = {
-	"EOK",
-	"ENOENT",
-	"ENOMEM",
-	"ELIMIT",
-	"EREFUSED",
-	"EFORWARD",
-	"EPERM",
-	"EHANGUP",
-	"EPARTY",
-	"EEXIST",
-	"EBADMEM",
-	"ENOTSUP",
-	"EADDRNOTAVAIL",
-	"ETIMEOUT",
-	"EINVAL",
-	"EBUSY",
-	"EOVERFLOW",
-	"EINTR"
+#include <abi/errno.in>
 };
 
+#undef __errno_entry
+#define __errno_entry(name, num, desc) "[" #name "]" desc,
+
 static const char* err_desc[] = {
-	"No error",
-	"No such entry",
-	"Not enough memory",
-	"Limit exceeded",
-	"Connection refused",
-	"Forwarding error",
-	"Permission denied",
-	"Answerbox closed connection",
-	"Other party error",
-	"Entry already exists",
-	"Bad memory pointer",
-	"Not supported",
-	"Address not available",
-	"Timeout expired",
-	"Invalid value",
-	"Resource is busy",
-	"Result does not fit its size",
-	"Operation interrupted"
+#include <abi/errno.in>
 };
 
 static fibril_local char noerr[NOERR_LEN];
 
+/* Returns index corresponding to the given errno, or -1 if not found. */
+static int find_errno(errno_t e)
+{
+	/* Just a dumb linear search.
+	 * There too few entries to warrant anything smarter.
+	 */
+
+	int len = sizeof(err_num) / sizeof(errno_t);
+
+	for (int i = 0; i < len; i++) {
+		if (err_num[i] == e) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
 const char *str_error_name(errno_t e)
 {
-	if ((e <= 0) && (e >= MIN_ERRNO))
-		return err_name[-e];
+	int i = find_errno(e);
 
-	/* Ad hoc descriptions of error codes interesting for USB. */
-	// FIXME: integrate these as first-class error values
-	switch (e) {
-		case ENOFS:
-			return "ENOFS";
-		case EBADCHECKSUM:
-			return "EBADCHECKSUM";
-		case ESTALL:
-			return "ESTALL";
-		case EAGAIN:
-			return "EAGAIN";
-		case EEMPTY:
-			return "EEMPTY";
-		default:
-			break;
+	if (i >= 0) {
+		return err_name[i];
 	}
 
@@ -115,22 +102,8 @@
 const char *str_error(errno_t e)
 {
-	if ((e <= 0) && (e >= MIN_ERRNO))
-		return err_desc[-e];
-	
-	/* Ad hoc descriptions of error codes interesting for USB. */
-	// FIXME: integrate these as first-class error values
-	switch (e) {
-		case ENOFS:
-			return "No such file system type";
-		case EBADCHECKSUM:
-			return "Bad checksum";
-		case ESTALL:
-			return "Operation stalled";
-		case EAGAIN:
-			return "Resource temporarily unavailable";
-		case EEMPTY:
-			return "Resource is empty";
-		default:
-			break;
+	int i = find_errno(e);
+
+	if (i >= 0) {
+		return err_desc[i];
 	}
 
Index: uspace/lib/c/include/errno.h
===================================================================
--- uspace/lib/c/include/errno.h	(revision bdb8ba96ffd7821d1ddf4c8979d1b413e1771809)
+++ uspace/lib/c/include/errno.h	(revision 3529fbf0dcb9c1b1a37194a16e000ee253b245a3)
@@ -36,4 +36,6 @@
 #define LIBC_ERRNO_H_
 
+typedef int errno_t;
+
 #include <abi/errno.h>
 
