ReactOS  0.4.15-dev-1049-g1062a29
compat.h
Go to the documentation of this file.
1 /*
2  compat: Some compatibility functions and header inclusions.
3  Basic standard C stuff, that may barely be above/around C89.
4 
5  The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
6  It is envisioned to include this compat header instead of any of the "standard" headers, to catch compatibility issues.
7  So, don't include stdlib.h or string.h ... include compat.h.
8 
9  copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
10  see COPYING and AUTHORS files in distribution or http://mpg123.org
11  initially written by Thomas Orgis
12 */
13 
14 #ifndef MPG123_COMPAT_H
15 #define MPG123_COMPAT_H
16 
17 #include "config.h"
18 #include "intsym.h"
19 
20 /* Disable inline for non-C99 compilers. */
21 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
22 #ifndef inline
23 #define inline
24 #endif
25 #endif
26 
27 #include <errno.h>
28 
29 #ifdef HAVE_STDLIB_H
30 /* realloc, size_t */
31 #include <stdlib.h>
32 #endif
33 
34 #include <stdio.h>
35 #include <math.h>
36 
37 #ifdef HAVE_SIGNAL_H
38 #include <signal.h>
39 #else
40 #ifdef HAVE_SYS_SIGNAL_H
41 #include <sys/signal.h>
42 #endif
43 #endif
44 
45 #ifdef HAVE_UNISTD_H
46 #include <unistd.h>
47 #endif
48 
49 /* Types, types, types. */
50 /* Do we actually need these two in addition to sys/types.h? As replacement? */
51 #ifdef HAVE_SYS_TYPES_H
52 #include <sys/types.h>
53 #endif
54 #ifdef HAVE_INTTYPES_H
55 #include <inttypes.h>
56 #endif
57 #ifdef HAVE_STDINT_H
58 #include <stdint.h>
59 #endif
60 /* We want SIZE_MAX, etc. */
61 #ifdef HAVE_LIMITS_H
62 #include <limits.h>
63 #endif
64 
65 #ifndef SIZE_MAX
66 #define SIZE_MAX ((size_t)-1)
67 #endif
68 #ifndef SSIZE_MAX
69 #define SSIZE_MAX ((size_t)-1/2)
70 #endif
71 #ifndef ULONG_MAX
72 #define ULONG_MAX ((unsigned long)-1)
73 #endif
74 
75 #ifdef HAVE_STRING_H
76 #include <string.h>
77 #endif
78 #ifdef HAVE_STRINGS_H
79 #include <strings.h>
80 #endif
81 
82 #ifdef OS2
83 #include <float.h>
84 #endif
85 
86 #ifdef HAVE_SYS_TIME_H
87 #include <sys/time.h>
88 #endif
89 /* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h */
90 #ifdef HAVE_SYS_SELECT_H
91 #include <sys/select.h>
92 #endif
93 
94 /* compat_open makes little sense without */
95 #include <fcntl.h>
96 
97 /* To parse big numbers... */
98 #ifdef HAVE_ATOLL
99 #define atobigint atoll
100 #else
101 #define atobigint atol
102 #endif
103 
104 typedef unsigned char byte;
105 
106 #ifndef __REACTOS__
107 #if defined(_MSC_VER) && !defined(MPG123_DEF_SSIZE_T)
108 #define MPG123_DEF_SSIZE_T
109 #include <stddef.h>
110 typedef ptrdiff_t ssize_t;
111 #endif
112 #endif /* __REACTOS__ */
113 
114 /* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
115 void *safe_realloc(void *ptr, size_t size);
116 #ifndef HAVE_STRERROR
117 const char *strerror(int errnum);
118 #endif
119 
120 /* Roll our own strdup() that does not depend on libc feature test macros
121  and returns NULL on NULL input instead of crashing. */
122 char* compat_strdup(const char *s);
123 
124 /* If we have the size checks enabled, try to derive some sane printfs.
125  Simple start: Use max integer type and format if long is not big enough.
126  I am hesitating to use %ll without making sure that it's there... */
127 #if (defined SIZEOF_OFF_T) && (SIZEOF_OFF_T > SIZEOF_LONG) && (defined PRIiMAX)
128 # define OFF_P PRIiMAX
129 typedef intmax_t off_p;
130 #else
131 # define OFF_P "li"
132 typedef long off_p;
133 #endif
134 
135 #if (defined SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > SIZEOF_LONG) && (defined PRIuMAX)
136 # define SIZE_P PRIuMAX
137 typedef uintmax_t size_p;
138 #else
139 # define SIZE_P "lu"
140 typedef unsigned long size_p;
141 #endif
142 
143 #if (defined SIZEOF_SSIZE_T) && (SIZEOF_SSIZE_T > SIZEOF_LONG) && (defined PRIiMAX)
144 # define SSIZE_P PRIuMAX
145 typedef intmax_t ssize_p;
146 #else
147 # define SSIZE_P "li"
148 typedef long ssize_p;
149 #endif
150 
151 /* Get an environment variable, possibly converted to UTF-8 from wide string.
152  The return value is a copy that you shall free. */
153 char *compat_getenv(const char* name);
154 
162 int compat_open(const char *filename, int flags);
163 FILE* compat_fopen(const char *filename, const char *mode);
167 FILE* compat_fdopen(int fd, const char *mode);
168 
175 int compat_close(int infd);
177 
178 /* 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. */
179 
180 #ifdef WANT_WIN32_UNICODE
181 
192 int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen);
193 
206 int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen);
207 #endif
208 
209 /*
210  A little bit of path abstraction: We always work with plain char strings
211  that usually represent POSIX-ish UTF-8 paths (something like c:/some/file
212  might appear). For Windows, those are converted to wide strings with \
213  instead of / and possible fun is had with prefixes to get around the old
214  path length limit. Outside of the compat library, that stuff should not
215  matter, although something like //?/UNC/server/some/file could be thrown
216  around as UTF-8 string, to be converted to a wide \\?\UNC\server\some\file
217  just before handing it to Windows API.
218 
219  There is a lot of unnecessary memory allocation and string copying because
220  of this, but this filesystem stuff is not really relevant to mpg123
221  performance, so the goal is to keep the code outside the compatibility layer
222  simple.
223 */
224 
225 /*
226  Concatenate a prefix and a path, one of them alowed to be NULL.
227  If the path is already absolute, the prefix is ignored. Relative
228  parts (like /..) are resolved if this is sensible for the platform
229  (meaning: for Windows), else they are preserved (on POSIX, actual
230  file system access would be needed because of symlinks).
231 */
232 char* compat_catpath(const char *prefix, const char* path);
233 
234 /* Return 1 if the given path indicates an existing directory,
235  0 otherwise. */
236 int compat_isdir(const char *path);
237 
238 /*
239  Directory traversal. This talks ASCII/UTF-8 paths externally, converts
240  to/from wchar_t internally if the platform wants that. Returning NULL
241  means failure to open/end of listing.
242  There is no promise about sorting entries.
243 */
244 struct compat_dir;
245 /* Returns NULL if either directory failed to open or listing is empty.
246  Listing can still be empty even if non-NULL, so always rely on the
247  nextfile/nextdir functions. */
248 struct compat_dir* compat_diropen(char *path);
249 void compat_dirclose(struct compat_dir*);
250 /* Get the next entry that is a file (or symlink to one).
251  The returned string is a copy that needs to be freed after use. */
252 char* compat_nextfile(struct compat_dir*);
253 /* Get the next entry that is a directory (or symlink to one).
254  The returned string is a copy that needs to be freed after use. */
255 char* compat_nextdir (struct compat_dir*);
256 
257 #ifdef USE_MODULES
258 /*
259  For keeping the path mess local, a system-specific dlopen() variant
260  is contained in here, too. This is very thin wrapping, even sparing
261  definition of a handle type, just using void pointers.
262  Use of absolute paths is a good idea if you want to be sure which
263  file is openend, as default search paths vary.
264 */
265 void *compat_dlopen (const char *path);
266 void *compat_dlsym (void *handle, const char* name);
267 void compat_dlclose(void *handle);
268 #endif
269 
270 /* Blocking write/read of data with signal resilience.
271  They continue after being interrupted by signals and always return the
272  amount of processed data (shortage indicating actual problem or EOF). */
273 size_t unintr_write(int fd, void const *buffer, size_t bytes);
274 size_t unintr_read (int fd, void *buffer, size_t bytes);
275 size_t unintr_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
276 
277 /* That one comes from Tellie on OS/2, needed in resolver. */
278 #ifdef __KLIBC__
279 typedef int socklen_t;
280 #endif
281 
282 /* OSX SDK defines an enum with "normal" as value. That clashes with
283  optimize.h */
284 #ifdef __APPLE__
285 #define normal mpg123_normal
286 #endif
287 
288 #include "true.h"
289 
290 #if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
291 void (*catchsignal(int signum, void(*handler)()))();
292 #endif
293 
294 #endif
int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen)
FILE * compat_fopen(const char *filename, const char *mode)
Definition: compat.c:218
int compat_open(const char *filename, int flags)
Definition: compat.c:181
int compat_isdir(const char *path)
Definition: compat.c:395
char * compat_getenv(const char *name)
Definition: compat.c:52
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
size_t unintr_read(int fd, void *buffer, size_t bytes)
Definition: compat.c:631
GLuint buffer
Definition: glext.h:5915
static int fd
Definition: io.c:51
#define ssize_t
Definition: config.h:517
const char * filename
Definition: ioapi.h:135
const char * strerror(int err)
Definition: compat_str.c:23
char * compat_nextdir(struct compat_dir *)
Definition: compat.c:529
FILE * compat_fdopen(int fd, const char *mode)
Definition: compat.c:248
char * compat_catpath(const char *prefix, const char *path)
Definition: compat.c:324
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
__MINGW_EXTENSION typedef long long intmax_t
Definition: stdint.h:68
static PVOID ptr
Definition: dispmode.c:27
int compat_close(int infd)
Definition: compat.c:253
unsigned long size_p
Definition: compat.h:140
GLsizeiptr size
Definition: glext.h:5919
void compat_dirclose(struct compat_dir *)
Definition: compat.c:481
char * compat_nextfile(struct compat_dir *)
Definition: compat.c:495
__MINGW_EXTENSION typedef unsigned long long uintmax_t
Definition: stdint.h:69
int socklen_t
Definition: tcp.c:35
GLbitfield flags
Definition: glext.h:7161
#define compat_dlclose
Definition: intsym.h:28
struct compat_dir * compat_diropen(char *path)
Definition: compat.c:431
#define compat_dlopen
Definition: intsym.h:26
Definition: parse.h:22
GLdouble s
Definition: gl.h:2039
int compat_fclose(FILE *stream)
Definition: compat.c:262
GLenum mode
Definition: glext.h:6217
#define compat_dlsym
Definition: intsym.h:27
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
size_t unintr_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
long off_p
Definition: compat.h:132
char * compat_strdup(const char *s)
Definition: compat_str.c:32
Definition: name.c:38
unsigned char byte
Definition: compat.h:104
void * safe_realloc(void *ptr, size_t size)
Definition: compat_str.c:16
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7786
int win32_wide_utf8(const wchar_t *const wptr, char **mbptr, size_t *buflen)
long ssize_p
Definition: compat.h:148
size_t unintr_write(int fd, void const *buffer, size_t bytes)
Definition: compat.c:616
void(*)() catchsignal(int signum, void(*handler)())
Definition: compat.h:291