Home | History | Annotate | Download | only in lib
      1 /*
      2  * Copyright (c) 2013 Cyril Hrubis <chrubis (at) suse.cz>
      3  *
      4  * This program is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU General Public License as
      6  * published by the Free Software Foundation; either version 2 of
      7  * the License, or (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it would be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program; if not, write the Free Software Foundation,
     16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     17  */
     18 
     19 #define _GNU_SOURCE
     20 #include <stdarg.h>
     21 #include <stdio.h>
     22 #include <errno.h>
     23 #include "test.h"
     24 #include "safe_stdio_fn.h"
     25 
     26 FILE *safe_fopen(const char *file, const int lineno, void (cleanup_fn)(void),
     27                  const char *path, const char *mode)
     28 {
     29 	FILE *f = fopen(path, mode);
     30 
     31 	if (f == NULL) {
     32 		tst_brkm(TBROK | TERRNO, cleanup_fn,
     33 			 "%s:%d: fopen(%s,%s) failed",
     34 			 file, lineno, path, mode);
     35 	}
     36 
     37 	return f;
     38 }
     39 
     40 int safe_fclose(const char *file, const int lineno, void (cleanup_fn)(void),
     41                 FILE *f)
     42 {
     43 	int ret;
     44 
     45 	ret = fclose(f);
     46 
     47 	if (ret) {
     48 		tst_brkm(TBROK | TERRNO, cleanup_fn,
     49 			 "%s:%d: fclose(%p) failed", file, lineno, f);
     50 	}
     51 
     52 	return ret;
     53 }
     54 
     55 int safe_asprintf(const char *file, const int lineno, void (cleanup_fn)(void),
     56                   char **strp, const char *fmt, ...)
     57 {
     58 	int ret;
     59 	va_list va;
     60 
     61 	va_start(va, fmt);
     62 	ret = vasprintf(strp, fmt, va);
     63 	va_end(va);
     64 
     65 	if (ret < 0) {
     66 		tst_brkm(TBROK | TERRNO, cleanup_fn,
     67 			 "%s:%d: asprintf(%s,...) failed", file, lineno, fmt);
     68 	}
     69 
     70 	return ret;
     71 }
     72 
     73 FILE *safe_popen(const char *file, const int lineno, void (cleanup_fn)(void),
     74 		 const char *command, const char *type)
     75 {
     76 	FILE *stream;
     77 	const int saved_errno = errno;
     78 
     79 	errno = 0;
     80 	stream = popen(command, type);
     81 
     82 	if (stream == NULL) {
     83 		if (errno != 0) {
     84 			tst_brkm(TBROK | TERRNO, cleanup_fn,
     85 				 "%s:%d: popen(%s,%s) failed",
     86 				 file, lineno, command, type);
     87 		} else {
     88 			tst_brkm(TBROK, cleanup_fn,
     89 				 "%s:%d: popen(%s,%s) failed: Out of memory",
     90 				 file, lineno, command, type);
     91 		}
     92 	}
     93 
     94 	errno = saved_errno;
     95 
     96 	return stream;
     97 }
     98