safe_macros: add SAFE_STRTOUL

commit 586992b33b tried to set ULONG_MAX as SAFE_STRTOL upper bound,
but this would cause the new issue:

 [root@localhost hugeshmat]# ./hugeshmat01
 hugeshmat01    0  TINFO  :  set nr_hugepages to 128
 hugeshmat01    1  TBROK  :  converted value out of range (0 - -1) at mem.c:840
 hugeshmat01    2  TBROK  :  Remaining cases broken
 hugeshmat01    0  TINFO  :  set nr_hugepages to 0

the failure is because SAFE_STRTOL converts ULONG_MAX as long type, which
will change 'ULONG_MAX' as -1.

the patch add a new macro SAFE_STRTOUL, which is a safe mode of strtoul()

Signed-off-by: Zhouping Liu <zliu@redhat.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index 1b27835..b9802fc 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -363,3 +363,26 @@
 
 	return rval;
 }
+
+unsigned long safe_strtoul(const char *file, const int lineno, void (cleanup_fn)(void),
+	    char *str, unsigned long min, unsigned long max)
+{
+	unsigned long rval;
+	char *endptr;
+
+	errno = 0;
+	rval = strtoul(str, &endptr, 10);
+	if ((errno == ERANGE && rval == ULONG_MAX)
+		    || (errno != 0 && rval == 0))
+		tst_brkm(TBROK|TERRNO, cleanup_fn,
+			"strtol failed at %s:%d", file, lineno);
+	if (rval > max || rval < min)
+		tst_brkm(TBROK, cleanup_fn,
+			"converted value out of range (%lu - %lu at %s:%d",
+			min, max, file, lineno);
+	if (endptr == str || (*endptr != '\0' && *endptr != '\n'))
+		tst_brkm(TBROK, cleanup_fn,
+			"Invalid value: '%s' at %s:%d", str, file, lineno);
+
+	return rval;
+}