diff --git a/headers/build/os/support/Errors.h b/headers/build/os/support/Errors.h index a07d8c1386..04d36b41ad 100644 --- a/headers/build/os/support/Errors.h +++ b/headers/build/os/support/Errors.h @@ -494,23 +494,44 @@ #define ENOEXEC HAIKU_ENOEXEC #define EPIPE HAIKU_EPIPE #define ENOATTR HAIKU_ENOATTR - - #undef errno - #define errno (*_haiku_build_errno()) #elif defined(HAIKU_HOST_PLATFORM_HAIKU) -# include <../os/support/Errors.h> +# include_next #endif // ! BUILDING_HAIKU_ERROR_MAPPER #ifdef __cplusplus extern "C" { #endif -extern int *_haiku_build_errno(); +extern const int _haiku_build_errno(); +extern void _haiku_build_set_errno(int error); extern int _haiku_to_host_error(int error); #ifdef __cplusplus -} +} // extern "C" + +struct BuildErrnoWrapper { + int operator=(int value) + { + _haiku_build_set_errno(value); + return value; + } + operator int() + { + return _haiku_build_errno(); + } +}; #endif +/* build-specific code */ +#ifndef BUILDING_HAIKU_ERROR_MAPPER +#undef errno +#ifndef __cplusplus +#define errno (_haiku_build_errno()) +#else +extern BuildErrnoWrapper build_errno; +#define errno build_errno +#endif +#endif // ! BUILDING_HAIKU_ERROR_MAPPER + #endif /* _BUILD_ERRORS_H */ diff --git a/src/build/libroot/errors.cpp b/src/build/libroot/errors.cpp index bd8aa7e299..245e4c46fb 100644 --- a/src/build/libroot/errors.cpp +++ b/src/build/libroot/errors.cpp @@ -183,34 +183,38 @@ _haiku_build_strerror(int errnum) return strerror(to_host_error(errnum)); } -// _haiku_build_errno -int * -_haiku_build_errno() -{ - static int previousErrno = 0; - static int localErrno = 0; - static int previousLocalErrno = 0; - - // If the localErrno has been changed and the real errno has not changed - // in the meantime, we update errno itself, so that the local update will - // be reflected. If errno has changed we always update localErrno. - int currentErrno = errno; - if (currentErrno == previousErrno) { - if (localErrno != previousLocalErrno) { - errno = previousErrno = to_host_error(localErrno); - previousLocalErrno = localErrno; - } - } else { - previousErrno = currentErrno; - previousLocalErrno = localErrno = to_haiku_error(errno); - } - - return &localErrno; -} - // _haiku_to_host_error int _haiku_to_host_error(int error) { return to_host_error(error); } + + +// #pragma mark - errno handling + + +BuildErrnoWrapper build_errno; +static int sPreviousErrno = 0; +static int sLocalErrno = 0; + + +const int +_haiku_build_errno() +{ + int currentErrno = errno; + if (currentErrno != sPreviousErrno) { + sPreviousErrno = currentErrno; + sLocalErrno = to_haiku_error(currentErrno); + } + + return sLocalErrno; +} + + +void +_haiku_build_set_errno(int error) +{ + sLocalErrno = error; + errno = sPreviousErrno = to_host_error(error); +}