Experimental approach to tackle the problem with Be's negative error codes and

ported software:
* If the macro B_USE_POSITIVE_POSIX_ERRORS is defined the POSIX error code
  constants (ENOMEM, EINTR,...) will have positive values.
* Introduced the macros B_TO_{POSITIVE,NEGATIVE}_ERROR() which do convert a
  given error code to a positive/negative value.
* Added static library libposix_error_mapper.a that overrides all POSIX
  functions (save the ones I forgot to add :-)) directly meddling with error
  codes (having them as parameter or returning them) dealing with the
  positive<->negative error code conversions. The functions have hidden
  visibility, so they affect only the shared object they are linked into.
* So ideally all one has to do is to build a ported software with
  -DB_USE_POSITIVE_POSIX_ERRORS and -lposix_error_mapper and be good with
  respect to error code problems.
* Potential issues:
  - When mixing ported and Haiku native code, i.e. using Haiku native code in
    a ported software or using a ported library in a Haiku native application
    care must be taken to convert error codes where the two interface. That's
    what the B_TO_{POSITIVE,NEGATIVE}_ERROR() macros are supposed to be used
    for.
  - A ported static library can obviously not be linked directly against
    -lposix_error_mapper. The shared object linking a against the ported static
    library has to do that. The previous point applies when that causes mixing
    with Haiku native code.
  - When dependent ported libraries are used probably all of them should use
    the error mapping.

