Add more compat code for non GNU environments
[oweals/busybox.git] / libbb / platform.c
1 /*
2  * Replacements for common but usually nonstandard functions that aren't
3  * supplied by all platforms.
4  *
5  * Copyright (C) 2009 by Dan Fandrich <dan@coneharvesters.com>, et. al.
6  *
7  * Licensed under the GPL version 2, see the file LICENSE in this tarball.
8  */
9 #include "libbb.h"
10
11 #ifndef HAVE_STRCHRNUL
12 char* FAST_FUNC strchrnul(const char *s, int c)
13 {
14         while (*s != '\0' && *s != c)
15                 s++;
16         return (char*)s;
17 }
18 #endif
19
20 #ifndef HAVE_VASPRINTF
21 int FAST_FUNC vasprintf(char **string_ptr, const char *format, va_list p)
22 {
23         int r;
24         va_list p2;
25         char buf[128];
26
27         va_copy(p2, p);
28         r = vsnprintf(buf, 128, format, p);
29         va_end(p);
30
31         if (r < 128) {
32                 va_end(p2);
33                 return xstrdup(buf);
34         }
35
36         *string_ptr = xmalloc(r+1);
37         r = vsnprintf(*string_ptr, r+1, format, p2);
38         va_end(p2);
39
40         return r;
41 }
42 #endif
43
44 #ifndef HAVE_FDPRINTF
45 /* dprintf is now actually part of POSIX.1, but was only added in 2008 */
46 int fdprintf(int fd, const char *format, ...)
47 {
48         va_list p;
49         int r;
50         char *string_ptr;
51
52         va_start(p, format);
53         r = vasprintf(&string_ptr, format, p);
54         va_end(p);
55         if (r >= 0) {
56                 r = full_write(fd, string_ptr, r);
57                 free(string_ptr);
58         }
59         return r;
60 }
61 #endif
62
63 #ifndef HAVE_MEMRCHR
64 /* Copyright (C) 2005 Free Software Foundation, Inc.
65  * memrchr() is a GNU function that might not be available everywhere.
66  * It's basically the inverse of memchr() - search backwards in a
67  * memory block for a particular character.
68  */
69 void* FAST_FUNC memrchr(const void *s, int c, size_t n)
70 {
71         const char *start = s, *end = s;
72
73         end += n - 1;
74
75         while (end >= start) {
76                 if (*end == (char)c)
77                         return (void *) end;
78                 end--;
79         }
80
81         return NULL;
82 }
83 #endif
84
85 #ifndef HAVE_MKDTEMP
86 /* This is now actually part of POSIX.1, but was only added in 2008 */
87 char* FAST_FUNC mkdtemp(char *template)
88 {
89         if (mktemp(template) == NULL || mkdir(template, 0700) != 0)
90                 return NULL;
91         return template;
92 }
93 #endif
94
95 #ifndef HAVE_STRCASESTR
96 /* Copyright (c) 1999, 2000 The ht://Dig Group */
97 char* FAST_FUNC strcasestr(const char *s, const char *pattern)
98 {
99         int length = strlen(pattern);
100
101         while (*s) {
102                 if (strncasecmp(s, pattern, length) == 0)
103                         return (char *)s;
104                 s++;
105         }
106         return 0;
107 }
108 #endif