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