summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMatthieu Patou <mat@matws.net>2010-10-21 00:13:54 +0400
committerMatthieu Patou <mat@matws.net>2010-10-22 01:00:53 +0400
commit2d0ac59fcc490517b202180f49b178ab80c2534e (patch)
tree8d4ea0c932fec9cb4ab88b4586e54513e596cee9 /lib
parentc529317fe2b48e045b35a613cfd1ad3f03b68435 (diff)
downloadsamba-2d0ac59fcc490517b202180f49b178ab80c2534e.tar.gz
samba-2d0ac59fcc490517b202180f49b178ab80c2534e.tar.bz2
samba-2d0ac59fcc490517b202180f49b178ab80c2534e.zip
replace: use a wrapper around strtoll if it didn't behave as expected
Diffstat (limited to 'lib')
-rw-r--r--lib/replace/replace.c50
-rw-r--r--lib/replace/replace.h12
-rw-r--r--lib/replace/wscript17
3 files changed, 77 insertions, 2 deletions
diff --git a/lib/replace/replace.c b/lib/replace/replace.c
index a00f7053e2..5ecda9226f 100644
--- a/lib/replace/replace.c
+++ b/lib/replace/replace.c
@@ -3,6 +3,7 @@
replacement routines for broken systems
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jelmer Vernooij 2005-2008
+ Copyright (C) Matthieu Patou 2010
** NOTE! The following LGPL license applies to the replace
** library. This does NOT imply that all of Samba is released
@@ -502,6 +503,7 @@ char *rep_strtok_r(char *s, const char *delim, char **save_ptr)
}
#endif
+
#ifndef HAVE_STRTOLL
long long int rep_strtoll(const char *str, char **endptr, int base)
{
@@ -515,7 +517,29 @@ long long int rep_strtoll(const char *str, char **endptr, int base)
# error "You need a strtoll function"
#endif
}
-#endif
+#else
+#ifdef HAVE_BSD_STRTOLL
+#ifdef HAVE_STRTOQ
+long long int rep_strtoll(const char *str, char **endptr, int base)
+{
+ long long int nb = strtoq(str, endptr, base);
+ /* In linux EINVAL is only returned if base is not ok */
+ if (errno == EINVAL) {
+ if (base == 0 || (base >1 && base <37)) {
+ /* Base was ok so it's because we were not
+ * able to make the convertion.
+ * Let's reset errno.
+ */
+ errno = 0;
+ }
+ }
+ return nb;
+}
+#else
+#error "You need the strtoq function"
+#endif /* HAVE_STRTOQ */
+#endif /* HAVE_BSD_STRTOLL */
+#endif /* HAVE_STRTOLL */
#ifndef HAVE_STRTOULL
@@ -531,7 +555,29 @@ unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
# error "You need a strtoull function"
#endif
}
-#endif
+#else
+#ifdef HAVE_BSD_STRTOLL
+#ifdef HAVE_STRTOUQ
+long long int rep_strtoull(const char *str, char **endptr, int base)
+{
+ unsigned long long int nb = strtouq(str, endptr, base);
+ /* In linux EINVAL is only returned if base is not ok */
+ if (errno == EINVAL) {
+ if (base == 0 || (base >1 && base <37)) {
+ /* Base was ok so it's because we were not
+ * able to make the convertion.
+ * Let's reset errno.
+ */
+ errno = 0;
+ }
+ }
+ return nb;
+}
+#else
+#error "You need the strtouq function"
+#endif /* HAVE_STRTOUQ */
+#endif /* HAVE_BSD_STRTOLL */
+#endif /* HAVE_STRTOULL */
#ifndef HAVE_SETENV
int rep_setenv(const char *name, const char *value, int overwrite)
diff --git a/lib/replace/replace.h b/lib/replace/replace.h
index 10c7ee701c..8f820a949c 100644
--- a/lib/replace/replace.h
+++ b/lib/replace/replace.h
@@ -283,14 +283,26 @@ char *rep_strcasestr(const char *haystack, const char *needle);
char *rep_strtok_r(char *s, const char *delim, char **save_ptr);
#endif
+
+
#ifndef HAVE_STRTOLL
+long long int rep_strtoll(const char *str, char **endptr, int base);
#define strtoll rep_strtoll
+#else
+#ifdef HAVE_BSD_STRTOLL
long long int rep_strtoll(const char *str, char **endptr, int base);
+#define strtoll rep_strtoll
+#endif
#endif
#ifndef HAVE_STRTOULL
#define strtoull rep_strtoull
unsigned long long int rep_strtoull(const char *str, char **endptr, int base);
+#else
+#ifdef HAVE_BSD_STRTOLL
+long long int rep_strtoull(const char *str, char **endptr, int base);
+#define strtoull rep_strtoull
+#endif
#endif
#ifndef HAVE_FTRUNCATE
diff --git a/lib/replace/wscript b/lib/replace/wscript
index 48871d6442..1778ea71b0 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -160,6 +160,23 @@ def configure(conf):
conf.CHECK_FUNCS('link readlink symlink realpath snprintf vsnprintf')
conf.CHECK_FUNCS('asprintf vasprintf setenv unsetenv strnlen strtoull __strtoull')
conf.CHECK_FUNCS('strtouq strtoll __strtoll strtoq')
+ #Some OS (ie. freebsd) return EINVAL if the convertion could not be done, it's not what we expect
+ #Let's detect those cases
+ if conf.CONFIG_SET('HAVE_STRTOLL'):
+ conf.CHECK_CODE('''
+ long long nb = strtoll("Text", NULL, 0);
+ if (errno == EINVAL) {
+ return 0;
+ } else {
+ return 1;
+ }
+ ''',
+ msg="Checking correct behavior of strtoll",
+ headers = 'errno.h',
+ execute = True,
+ define_ret = True,
+ define = 'HAVE_BSD_STRTOLL',
+ )
conf.CHECK_FUNCS('if_nametoindex strerror_r')
conf.CHECK_FUNCS('getdirentries getdents syslog')
conf.CHECK_FUNCS('gai_strerror get_current_dir_name')