diff options
author | sethp <seth.pellegrino@gmail.com> | 2023-10-02 08:20:09 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-02 08:20:09 -0700 |
commit | 0e78c24fd231d5ee67ccd271bfa317faa963281c (patch) | |
tree | e9c8192abf3409bfdca2bb06cce5571b6b184c5e /src | |
parent | dddc03d3bc4df2bca26a880e8f078f84ea3d2454 (diff) | |
download | wabt-0e78c24fd231d5ee67ccd271bfa317faa963281c.tar.gz wabt-0e78c24fd231d5ee67ccd271bfa317faa963281c.tar.bz2 wabt-0e78c24fd231d5ee67ccd271bfa317faa963281c.zip |
feat: treat non-seekable files as pipes (#2309)
Previously, attempting to read from a pipe would result in an error:
'not a regular file', disallowing use of files like /dev/stdin or
/dev/fd/3, named fifos, sockets, etc.
The tools already understand how to (try to) read from non-regular
files, so this change attempts to do so when the input is not seek-able
(the "regular file" capability that's in use here).
Additionally, this adds a test for the new behavior using a bash
herestring and process substitution (the latter of which shows up in
argv as something like `/dev/fd/NN`). Since bash isn't commonly
installed on Windows, this change also introduces a new capability to
filter tests to specific platforms (sorry).
Diffstat (limited to 'src')
-rw-r--r-- | src/common.cc | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/src/common.cc b/src/common.cc index 037b8304..d1873c2c 100644 --- a/src/common.cc +++ b/src/common.cc @@ -59,14 +59,16 @@ const char* g_reloc_type_name[] = { }; WABT_STATIC_ASSERT(WABT_ARRAY_SIZE(g_reloc_type_name) == kRelocTypeCount); -static Result ReadStdin(std::vector<uint8_t>* out_data) { +static Result ReadAll(FILE* stream, + const char* name, + std::vector<uint8_t>* out_data) { out_data->resize(0); uint8_t buffer[4096]; while (true) { - size_t bytes_read = fread(buffer, 1, sizeof(buffer), stdin); + size_t bytes_read = fread(buffer, 1, sizeof(buffer), stream); if (bytes_read == 0) { - if (ferror(stdin)) { - fprintf(stderr, "error reading from stdin: %s\n", strerror(errno)); + if (ferror(stream)) { + fprintf(stderr, "error reading from %s: %s\n", name, strerror(errno)); return Result::Error; } return Result::Ok; @@ -82,7 +84,7 @@ Result ReadFile(std::string_view filename, std::vector<uint8_t>* out_data) { const char* filename_cstr = filename_str.c_str(); if (filename == "-") { - return ReadStdin(out_data); + return ReadAll(stdin, "stdin", out_data); } struct stat statbuf; @@ -91,8 +93,8 @@ Result ReadFile(std::string_view filename, std::vector<uint8_t>* out_data) { return Result::Error; } - if (!(statbuf.st_mode & S_IFREG)) { - fprintf(stderr, "%s: not a regular file\n", filename_cstr); + if (statbuf.st_mode & S_IFDIR) { + fprintf(stderr, "%s: is a directory\n", filename_cstr); return Result::Error; } @@ -103,9 +105,11 @@ Result ReadFile(std::string_view filename, std::vector<uint8_t>* out_data) { } if (fseek(infile, 0, SEEK_END) < 0) { - perror("fseek to end failed"); + // not seekable, so we can't pre-allocate out_data, but let's try and read + // it anyway (for pipes, sockets, etc.) + auto res = ReadAll(infile, filename_cstr, out_data); fclose(infile); - return Result::Error; + return res; } long size = ftell(infile); |