Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/gzip apply a patch from christian biere:



details:   https://anonhg.NetBSD.org/src/rev/385d7d2b238a
branches:  trunk
changeset: 584480:385d7d2b238a
user:      mrg <mrg%NetBSD.org@localhost>
date:      Tue Sep 20 05:12:15 2005 +0000

description:
apply a patch from christian biere:
- if we have an open fd, use it instead and, eg, fstat(2), of the file name
and stat(2).
- signed/unsigned variable fixes
- misc. cleanup

diffstat:

 usr.bin/gzip/gzip.c |  116 +++++++++++++++++++++++++++++----------------------
 1 files changed, 66 insertions(+), 50 deletions(-)

diffs (truncated from 311 to 300 lines):

diff -r 04c18bc1a4e0 -r 385d7d2b238a usr.bin/gzip/gzip.c
--- a/usr.bin/gzip/gzip.c       Tue Sep 20 04:48:10 2005 +0000
+++ b/usr.bin/gzip/gzip.c       Tue Sep 20 05:12:15 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gzip.c,v 1.76 2005/09/15 18:51:33 mrg Exp $    */
+/*     $NetBSD: gzip.c,v 1.77 2005/09/20 05:12:15 mrg Exp $    */
 
 /*
  * Copyright (c) 1997, 1998, 2003, 2004 Matthew R. Green
@@ -32,7 +32,7 @@
 #ifndef lint
 __COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004 Matthew R. Green\n\
      All rights reserved.\n");
-__RCSID("$NetBSD: gzip.c,v 1.76 2005/09/15 18:51:33 mrg Exp $");
+__RCSID("$NetBSD: gzip.c,v 1.77 2005/09/20 05:12:15 mrg Exp $");
 #endif /* not lint */
 
 /*
@@ -203,8 +203,8 @@
 static void    handle_dir(char *);
 static void    print_verbage(const char *, const char *, off_t, off_t);
 static void    print_test(const char *, int);
-static void    copymodes(const char *, struct stat *);
-static int     check_outfile(const char *outfile, struct stat *sb);
+static void    copymodes(int fd, const struct stat *, const char *file);
+static int     check_outfile(const char *outfile);
 #endif
 
 #ifndef NO_BZIP2_SUPPORT
@@ -597,6 +597,7 @@
        /* clean up */
        for (;;) {
                size_t len;
+               ssize_t w;
 
                error = deflate(&z, Z_FINISH);
                if (error != Z_OK && error != Z_STREAM_END) {
@@ -607,7 +608,8 @@
 
                len = (char *)z.next_out - outbufp;
 
-               if (write(out, outbufp, len) != len) {
+               w = write(out, outbufp, len);
+               if (w == -1 || (size_t)w != len) {
                        maybe_warn("write");
                        out_tot = -1;
                        goto out;
@@ -717,7 +719,7 @@
 
        for (;;) {
                if ((z.avail_in == 0 || needmore) && done_reading == 0) {
-                       size_t in_size;
+                       ssize_t in_size;
 
                        if (z.avail_in > 0) {
                                memmove(inbufp, z.next_in, z.avail_in);
@@ -1005,12 +1007,14 @@
 
 #ifndef SMALL
 /*
- * set the owner, mode, flags & utimes for a file
+ * set the owner, mode, flags & utimes using the given file descriptor.
+ * file is only used in possible warning messages.
  */
 static void
-copymodes(const char *file, struct stat *sbp)
+copymodes(int fd, const struct stat *sbp, const char *file)
 {
        struct timeval times[2];
+       struct stat sb;
 
        /*
         * If we have no info on the input, give this file some
@@ -1019,30 +1023,31 @@
        if (sbp == NULL) {
                mode_t mask = umask(022);
 
-               (void)chmod(file, DEFFILEMODE & ~mask);
+               (void)fchmod(fd, DEFFILEMODE & ~mask);
                (void)umask(mask);
                return; 
        }
+       sb = *sbp;
 
        /* if the chown fails, remove set-id bits as-per compress(1) */
-       if (chown(file, sbp->st_uid, sbp->st_gid) < 0) {
+       if (fchown(fd, sb.st_uid, sb.st_gid) < 0) {
                if (errno != EPERM)
-                       maybe_warn("couldn't chown: %s", file);
-               sbp->st_mode &= ~(S_ISUID|S_ISGID);
+                       maybe_warn("couldn't fchown: %s", file);
+               sb.st_mode &= ~(S_ISUID|S_ISGID);
        }
 
        /* we only allow set-id and the 9 normal permission bits */
-       sbp->st_mode &= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
-       if (chmod(file, sbp->st_mode) < 0)
-               maybe_warn("couldn't chmod: %s", file);
+       sb.st_mode &= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
+       if (fchmod(fd, sb.st_mode) < 0)
+               maybe_warn("couldn't fchmod: %s", file);
 
        /* only try flags if they exist already */
-        if (sbp->st_flags != 0 && chflags(file, sbp->st_flags) < 0)
-               maybe_warn("couldn't chflags: %s", file);
+        if (sb.st_flags != 0 && fchflags(fd, sb.st_flags) < 0)
+               maybe_warn("couldn't fchflags: %s", file);
 
-       TIMESPEC_TO_TIMEVAL(&times[0], &sbp->st_atimespec);
-       TIMESPEC_TO_TIMEVAL(&times[1], &sbp->st_mtimespec);
-       if (utimes(file, times) < 0)
+       TIMESPEC_TO_TIMEVAL(&times[0], &sb.st_atimespec);
+       TIMESPEC_TO_TIMEVAL(&times[1], &sb.st_mtimespec);
+       if (futimes(fd, times) < 0)
                maybe_warn("couldn't utimes: %s", file);
 }
 #endif
@@ -1073,11 +1078,12 @@
 #ifndef SMALL
 /* check the outfile is OK. */
 static int
-check_outfile(const char *outfile, struct stat *sb)
+check_outfile(const char *outfile)
 {
+       struct stat sb;
        int ok = 1;
 
-       if (lflag == 0 && stat(outfile, sb) == 0) {
+       if (lflag == 0 && stat(outfile, &sb) == 0) {
                if (fflag)
                        unlink(outfile);
                else if (isatty(STDIN_FILENO)) {
@@ -1100,7 +1106,7 @@
 }
 
 static void
-unlink_input(const char *file, struct stat *sb)
+unlink_input(const char *file, const struct stat *sb)
 {
        struct stat nsb;
 
@@ -1156,19 +1162,16 @@
                return -1;
        }
 
-#ifndef SMALL
-       if (stat(file, &isb) != 0) {
-               maybe_warn("cannot stat %s -- skipping", file);
-               return -1;
-       }
-#endif
        if (cflag == 0) {
 #ifndef SMALL
-               if (isb.st_nlink > 1 && fflag == 0) {
-                       maybe_warnx("%s has %d other link%s -- skipping", file,
-                           isb.st_nlink - 1, isb.st_nlink == 1 ? "" : "s");
-                       close(in);
-                       return -1;
+               if (fstat(in, &isb) == 0) {
+                       if (isb.st_nlink > 1 && fflag == 0) {
+                               maybe_warnx("%s has %d other link%s -- "
+                                           "skipping", file, isb.st_nlink - 1,
+                                           isb.st_nlink == 1 ? "" : "s");
+                               close(in);
+                               return -1;
+                       }
                }
 
                if (fflag == 0 && (suff = check_suffix(file, 0))
@@ -1181,13 +1184,13 @@
 #endif
 
                /* Add (usually) .gz to filename */
-               if (snprintf(outfile, outsize, "%s%s",
+               if ((size_t)snprintf(outfile, outsize, "%s%s",
                                        file, suffixes[0].zipped) >= outsize)
                        memcpy(outfile - suffixes[0].ziplen - 1,
                                suffixes[0].zipped, suffixes[0].ziplen + 1);
 
 #ifndef SMALL
-               if (check_outfile(outfile, &osb) == 0) {
+               if (check_outfile(outfile) == 0) {
                        close(in);
                        return -1;
                }
@@ -1218,11 +1221,8 @@
        if (cflag != 0)
                return insize == -1 ? -1 : size;
 
-       if (close(out) == -1)
-               maybe_warn("couldn't close ouput");
-
 #ifndef SMALL
-       if (stat(outfile, &osb) != 0) {
+       if (fstat(out, &osb) != 0) {
                maybe_warn("couldn't stat: %s", outfile);
                goto bad_outfile;
        }
@@ -1234,8 +1234,10 @@
                goto bad_outfile;
        }
 
-       copymodes(outfile, &isb);
+       copymodes(out, &isb, outfile);
 #endif
+       if (close(out) == -1)
+               maybe_warn("couldn't close output");
 
        /* output is good, ok to delete input */
        unlink_input(file, &isb);
@@ -1243,6 +1245,9 @@
 
 #ifndef SMALL
     bad_outfile:
+       if (close(out) == -1)
+               maybe_warn("couldn't close output");
+
        maybe_warnx("leaving original %s", file);
        unlink(outfile);
        return size;
@@ -1258,7 +1263,7 @@
        ssize_t rbytes;
        unsigned char header1[4];
        enum filetype method;
-       int fd, zfd = -1;
+       int fd, ofd, zfd = -1;
 #ifndef SMALL
        time_t timestamp = 0;
        unsigned char name[PATH_MAX + 1];
@@ -1346,7 +1351,7 @@
                }
                if (nflag == 0 && timestamp)
                        isb.st_mtime = timestamp;
-               if (check_outfile(outfile, &osb) == 0)
+               if (check_outfile(outfile) == 0)
                        goto lose;
 #endif
        }
@@ -1461,22 +1466,32 @@
        /*
         * if we can't stat the file don't remove the file.
         */
-       if (stat(outfile, &osb) != 0) {
+
+       ofd = open(outfile, O_RDWR, 0);
+       if (ofd == -1) {
+               maybe_warn("couldn't open (leaving original): %s",
+                          outfile);
+               return -1;
+       }
+       if (fstat(ofd, &osb) != 0) {
                maybe_warn("couldn't stat (leaving original): %s",
                           outfile);
+               close(ofd);
                return -1;
        }
        if (osb.st_size != size) {
                maybe_warnx("stat gave different size: %" PRIdOFF
                                " != %" PRIdOFF " (leaving original)",
                                size, osb.st_size);
+               close(ofd);
                unlink(outfile);
                return -1;
        }
        unlink_input(file, &isb);
 #ifndef SMALL
-       copymodes(outfile, &isb);
+       copymodes(ofd, &isb, outfile);
 #endif
+       close(ofd);
        return size;
 
     lose:
@@ -1493,9 +1508,11 @@
 {
        char buf[BUFLEN];
        off_t in_tot;
+       ssize_t w;
 
        in_tot = count;
-       if (write(STDOUT_FILENO, prepend, count) != count) {
+       w = write(STDOUT_FILENO, prepend, count);
+       if (w == -1 || (size_t)w != count) {
                maybe_warn("write to stdout");
                return -1;
        }
@@ -1846,8 +1863,7 @@
        static off_t in_tot, out_tot;
        uint32_t crc = 0;
 #endif
-       off_t in = 0;
-       int rv;
+       off_t in = 0, rv;
 
        if (first) {
 #ifndef SMALL
@@ -1957,12 +1973,12 @@
 read_retry(int fd, void *buf, size_t sz)
 {
        char *cp = buf;



Home | Main Index | Thread Index | Old Index