1 : // Copyright (c) 2009, Google Inc.
2 : // All rights reserved.
3 : //
4 : // Redistribution and use in source and binary forms, with or without
5 : // modification, are permitted provided that the following conditions are
6 : // met:
7 : //
8 : // * Redistributions of source code must retain the above copyright
9 : // notice, this list of conditions and the following disclaimer.
10 : // * Redistributions in binary form must reproduce the above
11 : // copyright notice, this list of conditions and the following disclaimer
12 : // in the documentation and/or other materials provided with the
13 : // distribution.
14 : // * Neither the name of Google Inc. nor the names of its
15 : // contributors may be used to endorse or promote products derived from
16 : // this software without specific prior written permission.
17 : //
18 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 :
30 : // This header provides replacements for libc functions that we need. We if
31 : // call the libc functions directly we risk crashing in the dynamic linker as
32 : // it tries to resolve uncached PLT entries.
33 :
34 : #ifndef CLIENT_LINUX_LINUX_LIBC_SUPPORT_H_
35 : #define CLIENT_LINUX_LINUX_LIBC_SUPPORT_H_
36 :
37 : #include <stdint.h>
38 : #include <limits.h>
39 : #include <sys/types.h>
40 :
41 : extern "C" {
42 :
43 : static inline size_t
44 124 : my_strlen(const char* s) {
45 124 : size_t len = 0;
46 124 : while (*s++) len++;
47 124 : return len;
48 : }
49 :
50 : static inline int
51 0 : my_strcmp(const char* a, const char* b) {
52 0 : for (;;) {
53 0 : if (*a < *b)
54 0 : return -1;
55 0 : else if (*a > *b)
56 0 : return 1;
57 0 : else if (*a == 0)
58 0 : return 0;
59 0 : a++;
60 0 : b++;
61 : }
62 : }
63 :
64 : static inline int
65 730 : my_strncmp(const char* a, const char* b, size_t len) {
66 2700 : for (size_t i = 0; i < len; ++i) {
67 2328 : if (*a < *b)
68 358 : return -1;
69 1970 : else if (*a > *b)
70 0 : return 1;
71 1970 : else if (*a == 0)
72 0 : return 0;
73 1970 : a++;
74 1970 : b++;
75 : }
76 :
77 372 : return 0;
78 : }
79 :
80 : // Parse a non-negative integer.
81 : // result: (output) the resulting non-negative integer
82 : // s: a NUL terminated string
83 : // Return true iff successful.
84 : static inline bool
85 0 : my_strtoui(int* result, const char* s) {
86 0 : if (*s == 0)
87 0 : return false;
88 0 : int r = 0;
89 0 : for (;; s++) {
90 0 : if (*s == 0)
91 : break;
92 0 : const int old_r = r;
93 0 : r *= 10;
94 0 : if (*s < '0' || *s > '9')
95 0 : return false;
96 0 : r += *s - '0';
97 0 : if (r < old_r)
98 0 : return false;
99 : }
100 :
101 0 : *result = r;
102 0 : return true;
103 : }
104 :
105 : // Return the length of the given, non-negative integer when expressed in base
106 : // 10.
107 : static inline unsigned
108 1408 : my_int_len(intmax_t i) {
109 1408 : if (!i)
110 0 : return 1;
111 :
112 1408 : int len = 0;
113 16896 : while (i) {
114 14080 : len++;
115 14080 : i /= 10;
116 : }
117 :
118 1408 : return len;
119 : }
120 :
121 : // Convert a non-negative integer to a string
122 : // output: (output) the resulting string is written here. This buffer must be
123 : // large enough to hold the resulting string. Call |my_int_len| to get the
124 : // required length.
125 : // i: the non-negative integer to serialise.
126 : // i_len: the length of the integer in base 10 (see |my_int_len|).
127 : static inline void
128 1408 : my_itos(char* output, intmax_t i, unsigned i_len) {
129 15488 : for (unsigned index = i_len; index; --index, i /= 10)
130 14080 : output[index - 1] = '0' + (i % 10);
131 1408 : }
132 :
133 : static inline const char*
134 0 : my_strchr(const char* haystack, char needle) {
135 0 : while (*haystack && *haystack != needle)
136 0 : haystack++;
137 0 : if (*haystack == needle)
138 0 : return haystack;
139 0 : return (const char*) 0;
140 : }
141 :
142 : // Read a hex value
143 : // result: (output) the resulting value
144 : // s: a string
145 : // Returns a pointer to the first invalid charactor.
146 : static inline const char*
147 0 : my_read_hex_ptr(uintptr_t* result, const char* s) {
148 0 : uintptr_t r = 0;
149 :
150 0 : for (;; ++s) {
151 0 : if (*s >= '0' && *s <= '9') {
152 0 : r <<= 4;
153 0 : r += *s - '0';
154 0 : } else if (*s >= 'a' && *s <= 'f') {
155 0 : r <<= 4;
156 0 : r += (*s - 'a') + 10;
157 0 : } else if (*s >= 'A' && *s <= 'F') {
158 0 : r <<= 4;
159 0 : r += (*s - 'A') + 10;
160 : } else {
161 : break;
162 : }
163 : }
164 :
165 0 : *result = r;
166 0 : return s;
167 : }
168 :
169 : static inline void
170 1532 : my_memset(void* ip, char c, size_t len) {
171 1532 : char* p = (char *) ip;
172 50104 : while (len--)
173 47040 : *p++ = c;
174 1532 : }
175 :
176 : } // extern "C"
177 :
178 : #endif // CLIENT_LINUX_LINUX_LIBC_SUPPORT_H_
|