lib/safe_macros: Split and add SAFE_ASPRINTF()

Split the safe macros into safe_macros.h and safe_stdio.h as the safe
macros header started to be too big. There is also second reason for the
split, as asprintf() requires _GNU_SOURCE defined so this helps keep the
definition only inside of the safe_stdio.c file which affects only
functions in the file and has easily foreseeable effects.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
diff --git a/include/safe_file_ops.h b/include/safe_file_ops.h
index ad1eec8..7ff5baa 100644
--- a/include/safe_file_ops.h
+++ b/include/safe_file_ops.h
@@ -22,10 +22,10 @@
  */
 
  /*
-  
+
    This code helps with file reading/writing files providing scanf/printf like
    interface that opens and closes the file automatically.
-   
+
    This kind of interface is especially useful for reading/writing values
    from/to pseudo filesystems like procfs or sysfs.
 
diff --git a/include/safe_macros.h b/include/safe_macros.h
index 3a26df6..adf4d09 100644
--- a/include/safe_macros.h
+++ b/include/safe_macros.h
@@ -23,7 +23,8 @@
 #include <libgen.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <stdio.h>
+
+#include "safe_stdio.h"
 
 char*	safe_basename(const char *file, const int lineno,
 	    void (*cleanup_fn)(void), char *path);
@@ -174,15 +175,5 @@
 #define SAFE_SYSCONF(cleanup_fn, name) \
 	safe_sysconf(__FILE__, __LINE__, cleanup_fn, name)
 
-FILE *safe_fopen(const char *file, const int lineno, void (cleanup_fn)(void),
-                 const char *path, const char *mode);
-#define SAFE_FOPEN(cleanup_fn, path, mode) \
-	safe_fopen(__FILE__, __LINE__, cleanup_fn, path, mode)
-
-int safe_fclose(const char *file, const int lineno, void (cleanup_fn)(void),
-                FILE *f);
-#define SAFE_FCLOSE(cleanup_fn, f) \
-	safe_fclose(__FILE__, __LINE__, cleanup_fn, f)
-
 #endif /* __SAFE_MACROS_H__ */
 #endif /* __TEST_H__ */
diff --git a/include/safe_stdio.h b/include/safe_stdio.h
new file mode 100644
index 0000000..a4e3da0
--- /dev/null
+++ b/include/safe_stdio.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __SAFE_STDIO_H__
+#define __SAFE_STDIO_H__
+
+#include <stdio.h>
+
+FILE *safe_fopen(const char *file, const int lineno, void (cleanup_fn)(void),
+                 const char *path, const char *mode);
+#define SAFE_FOPEN(cleanup_fn, path, mode) \
+	safe_fopen(__FILE__, __LINE__, cleanup_fn, path, mode)
+
+int safe_fclose(const char *file, const int lineno, void (cleanup_fn)(void),
+                FILE *f);
+#define SAFE_FCLOSE(cleanup_fn, f) \
+	safe_fclose(__FILE__, __LINE__, cleanup_fn, f)
+
+int safe_asprintf(const char *file, const int lineno, void (cleanup_fn)(void),
+                  char **strp, const char *fmt, ...);
+#define SAFE_ASPRINTF(cleanup_fn, strp, fmt, ...) \
+	safe_asprintf(__FILE__, __LINE__, cleanup_fn, strp, fmt, __VA_ARGS__)
+
+#endif /* __SAFE_STDIO_H__ */
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index fb02796..4da9914 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -438,32 +438,3 @@
 
 	return rval;
 }
-
-FILE *safe_fopen(const char *file, const int lineno, void (cleanup_fn)(void),
-                 const char *path, const char *mode)
-{
-	FILE *f = fopen(path, mode);
-
-	if (f == NULL) {
-		tst_brkm(TBROK | TERRNO, cleanup_fn,
-		         "fopen(%s) failed at %s:%d", path, file, lineno);
-		return NULL;
-	}
-
-	return f;
-}
-
-int safe_fclose(const char *file, const int lineno, void (cleanup_fn)(void),
-                FILE *f)
-{
-	int ret;
-
-	ret = fclose(f);
-
-	if (ret) {
-		tst_brkm(TBROK | TERRNO, cleanup_fn,
-		         "fclose failed at %s:%d", file, lineno);
-	}
-
-	return ret;
-}
diff --git a/lib/safe_stdio.c b/lib/safe_stdio.c
new file mode 100644
index 0000000..d9a2529
--- /dev/null
+++ b/lib/safe_stdio.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#define _GNU_SOURCE
+#include <stdarg.h>
+#include <stdio.h>
+#include "test.h"
+#include "safe_stdio.h"
+
+FILE *safe_fopen(const char *file, const int lineno, void (cleanup_fn)(void),
+                 const char *path, const char *mode)
+{
+	FILE *f = fopen(path, mode);
+
+	if (f == NULL) {
+		tst_brkm(TBROK | TERRNO, cleanup_fn,
+		         "fopen(%s) failed at %s:%d", path, file, lineno);
+		return NULL;
+	}
+
+	return f;
+}
+
+int safe_fclose(const char *file, const int lineno, void (cleanup_fn)(void),
+                FILE *f)
+{
+	int ret;
+
+	ret = fclose(f);
+
+	if (ret) {
+		tst_brkm(TBROK | TERRNO, cleanup_fn,
+		         "fclose failed at %s:%d", file, lineno);
+	}
+
+	return ret;
+}
+
+int safe_asprintf(const char *file, const int lineno, void (cleanup_fn)(void),
+                  char **strp, const char *fmt, ...)
+{
+	int ret;
+	va_list va;
+
+	va_start(va, fmt);
+	ret = vasprintf(strp, fmt, va);
+	va_end(va);
+
+	if (ret < 0) {
+		tst_brkm(TBROK | TERRNO, cleanup_fn,
+		         "asprintf failed at %s:%d", file, lineno);
+	}
+
+	return ret;
+}