From b2def1c863e7e936eca2ee5d0fb1ccd7c83e4be7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 28 Jun 2008 16:52:50 +1000 Subject: [PATCH] Add fclose_noerr() --- ccan/noerr/noerr.c | 13 +++++++++++++ ccan/noerr/noerr.h | 10 ++++++++++ ccan/noerr/test/run.c | 17 ++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/ccan/noerr/noerr.c b/ccan/noerr/noerr.c index d6df81f7..439ac7e8 100644 --- a/ccan/noerr/noerr.c +++ b/ccan/noerr/noerr.c @@ -15,6 +15,19 @@ int close_noerr(int fd) return ret; } +int fclose_noerr(FILE *fp) +{ + int saved_errno = errno, ret; + + if (fclose(fp) != 0) + ret = errno; + else + ret = 0; + + errno = saved_errno; + return ret; +} + int unlink_noerr(const char *pathname) { int saved_errno = errno, ret; diff --git a/ccan/noerr/noerr.h b/ccan/noerr/noerr.h index 559ba613..191b3d3c 100644 --- a/ccan/noerr/noerr.h +++ b/ccan/noerr/noerr.h @@ -1,5 +1,6 @@ #ifndef NOERR_H #define NOERR_H +#include /** * close_noerr - close without stomping errno. @@ -10,6 +11,15 @@ */ int close_noerr(int fd); +/** + * fclose_noerr - close without stomping errno. + * @fp: the FILE pointer. + * + * errno is saved and restored across the call to fclose: if an error occurs, + * the resulting (non-zero) errno is returned. + */ +int fclose_noerr(FILE *fp); + /** * unlink_noerr - unlink a file without stomping errno. * @pathname: the path to unlink. diff --git a/ccan/noerr/test/run.c b/ccan/noerr/test/run.c index 6d3c6837..6f1361ce 100644 --- a/ccan/noerr/test/run.c +++ b/ccan/noerr/test/run.c @@ -12,8 +12,9 @@ int main(int argc, char *argv[]) /* tempnam(3) is generally a bad idea, but OK here. */ char *name = tempnam(NULL, "noerr"); int fd; + FILE *fp; - plan_tests(12); + plan_tests(15); /* Should fail to unlink. */ ok1(unlink(name) != 0); ok1(errno == ENOENT); @@ -44,5 +45,19 @@ int main(int argc, char *argv[]) ok1(unlink_noerr(name) == 0); ok1(errno == 100); + /* Test failing fclose */ + fp = fopen(name, "wb"); + assert(fp); + close(fileno(fp)); + ok1(fclose_noerr(fp) == EBADF); + + /* Test successful fclose */ + fp = fopen(name, "wb"); + assert(fp); + + errno = 100; + ok1(fclose_noerr(fp) == 0); + ok1(errno == 100); + return exit_status(); } -- 2.39.2