Changeset: cde28737021c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/cde28737021c
Modified Files:
        sql/storage/store.c
Branch: default
Log Message:

In snapshot code, use int64_t to represent file sizes


diffs (164 lines):

diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -2557,12 +2557,18 @@ tar_write_header_field(char **cursor_ptr
 
 // Write a tar header to the given stream.
 static gdk_return __attribute__((__warn_unused_result__))
-tar_write_header(stream *tarfile, const char *path, time_t mtime, size_t size)
+tar_write_header(stream *tarfile, const char *path, time_t mtime, int64_t size)
 {
        char buf[TAR_BLOCK_SIZE] = {0};
        char *cursor = buf;
        char *chksum;
 
+       if (size > 077777777777) { // 0_777_7777_7777
+               // doesn't fit header field
+               GDKerror("error writing tar file: member %s too large", path);
+               return GDK_FAIL;
+       }
+
        // We set the uid/gid fields to 0 and the uname/gname fields to "".
        // When unpacking as a normal user, they are ignored and the files are
        // owned by that user. When unpacking as root it is reasonable that
@@ -2574,7 +2580,7 @@ tar_write_header(stream *tarfile, const 
        tar_write_header_field(&cursor, 8, "0000644");      // mode[8]
        tar_write_header_field(&cursor, 8, "%07o", 0U);      // uid[8]
        tar_write_header_field(&cursor, 8, "%07o", 0U);      // gid[8]
-       tar_write_header_field(&cursor, 12, "%011zo", size);      // size[12]
+       tar_write_header_field(&cursor, 12, "%011"PRIo64, size);      // 
size[12]
        tar_write_header_field(&cursor, 12, "%011lo", (unsigned long)mtime); // 
mtime[12]
        chksum = cursor; // use this later to set the computed checksum
        tar_write_header_field(&cursor, 8, "%8s", ""); // chksum[8]
@@ -2609,7 +2615,7 @@ tar_write_header(stream *tarfile, const 
  * of TAR_BLOCK_SIZE.
  */
 static gdk_return __attribute__((__warn_unused_result__))
-tar_write(stream *outfile, const char *data, size_t size)
+tar_write(stream *outfile, const char *path,  const char *data, size_t size)
 {
        const size_t tail = size % TAR_BLOCK_SIZE;
        const size_t bulk = size - tail;
@@ -2617,7 +2623,7 @@ tar_write(stream *outfile, const char *d
        if (bulk) {
                size_t written = mnstr_write(outfile, data, 1, bulk);
                if (written != bulk) {
-                       GDKerror("Wrote only %zu bytes instead of first %zu", 
written, bulk);
+                       GDKerror("Wrote only %zu bytes of %s instead of first 
%zu", written, path, bulk);
                        return GDK_FAIL;
                }
        }
@@ -2627,7 +2633,7 @@ tar_write(stream *outfile, const char *d
                memcpy(buf, data + bulk, tail);
                size_t written = mnstr_write(outfile, buf, 1, TAR_BLOCK_SIZE);
                if (written != TAR_BLOCK_SIZE) {
-                       GDKerror("Wrote only %zu tail bytes instead of %d", 
written, TAR_BLOCK_SIZE);
+                       GDKerror("Wrote only %zu tail bytes of %s instead of 
%d", written, path, TAR_BLOCK_SIZE);
                        return GDK_FAIL;
                }
        }
@@ -2644,40 +2650,38 @@ tar_write_data(stream *tarfile, const ch
        if (res != GDK_SUCCEED)
                return res;
 
-       return tar_write(tarfile, data, size);
+       return tar_write(tarfile, path, data, size);
 }
 
 static gdk_return __attribute__((__warn_unused_result__))
-tar_copy_stream(stream *tarfile, const char *path, time_t mtime, stream 
*contents, size_t size, char *buf, size_t bufsize)
-{
-       size_t file_size;
-       size_t to_read;
-
-       file_size = getFileSize(contents);
-       if (file_size < size) {
-               GDKerror("Have to copy %zd bytes but only %zd exist in %s", 
size, file_size, path);
-               return GDK_FAIL;
-       }
-
+tar_copy_stream(stream *tarfile, const char *path, time_t mtime, stream 
*contents, int64_t size, char *buf, size_t bufsize)
+{
        assert( (bufsize % TAR_BLOCK_SIZE) == 0);
        assert(bufsize >= TAR_BLOCK_SIZE);
 
-
        if (tar_write_header(tarfile, path, mtime, size) != GDK_SUCCEED)
                return GDK_FAIL;
 
-       to_read = size;
-
-       while (to_read > 0) {
-               size_t chunk = (to_read <= bufsize) ? to_read : bufsize;
+       int64_t to_do = size;
+       while (to_do > 0) {
+               size_t chunk = (to_do <= (int64_t)bufsize) ? (size_t)to_do : 
bufsize;
                ssize_t nbytes = mnstr_read(contents, buf, 1, chunk);
-               if (nbytes != (ssize_t)chunk) {
-                       GDKerror("Read only %zd/%zd bytes of component %s: %s", 
nbytes, chunk, path, mnstr_peek_error(contents));
+               if (nbytes > 0) {
+                       if (tar_write(tarfile, path, buf, nbytes) != 
GDK_SUCCEED)
+                               return GDK_FAIL;
+                       to_do -= (int64_t)nbytes;
+                       continue;
+               }
+               // error handling
+               if (nbytes < 0) {
+                       GDKerror("Error after reading %"PRId64"/%"PRId64" 
bytes: %s",
+                               size - to_do, size, mnstr_peek_error(contents));
                        return GDK_FAIL;
-               }
-               if (tar_write(tarfile, buf, chunk) != GDK_SUCCEED)
+               } else {
+                       GDKerror("Unexpected end of file after reading 
%"PRId64"/%"PRId64" bytes of %s",
+                               size - to_do, size, path);
                        return GDK_FAIL;
-               to_read -= chunk;
+               }
        }
 
        return GDK_SUCCEED;
@@ -2726,13 +2730,13 @@ hot_snapshot_write_tar(stream *out, cons
        *src_name++ = DIR_SEP;
 
        char command;
-       long size;
-       while (sscanf(p, "%c %ld %100s\n%n", &command, &size, src_name, &len) 
== 3) {
+       int64_t size;
+       while (sscanf(p, "%c %"SCNi64" %100s\n%n", &command, &size, src_name, 
&len) == 3) {
                GDK_CHECK_TIMEOUT_BODY(qry_ctx, GOTO_LABEL_TIMEOUT_HANDLER(end, 
qry_ctx));
                p += len;
                strcpy(dest_name, src_name);
                if (size < 0) {
-                       GDKerror("malformed snapshot plan for %s: size %ld < 
0", src_name, size);
+                       GDKerror("malformed snapshot plan for %s: size 
%"PRId64" < 0", src_name, size);
                        goto end;
                }
                switch (command) {
@@ -2748,9 +2752,9 @@ hot_snapshot_write_tar(stream *out, cons
                                infile = NULL;
                                break;
                        case 'w':
-                               if (tar_write_data(out, dest_path, timestamp, 
p, size) != GDK_SUCCEED)
+                               if (tar_write_data(out, dest_path, timestamp, 
p, (size_t)size) != GDK_SUCCEED)
                                        goto end;
-                               p += size;
+                               p += (size_t)size;
                                break;
                        default:
                                GDKerror("Unknown command in snapshot plan: %c 
(%s)", command, src_name);
@@ -2760,11 +2764,12 @@ hot_snapshot_write_tar(stream *out, cons
        }
 
        // write a trailing block of zeros. If it succeeds, this function 
succeeds.
+       char *descr = "end-of-archive marker";
        char a;
        a = '\0';
-       ret = tar_write(out, &a, 1);
+       ret = tar_write(out, descr, &a, 1);
        if (ret == GDK_SUCCEED)
-               ret = tar_write(out, &a, 1);
+               ret = tar_write(out, descr, &a, 1);
 
 end:
        free(plan);
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to