diff --git a/programs/fileio.c b/programs/fileio.c index 3c2c5c64d..6fbe0c8ed 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -649,18 +649,24 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs, #endif if (f == NULL) { DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno)); + } else { + /* An increased buffer size can provide a significant performance + * boost on some platforms. Note that providing a NULL buf with a + * size that's not 0 is not defined in ANSI C, but is defined in an + * extension. There are three possibilities here: + * 1. Libc supports the extended version and everything is good. + * 2. Libc ignores the size when buf is NULL, in which case + * everything will continue as if we didn't call `setvbuf()`. + * 3. We fail the call and execution continues but a warning + * message might be shown. + * In all cases due execution continues. For now, I believe that + * this is a more cost-effective solution than managing the buffers + * allocations ourselves (will require an API change). + */ + if (setvbuf(f, NULL, _IOFBF, 1 MB)) { + DISPLAYLEVEL(2, "Warning: setvbuf failed for %s\n", dstFileName); + } } - /* An increased buffer size can provide a significant performance boost on some platforms. - * Note that providing a NULL buf with a size that's not 0 is not defined in ANSI C, but is defined - * in an extension. There are three possibilities here - - * 1. Libc supports the extended version and everything is good. - * 2. Libc ignores the size when buf is NULL, in which case everything will continue as if we didn't - * call `setvbuf`. - * 3. We fail the call and execution continues but a warning message might be shown. - * In all cases due execution continues. For now, I believe that this is a more cost-effective - * solution than managing the buffers allocations ourselves (will require an API change). */ - if(setvbuf(f, NULL, _IOFBF, 1 MB)) - DISPLAYLEVEL(2, "Warning: setvbuf failed for %s\n", dstFileName); return f; } } diff --git a/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh b/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh new file mode 100755 index 000000000..1aa4525fb --- /dev/null +++ b/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# motivated by issue #3523 + +datagen > file +mkdir out +chmod 000 out + +zstd file -q --trace-file-stat -o out/file.zst +zstd -tq out/file.zst + +chmod 777 out diff --git a/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh.stderr.exact b/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh.stderr.exact new file mode 100644 index 000000000..95deaf2b1 --- /dev/null +++ b/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh.stderr.exact @@ -0,0 +1,26 @@ +Trace:FileStat: > UTIL_isLink(file) +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_isConsole(2) +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_getFileSize(file) +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: < 65537 +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: > UTIL_isDirectoryStat() +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: > UTIL_isSameFile(file, out/file.zst) +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: > UTIL_stat(-1, out/file.zst) +Trace:FileStat: < 0 +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_isRegularFile(out/file.zst) +Trace:FileStat: > UTIL_stat(-1, out/file.zst) +Trace:FileStat: < 0 +Trace:FileStat: < 0 +zstd: out/file.zst: Permission denied +zstd: can't stat out/file.zst : Permission denied -- ignored diff --git a/tests/cli-tests/run.py b/tests/cli-tests/run.py index 45af5124b..a2e1c1f86 100755 --- a/tests/cli-tests/run.py +++ b/tests/cli-tests/run.py @@ -535,7 +535,8 @@ class TestSuite: subprocess.run( args=[script], stdin=subprocess.DEVNULL, - capture_output=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, cwd=cwd, env=env, check=True,