Hi,

This is also a bit of an RFC; the return value of close() is
important, but it is rarely checked.

We tend to notice this more on our kernel because of our buffer cache
implementation, but I think it's generally the right thing to do.

xclose should probably be used more liberally, but gzip was one where
I saw the problem.

-i

diff --git a/archival/bbunzip.c b/archival/bbunzip.c
index d25f509..a0505cc 100644
--- a/archival/bbunzip.c
+++ b/archival/bbunzip.c
@@ -98,6 +98,7 @@ int FAST_FUNC bbunpack(char **argv,
                status = unpacker(&info);
                if (status < 0)
                        exitcode = 1;
+               xclose(STDOUT_FILENO);

                if (filename) {
                        char *del = new_name;
@@ -108,10 +109,13 @@ int FAST_FUNC bbunpack(char **argv,

                                        times.actime = info.mtime;
                                        times.modtime = info.mtime;
-                                       /* Close first.
-                                        * On some systems calling utime
-                                        * then closing resets the mtime. */
-                                       close(STDOUT_FILENO);
+
+                                       /* Note the file was closed
+                                        * above -- on some systems
+                                        * calling utime then closing
+                                        * resets the mtime which we
+                                        * don't want! */
+
                                        /* Ignoring errors */
                                        utime(new_name, &times);
                                }
diff --git a/include/libbb.h b/include/libbb.h
index 8ecde5b..22d2c04 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -629,6 +629,9 @@ extern void xwrite(int fd, const void *buf, size_t count) 
FAST_FUNC;
 extern void xwrite_str(int fd, const char *str) FAST_FUNC;
 extern void xopen_xwrite_close(const char* file, const char *str) FAST_FUNC;

+/* Close fd, but check for failures (e.g. failed delayed writes from NFS, etc) 
*/
+extern void xclose(int fd) FAST_FUNC;
+
 /* Reads and prints to stdout till eof, then closes FILE. Exits on error: */
 extern void xprint_and_close_file(FILE *file) FAST_FUNC;

diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index 5f56b36..aaf9989 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -213,6 +213,12 @@ void FAST_FUNC xwrite_str(int fd, const char *str)
        xwrite(fd, str, strlen(str));
 }

+void FAST_FUNC xclose(int fd)
+{
+       if (close(fd))
+               bb_perror_msg_and_die("close failed");
+}
+
 // Die with an error message if we can't lseek to the right spot.
 off_t FAST_FUNC xlseek(int fd, off_t offset, int whence)
 {
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to