1/* 2 * Copyright (c) 2013 Cyril Hrubis <chrubis@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 26FILE *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_(file, lineno, TBROK | TERRNO, cleanup_fn, 33 "fopen(%s,%s) failed", path, mode); 34 } 35 36 return f; 37} 38 39int safe_fclose(const char *file, const int lineno, void (cleanup_fn)(void), 40 FILE *f) 41{ 42 int ret; 43 44 ret = fclose(f); 45 46 if (ret == EOF) { 47 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn, 48 "fclose(%p) failed", f); 49 } else if (ret) { 50 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn, 51 "Invalid fclose(%p) return value %d", f, ret); 52 } 53 54 return ret; 55} 56 57int safe_asprintf(const char *file, const int lineno, void (cleanup_fn)(void), 58 char **strp, const char *fmt, ...) 59{ 60 int ret; 61 va_list va; 62 63 va_start(va, fmt); 64 ret = vasprintf(strp, fmt, va); 65 va_end(va); 66 67 if (ret == -1) { 68 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn, 69 "asprintf(%s,...) failed", fmt); 70 } else if (ret < 0) { 71 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn, 72 "Invalid asprintf(%s,...) return value %d", fmt, ret); 73 } 74 75 return ret; 76} 77 78FILE *safe_popen(const char *file, const int lineno, void (cleanup_fn)(void), 79 const char *command, const char *type) 80{ 81 FILE *stream; 82 const int saved_errno = errno; 83 84 errno = 0; 85 stream = popen(command, type); 86 87 if (stream == NULL) { 88 if (errno != 0) { 89 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn, 90 "popen(%s,%s) failed", command, type); 91 } else { 92 tst_brkm_(file, lineno, TBROK, cleanup_fn, 93 "popen(%s,%s) failed: Out of memory", 94 command, type); 95 } 96 } 97 98 errno = saved_errno; 99 100 return stream; 101} 102