Add fclose_noerr()
authorRusty Russell <rusty@vivaldi>
Sat, 28 Jun 2008 06:52:50 +0000 (16:52 +1000)
committerRusty Russell <rusty@vivaldi>
Sat, 28 Jun 2008 06:52:50 +0000 (16:52 +1000)
ccan/noerr/noerr.c
ccan/noerr/noerr.h
ccan/noerr/test/run.c

index d6df81f7a0677dad1591473a79ed6432cead713c..439ac7e8b02e1ed83038d2c51939290d282343b4 100644 (file)
@@ -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;
index 559ba6132840543f4d9a2e4fa1dcb07cb9cdf6fb..191b3d3cfc49eb76405b9b79f4680c0e622b43fd 100644 (file)
@@ -1,5 +1,6 @@
 #ifndef NOERR_H
 #define NOERR_H
+#include <stdio.h>
 
 /**
  * close_noerr - close without stomping errno.
  */
 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.
index 6d3c6837cd228b857f3b11ab589dd0f2aa00aca7..6f1361ce4d851929196c5c404de17bee91e2354a 100644 (file)
@@ -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();
 }