Comments welcome.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29653 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-03-22 15:43:03 +00:00
parent 4b0f97863f
commit 39d58e2f49
18 changed files with 924 additions and 91 deletions
+121 -90
View File
@@ -114,100 +114,115 @@
#define B_PARTITION_TOO_SMALL (B_STORAGE_ERROR_BASE + 15)
/* POSIX Errors */
#define E2BIG (B_POSIX_ERROR_BASE + 1)
#define ECHILD (B_POSIX_ERROR_BASE + 2)
#define EDEADLK (B_POSIX_ERROR_BASE + 3)
#define EFBIG (B_POSIX_ERROR_BASE + 4)
#define EMLINK (B_POSIX_ERROR_BASE + 5)
#define ENFILE (B_POSIX_ERROR_BASE + 6)
#define ENODEV (B_POSIX_ERROR_BASE + 7)
#define ENOLCK (B_POSIX_ERROR_BASE + 8)
#define ENOSYS (B_POSIX_ERROR_BASE + 9)
#define ENOTTY (B_POSIX_ERROR_BASE + 10)
#define ENXIO (B_POSIX_ERROR_BASE + 11)
#define ESPIPE (B_POSIX_ERROR_BASE + 12)
#define ESRCH (B_POSIX_ERROR_BASE + 13)
#define EFPOS (B_POSIX_ERROR_BASE + 14)
#define ESIGPARM (B_POSIX_ERROR_BASE + 15)
#define EDOM (B_POSIX_ERROR_BASE + 16)
#define ERANGE (B_POSIX_ERROR_BASE + 17)
#define EPROTOTYPE (B_POSIX_ERROR_BASE + 18)
#define EPROTONOSUPPORT (B_POSIX_ERROR_BASE + 19)
#define EPFNOSUPPORT (B_POSIX_ERROR_BASE + 20)
#define EAFNOSUPPORT (B_POSIX_ERROR_BASE + 21)
#define EADDRINUSE (B_POSIX_ERROR_BASE + 22)
#define EADDRNOTAVAIL (B_POSIX_ERROR_BASE + 23)
#define ENETDOWN (B_POSIX_ERROR_BASE + 24)
#define ENETUNREACH (B_POSIX_ERROR_BASE + 25)
#define ENETRESET (B_POSIX_ERROR_BASE + 26)
#define ECONNABORTED (B_POSIX_ERROR_BASE + 27)
#define ECONNRESET (B_POSIX_ERROR_BASE + 28)
#define EISCONN (B_POSIX_ERROR_BASE + 29)
#define ENOTCONN (B_POSIX_ERROR_BASE + 30)
#define ESHUTDOWN (B_POSIX_ERROR_BASE + 31)
#define ECONNREFUSED (B_POSIX_ERROR_BASE + 32)
#define EHOSTUNREACH (B_POSIX_ERROR_BASE + 33)
#define ENOPROTOOPT (B_POSIX_ERROR_BASE + 34)
#define ENOBUFS (B_POSIX_ERROR_BASE + 35)
#define EINPROGRESS (B_POSIX_ERROR_BASE + 36)
#define EALREADY (B_POSIX_ERROR_BASE + 37)
#define EILSEQ (B_POSIX_ERROR_BASE + 38)
#define ENOMSG (B_POSIX_ERROR_BASE + 39)
#define ESTALE (B_POSIX_ERROR_BASE + 40)
#define EOVERFLOW (B_POSIX_ERROR_BASE + 41)
#define EMSGSIZE (B_POSIX_ERROR_BASE + 42)
#define EOPNOTSUPP (B_POSIX_ERROR_BASE + 43)
#define ENOTSOCK (B_POSIX_ERROR_BASE + 44)
#define EHOSTDOWN (B_POSIX_ERROR_BASE + 45)
#define EBADMSG (B_POSIX_ERROR_BASE + 46)
#define ECANCELED (B_POSIX_ERROR_BASE + 47)
#define EDESTADDRREQ (B_POSIX_ERROR_BASE + 48)
#define EDQUOT (B_POSIX_ERROR_BASE + 49)
#define EIDRM (B_POSIX_ERROR_BASE + 50)
#define EMULTIHOP (B_POSIX_ERROR_BASE + 51)
#define ENODATA (B_POSIX_ERROR_BASE + 52)
#define ENOLINK (B_POSIX_ERROR_BASE + 53)
#define ENOSR (B_POSIX_ERROR_BASE + 54)
#define ENOSTR (B_POSIX_ERROR_BASE + 55)
#define ENOTSUP (B_POSIX_ERROR_BASE + 56)
#define EPROTO (B_POSIX_ERROR_BASE + 57)
#define ETIME (B_POSIX_ERROR_BASE + 58)
#define ETXTBSY (B_POSIX_ERROR_BASE + 59)
#ifdef B_USE_POSITIVE_POSIX_ERRORS
# define B_TO_POSIX_ERROR(error) (-(error))
# define B_FROM_POSIX_ERROR(error) (-(error))
#else
# define B_TO_POSIX_ERROR(error) (error)
# define B_FROM_POSIX_ERROR(error) (error)
#endif
#define B_POSIX_ENOMEM B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 0)
#define E2BIG B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 1)
#define ECHILD B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 2)
#define EDEADLK B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 3)
#define EFBIG B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 4)
#define EMLINK B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 5)
#define ENFILE B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 6)
#define ENODEV B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 7)
#define ENOLCK B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 8)
#define ENOSYS B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 9)
#define ENOTTY B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 10)
#define ENXIO B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 11)
#define ESPIPE B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 12)
#define ESRCH B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 13)
#define EFPOS B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 14)
#define ESIGPARM B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 15)
#define EDOM B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 16)
#define ERANGE B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 17)
#define EPROTOTYPE B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 18)
#define EPROTONOSUPPORT B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 19)
#define EPFNOSUPPORT B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 20)
#define EAFNOSUPPORT B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 21)
#define EADDRINUSE B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 22)
#define EADDRNOTAVAIL B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 23)
#define ENETDOWN B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 24)
#define ENETUNREACH B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 25)
#define ENETRESET B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 26)
#define ECONNABORTED B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 27)
#define ECONNRESET B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 28)
#define EISCONN B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 29)
#define ENOTCONN B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 30)
#define ESHUTDOWN B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 31)
#define ECONNREFUSED B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 32)
#define EHOSTUNREACH B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 33)
#define ENOPROTOOPT B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 34)
#define ENOBUFS B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 35)
#define EINPROGRESS B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 36)
#define EALREADY B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 37)
#define EILSEQ B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 38)
#define ENOMSG B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 39)
#define ESTALE B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 40)
#define EOVERFLOW B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 41)
#define EMSGSIZE B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 42)
#define EOPNOTSUPP B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 43)
#define ENOTSOCK B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 44)
#define EHOSTDOWN B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 45)
#define EBADMSG B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 46)
#define ECANCELED B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 47)
#define EDESTADDRREQ B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 48)
#define EDQUOT B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 49)
#define EIDRM B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 50)
#define EMULTIHOP B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 51)
#define ENODATA B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 52)
#define ENOLINK B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 53)
#define ENOSR B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 54)
#define ENOSTR B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 55)
#define ENOTSUP B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 56)
#define EPROTO B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 57)
#define ETIME B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 58)
#define ETXTBSY B_TO_POSIX_ERROR(B_POSIX_ERROR_BASE + 59)
/* B_NO_MEMORY (0x80000000) can't be negated, so it needs special handling */
#ifdef B_USE_POSITIVE_POSIX_ERRORS
# define ENOMEM B_POSIX_ENOMEM
#else
# define ENOMEM B_NO_MEMORY
#endif
/* POSIX errors that can be mapped to BeOS error codes */
#define ENOMEM B_NO_MEMORY
#define EACCES B_PERMISSION_DENIED
#define EINTR B_INTERRUPTED
#define EIO B_IO_ERROR
#define EBUSY B_BUSY
#define EFAULT B_BAD_ADDRESS
#define ETIMEDOUT B_TIMED_OUT
#define EAGAIN B_WOULD_BLOCK /* SysV compatibility */
#define EWOULDBLOCK B_WOULD_BLOCK /* BSD compatibility */
#define EBADF B_FILE_ERROR
#define EEXIST B_FILE_EXISTS
#define EINVAL B_BAD_VALUE
#define ENAMETOOLONG B_NAME_TOO_LONG
#define ENOENT B_ENTRY_NOT_FOUND
#define EPERM B_NOT_ALLOWED
#define ENOTDIR B_NOT_A_DIRECTORY
#define EISDIR B_IS_A_DIRECTORY
#define ENOTEMPTY B_DIRECTORY_NOT_EMPTY
#define ENOSPC B_DEVICE_FULL
#define EROFS B_READ_ONLY_DEVICE
#define EMFILE B_NO_MORE_FDS
#define EXDEV B_CROSS_DEVICE_LINK
#define ELOOP B_LINK_LIMIT
#define ENOEXEC B_NOT_AN_EXECUTABLE
#define EPIPE B_BUSTED_PIPE
#define EACCES B_TO_POSIX_ERROR(B_PERMISSION_DENIED)
#define EINTR B_TO_POSIX_ERROR(B_INTERRUPTED)
#define EIO B_TO_POSIX_ERROR(B_IO_ERROR)
#define EBUSY B_TO_POSIX_ERROR(B_BUSY)
#define EFAULT B_TO_POSIX_ERROR(B_BAD_ADDRESS)
#define ETIMEDOUT B_TO_POSIX_ERROR(B_TIMED_OUT)
#define EAGAIN B_TO_POSIX_ERROR(B_WOULD_BLOCK) /* SysV compatibility */
#define EWOULDBLOCK B_TO_POSIX_ERROR(B_WOULD_BLOCK) /* BSD compatibility */
#define EBADF B_TO_POSIX_ERROR(B_FILE_ERROR)
#define EEXIST B_TO_POSIX_ERROR(B_FILE_EXISTS)
#define EINVAL B_TO_POSIX_ERROR(B_BAD_VALUE)
#define ENAMETOOLONG B_TO_POSIX_ERROR(B_NAME_TOO_LONG)
#define ENOENT B_TO_POSIX_ERROR(B_ENTRY_NOT_FOUND)
#define EPERM B_TO_POSIX_ERROR(B_NOT_ALLOWED)
#define ENOTDIR B_TO_POSIX_ERROR(B_NOT_A_DIRECTORY)
#define EISDIR B_TO_POSIX_ERROR(B_IS_A_DIRECTORY)
#define ENOTEMPTY B_TO_POSIX_ERROR(B_DIRECTORY_NOT_EMPTY)
#define ENOSPC B_TO_POSIX_ERROR(B_DEVICE_FULL)
#define EROFS B_TO_POSIX_ERROR(B_READ_ONLY_DEVICE)
#define EMFILE B_TO_POSIX_ERROR(B_NO_MORE_FDS)
#define EXDEV B_TO_POSIX_ERROR(B_CROSS_DEVICE_LINK)
#define ELOOP B_TO_POSIX_ERROR(B_LINK_LIMIT)
#define ENOEXEC B_TO_POSIX_ERROR(B_NOT_AN_EXECUTABLE)
#define EPIPE B_TO_POSIX_ERROR(B_BUSTED_PIPE)
/* new error codes that can be mapped to POSIX errors */
#define B_BUFFER_OVERFLOW EOVERFLOW
#define B_TOO_MANY_ARGS E2BIG
#define B_FILE_TOO_LARGE EFBIG
#define B_RESULT_NOT_REPRESENTABLE ERANGE
#define B_DEVICE_NOT_FOUND ENODEV
#define B_NOT_SUPPORTED EOPNOTSUPP
#define B_BUFFER_OVERFLOW B_FROM_POSIX_ERROR(EOVERFLOW)
#define B_TOO_MANY_ARGS B_FROM_POSIX_ERROR(E2BIG)
#define B_FILE_TOO_LARGE B_FROM_POSIX_ERROR(EFBIG)
#define B_RESULT_NOT_REPRESENTABLE B_FROM_POSIX_ERROR(ERANGE)
#define B_DEVICE_NOT_FOUND B_FROM_POSIX_ERROR(ENODEV)
#define B_NOT_SUPPORTED B_FROM_POSIX_ERROR(EOPNOTSUPP)
/* Media Kit Errors */
#define B_STREAM_NOT_FOUND (B_MEDIA_ERROR_BASE + 0)
@@ -266,4 +281,20 @@
#define B_DEV_MULTIPLE_ERRORS (B_DEVICE_ERROR_BASE + 29)
#define B_DEV_TOO_LATE (B_DEVICE_ERROR_BASE + 30)
#define B_TO_POSITIVE_ERROR(error) _to_positive_error(error)
#define B_TO_NEGATIVE_ERROR(error) _to_negative_error(error)
#ifdef __cplusplus
extern "C" {
#endif
int _to_positive_error(int error);
int _to_negative_error(int error);
#ifdef __cplusplus
}
#endif
#endif /* _ERRORS_H */