]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
vipw: move copyfile to the lib
authorEgor Chelak <egor.chelak@gmail.com>
Fri, 6 Nov 2020 07:45:18 +0000 (09:45 +0200)
committerEgor Chelak <egor.chelak@gmail.com>
Mon, 9 Nov 2020 05:18:42 +0000 (07:18 +0200)
Also, a bug in pw_tmpfile was fixed: copyfile used tmp_file to report
errors, but pw_tmpfile only assigned that variable _after_ calling
copyfile.

Suggested-by: Sami Kerola <kerolasa@iki.fi>
Reviewed-by: Sami Kerola <kerolasa@iki.fi>
Signed-off-by: Egor Chelak <egor.chelak@gmail.com>
include/fileutils.h
lib/fileutils.c
login-utils/vipw.c

index 479ad15cfea8725b96598df7a8bbaff579abc0c7..2766b0d437592d6d15a999994a7e1881e31ecce8 100644 (file)
@@ -74,4 +74,6 @@ static inline struct dirent *xreaddir(DIR *dp)
 
 extern void close_all_fds(const int exclude[], size_t exsz);
 
+int ul_copy_file(int from, int to);
+
 #endif /* UTIL_LINUX_FILEUTILS */
index 003f890f93262b9633985ca8a5bc498f8bd5e551..9e0823d30eeeed8b18e2c8cadb538cffb1a4bd03 100644 (file)
@@ -10,6 +10,7 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <string.h>
 
 #include "c.h"
 #include "fileutils.h"
@@ -246,3 +247,21 @@ char *stripoff_last_component(char *path)
        *p = '\0';
        return p + 1;
 }
+
+/* Copies the contents of a file. Returns -1 on read error, -2 on write error. */
+int ul_copy_file(int from, int to)
+{
+       ssize_t nr, nw, off;
+       char buf[8 * 1024];
+
+       while ((nr = read(from, buf, sizeof(buf))) > 0)
+               for (off = 0; nr > 0; nr -= nw, off += nw)
+                       if ((nw = write(to, buf + off, nr)) < 0)
+                               return -2;
+       if (nr < 0)
+               return -1;
+#ifdef HAVE_EXPLICIT_BZERO
+       explicit_bzero(buf, sizeof(buf));
+#endif
+       return 0;
+}
index 38953b7f5923980d01e33e489a1caef494b78c54..a107259aecbeb784596f81319dd309a4fdff68d7 100644 (file)
@@ -88,23 +88,6 @@ static char *tmp_file;                       /* tmp file */
 
 void pw_error (char *, int, int);
 
-static void copyfile(int from, int to)
-{
-       int nr, nw, off;
-       char buf[8 * 1024];
-
-       while ((nr = read(from, buf, sizeof(buf))) > 0)
-               for (off = 0; nr > 0; nr -= nw, off += nw)
-                       if ((nw = write(to, buf + off, nr)) < 0)
-                               pw_error(tmp_file, 1, 1);
-
-       if (nr < 0)
-               pw_error(orig_file, 1, 1);
-#ifdef HAVE_EXPLICIT_BZERO
-       explicit_bzero(buf, sizeof(buf));
-#endif
-}
-
 static void pw_init(void)
 {
        struct rlimit rlim;
@@ -139,14 +122,19 @@ static FILE * pw_tmpfile(int lockfd)
 {
        FILE *fd;
        char *tmpname = NULL;
+       int res;
 
        if ((fd = xfmkstemp(&tmpname, "/etc", ".vipw")) == NULL) {
                ulckpwdf();
                err(EXIT_FAILURE, _("can't open temporary file"));
        }
 
-       copyfile(lockfd, fileno(fd));
        tmp_file = tmpname;
+       res = ul_copy_file(lockfd, fileno(fd));
+       if (res == -1)
+               pw_error(orig_file, 1, 1);
+       else if (res == -2)
+               pw_error(tmp_file, 1, 1);
        return fd;
 }