xref: /memcached-1.4.29/util.c (revision 51c8f31f)
1891082f3SDustin Sallings #include <stdio.h>
2420aa2d9SBrad Fitzpatrick #include <assert.h>
3674166c0SBrad Fitzpatrick #include <ctype.h>
4674166c0SBrad Fitzpatrick #include <errno.h>
5674166c0SBrad Fitzpatrick #include <string.h>
6674166c0SBrad Fitzpatrick #include <stdlib.h>
7891082f3SDustin Sallings #include <stdarg.h>
8420aa2d9SBrad Fitzpatrick 
9420aa2d9SBrad Fitzpatrick #include "memcached.h"
10420aa2d9SBrad Fitzpatrick 
1139f6eeb3SPaul Lindner /* Avoid warnings on solaris, where isspace() is an index into an array, and gcc uses signed chars */
1239f6eeb3SPaul Lindner #define xisspace(c) isspace((unsigned char)c)
1339f6eeb3SPaul Lindner 
safe_strtoull(const char * str,uint64_t * out)14a977b556SDustin Sallings bool safe_strtoull(const char *str, uint64_t *out) {
15420aa2d9SBrad Fitzpatrick     assert(out != NULL);
16674166c0SBrad Fitzpatrick     errno = 0;
17420aa2d9SBrad Fitzpatrick     *out = 0;
18420aa2d9SBrad Fitzpatrick     char *endptr;
19420aa2d9SBrad Fitzpatrick     unsigned long long ull = strtoull(str, &endptr, 10);
20*51c8f31fSTrond Norbye     if ((errno == ERANGE) || (str == endptr)) {
21674166c0SBrad Fitzpatrick         return false;
22*51c8f31fSTrond Norbye     }
23*51c8f31fSTrond Norbye 
2439f6eeb3SPaul Lindner     if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
25674166c0SBrad Fitzpatrick         if ((long long) ull < 0) {
267659ae1cSDustin Sallings             /* only check for negative signs in the uncommon case when
277659ae1cSDustin Sallings              * the unsigned number is so big that it's negative as a
287659ae1cSDustin Sallings              * signed number. */
29674166c0SBrad Fitzpatrick             if (strchr(str, '-') != NULL) {
30674166c0SBrad Fitzpatrick                 return false;
31674166c0SBrad Fitzpatrick             }
32674166c0SBrad Fitzpatrick         }
33420aa2d9SBrad Fitzpatrick         *out = ull;
34420aa2d9SBrad Fitzpatrick         return true;
35420aa2d9SBrad Fitzpatrick     }
36420aa2d9SBrad Fitzpatrick     return false;
37420aa2d9SBrad Fitzpatrick }
38674166c0SBrad Fitzpatrick 
safe_strtoll(const char * str,int64_t * out)39a977b556SDustin Sallings bool safe_strtoll(const char *str, int64_t *out) {
40674166c0SBrad Fitzpatrick     assert(out != NULL);
41674166c0SBrad Fitzpatrick     errno = 0;
42674166c0SBrad Fitzpatrick     *out = 0;
43674166c0SBrad Fitzpatrick     char *endptr;
44674166c0SBrad Fitzpatrick     long long ll = strtoll(str, &endptr, 10);
45*51c8f31fSTrond Norbye     if ((errno == ERANGE) || (str == endptr)) {
46674166c0SBrad Fitzpatrick         return false;
47*51c8f31fSTrond Norbye     }
48*51c8f31fSTrond Norbye 
4939f6eeb3SPaul Lindner     if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
50674166c0SBrad Fitzpatrick         *out = ll;
51674166c0SBrad Fitzpatrick         return true;
52674166c0SBrad Fitzpatrick     }
53674166c0SBrad Fitzpatrick     return false;
54674166c0SBrad Fitzpatrick }
5563ba0e14SDustin Sallings 
safe_strtoul(const char * str,uint32_t * out)5663ba0e14SDustin Sallings bool safe_strtoul(const char *str, uint32_t *out) {
5763ba0e14SDustin Sallings     char *endptr = NULL;
5863ba0e14SDustin Sallings     unsigned long l = 0;
5963ba0e14SDustin Sallings     assert(out);
6063ba0e14SDustin Sallings     assert(str);
6163ba0e14SDustin Sallings     *out = 0;
6263ba0e14SDustin Sallings     errno = 0;
6363ba0e14SDustin Sallings 
6463ba0e14SDustin Sallings     l = strtoul(str, &endptr, 10);
65*51c8f31fSTrond Norbye     if ((errno == ERANGE) || (str == endptr)) {
6663ba0e14SDustin Sallings         return false;
6763ba0e14SDustin Sallings     }
6863ba0e14SDustin Sallings 
6939f6eeb3SPaul Lindner     if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
7063ba0e14SDustin Sallings         if ((long) l < 0) {
7163ba0e14SDustin Sallings             /* only check for negative signs in the uncommon case when
7263ba0e14SDustin Sallings              * the unsigned number is so big that it's negative as a
7363ba0e14SDustin Sallings              * signed number. */
7463ba0e14SDustin Sallings             if (strchr(str, '-') != NULL) {
7563ba0e14SDustin Sallings                 return false;
7663ba0e14SDustin Sallings             }
7763ba0e14SDustin Sallings         }
7863ba0e14SDustin Sallings         *out = l;
7963ba0e14SDustin Sallings         return true;
8063ba0e14SDustin Sallings     }
8163ba0e14SDustin Sallings 
8263ba0e14SDustin Sallings     return false;
8363ba0e14SDustin Sallings }
8463ba0e14SDustin Sallings 
safe_strtol(const char * str,int32_t * out)8563ba0e14SDustin Sallings bool safe_strtol(const char *str, int32_t *out) {
8663ba0e14SDustin Sallings     assert(out != NULL);
8763ba0e14SDustin Sallings     errno = 0;
8863ba0e14SDustin Sallings     *out = 0;
8963ba0e14SDustin Sallings     char *endptr;
9063ba0e14SDustin Sallings     long l = strtol(str, &endptr, 10);
91*51c8f31fSTrond Norbye     if ((errno == ERANGE) || (str == endptr)) {
9263ba0e14SDustin Sallings         return false;
93*51c8f31fSTrond Norbye     }
94*51c8f31fSTrond Norbye 
9539f6eeb3SPaul Lindner     if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
9663ba0e14SDustin Sallings         *out = l;
9763ba0e14SDustin Sallings         return true;
9863ba0e14SDustin Sallings     }
9963ba0e14SDustin Sallings     return false;
10063ba0e14SDustin Sallings }
101891082f3SDustin Sallings 
vperror(const char * fmt,...)102891082f3SDustin Sallings void vperror(const char *fmt, ...) {
103891082f3SDustin Sallings     int old_errno = errno;
1047fc4fcc9STrond Norbye     char buf[1024];
105891082f3SDustin Sallings     va_list ap;
106891082f3SDustin Sallings 
107891082f3SDustin Sallings     va_start(ap, fmt);
1087fc4fcc9STrond Norbye     if (vsnprintf(buf, sizeof(buf), fmt, ap) == -1) {
1097fc4fcc9STrond Norbye         buf[sizeof(buf) - 1] = '\0';
1107fc4fcc9STrond Norbye     }
111891082f3SDustin Sallings     va_end(ap);
112891082f3SDustin Sallings 
113891082f3SDustin Sallings     errno = old_errno;
114891082f3SDustin Sallings 
115891082f3SDustin Sallings     perror(buf);
116891082f3SDustin Sallings }
1179791b779STrond Norbye 
1189791b779STrond Norbye #ifndef HAVE_HTONLL
mc_swap64(uint64_t in)1199791b779STrond Norbye static uint64_t mc_swap64(uint64_t in) {
1209791b779STrond Norbye #ifdef ENDIAN_LITTLE
1219791b779STrond Norbye     /* Little endian, flip the bytes around until someone makes a faster/better
1229791b779STrond Norbye     * way to do this. */
1239791b779STrond Norbye     int64_t rv = 0;
1249791b779STrond Norbye     int i = 0;
1259791b779STrond Norbye      for(i = 0; i<8; i++) {
1269791b779STrond Norbye         rv = (rv << 8) | (in & 0xff);
1279791b779STrond Norbye         in >>= 8;
1289791b779STrond Norbye      }
1299791b779STrond Norbye     return rv;
1309791b779STrond Norbye #else
1319791b779STrond Norbye     /* big-endian machines don't need byte swapping */
1329791b779STrond Norbye     return in;
1339791b779STrond Norbye #endif
1349791b779STrond Norbye }
1359791b779STrond Norbye 
ntohll(uint64_t val)1369791b779STrond Norbye uint64_t ntohll(uint64_t val) {
1379791b779STrond Norbye    return mc_swap64(val);
1389791b779STrond Norbye }
1399791b779STrond Norbye 
htonll(uint64_t val)1409791b779STrond Norbye uint64_t htonll(uint64_t val) {
1419791b779STrond Norbye    return mc_swap64(val);
1429791b779STrond Norbye }
1439791b779STrond Norbye #endif
1449791b779STrond Norbye 
145