/* compat: Some compatibility functions and header inclusions. Basic standard C stuff, that may barely be above/around C89. The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX. It is envisioned to include this compat header instead of any of the "standard" headers, to catch compatibility issues. So, don't include stdlib.h or string.h ... include compat.h. copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1 see COPYING and AUTHORS files in distribution or http://mpg123.org initially written by Thomas Orgis */ #ifndef MPG123_COMPAT_H #define MPG123_COMPAT_H #include "config.h" #include "intsym.h" /* For --nagging compilation with -std=c89, we need to disable the inline keyword. */ #ifdef PLAIN_C89 #ifndef inline #define inline #endif #endif #include #ifdef HAVE_STDLIB_H /* realloc, size_t */ #include #endif #include #include #ifdef HAVE_SIGNAL_H #include #else #ifdef HAVE_SYS_SIGNAL_H #include #endif #endif #ifdef HAVE_UNISTD_H #include #endif /* Types, types, types. */ /* Do we actually need these two in addition to sys/types.h? As replacement? */ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif #ifdef HAVE_STDINT_H #include #endif /* We want SIZE_MAX, etc. */ #ifdef HAVE_LIMITS_H #include #endif #ifndef SIZE_MAX #define SIZE_MAX ((size_t)-1) #endif #ifndef ULONG_MAX #define ULONG_MAX ((unsigned long)-1) #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef OS2 #include #endif #ifdef HAVE_SYS_TIME_H #include #endif /* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h */ #ifdef HAVE_SYS_SELECT_H #include #endif /* compat_open makes little sense without */ #include /* To parse big numbers... */ #ifdef HAVE_ATOLL #define atobigint atoll #else #define atobigint atol #endif typedef unsigned char byte; #ifdef _MSC_VER typedef long ssize_t; #endif /* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */ void *safe_realloc(void *ptr, size_t size); #ifndef HAVE_STRERROR const char *strerror(int errnum); #endif /* Roll our own strdup() that does not depend on libc feature test macros and returns NULL on NULL input instead of crashing. */ char* compat_strdup(const char *s); /* If we have the size checks enabled, try to derive some sane printfs. Simple start: Use max integer type and format if long is not big enough. I am hesitating to use %ll without making sure that it's there... */ #if !(defined PLAIN_C89) && (defined SIZEOF_OFF_T) && (SIZEOF_OFF_T > SIZEOF_LONG) && (defined PRIiMAX) # define OFF_P PRIiMAX typedef intmax_t off_p; #else # define OFF_P "li" typedef long off_p; #endif #if !(defined PLAIN_C89) && (defined SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > SIZEOF_LONG) && (defined PRIuMAX) # define SIZE_P PRIuMAX typedef uintmax_t size_p; #else # define SIZE_P "lu" typedef unsigned long size_p; #endif #if !(defined PLAIN_C89) && (defined SIZEOF_SSIZE_T) && (SIZEOF_SSIZE_T > SIZEOF_LONG) && (defined PRIiMAX) # define SSIZE_P PRIuMAX typedef intmax_t ssize_p; #else # define SSIZE_P "li" typedef long ssize_p; #endif /** * Opening a file handle can be different. * This function here is defined to take a path in native encoding (ISO8859 / UTF-8 / ...), or, when MS Windows Unicode support is enabled, an UTF-8 string that will be converted back to native UCS-2 (wide character) before calling the system's open function. * @param[in] wptr Pointer to wide string. * @param[in] mbptr Pointer to multibyte string. * @return file descriptor (>=0) or error code. */ int compat_open(const char *filename, int flags); FILE* compat_fopen(const char *filename, const char *mode); /** * Also fdopen to avoid having to define POSIX macros in various source files. */ FILE* compat_fdopen(int fd, const char *mode); /** * Closing a file handle can be platform specific. * This function takes a file descriptor that is to be closed. * @param[in] infd File descriptor to be closed. * @return 0 if the file was successfully closed. A return value of -1 indicates an error. */ int compat_close(int infd); int compat_fclose(FILE* stream); /* Those do make sense in a separate file, but I chose to include them in compat.c because that's the one source whose object is shared between mpg123 and libmpg123 -- and both need the functionality internally. */ #ifdef WANT_WIN32_UNICODE /** * win32_uni2mbc * Converts a null terminated UCS-2 string to a multibyte (UTF-8) equivalent. * Caller is supposed to free allocated buffer. * @param[in] wptr Pointer to wide string. * @param[out] mbptr Pointer to multibyte string. * @param[out] buflen Optional parameter for length of allocated buffer. * @return status of WideCharToMultiByte conversion. * * WideCharToMultiByte - http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspx */ int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen); /** * win32_mbc2uni * Converts a null terminated UTF-8 string to a UCS-2 equivalent. * Caller is supposed to free allocated buffer. * @param[out] mbptr Pointer to multibyte string. * @param[in] wptr Pointer to wide string. * @param[out] buflen Optional parameter for length of allocated buffer. * @return status of WideCharToMultiByte conversion. * * MultiByteToWideChar - http://msdn.microsoft.com/en-us/library/dd319072(VS.85).aspx */ int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen); #endif /* Blocking write/read of data with signal resilience. Both continue after being interrupted by signals and always return the amount of processed data (shortage indicating actual problem or EOF). */ size_t unintr_write(int fd, void const *buffer, size_t bytes); size_t unintr_read (int fd, void *buffer, size_t bytes); /* That one comes from Tellie on OS/2, needed in resolver. */ #ifdef __KLIBC__ typedef int socklen_t; #endif /* OSX SDK defines an enum with "normal" as value. That clashes with optimize.h */ #ifdef __APPLE__ #define normal mpg123_normal #endif #include "true.h" #if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H) void (*catchsignal(int signum, void(*handler)()))(); #endif #endif