Improve error handling
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 4s
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 4s
Handle SIGPIPE.
This commit is contained in:
parent
e7db978a3c
commit
c1c4f048cb
2 changed files with 82 additions and 2 deletions
|
@ -28,6 +28,7 @@
|
||||||
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
|
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <spawn.h>
|
#include <spawn.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
@ -39,6 +40,14 @@
|
||||||
|
|
||||||
#define TEMP_FILENAME_CMP "simple_archiver_compressed_%u.tmp"
|
#define TEMP_FILENAME_CMP "simple_archiver_compressed_%u.tmp"
|
||||||
|
|
||||||
|
int is_sig_pipe_occurred = 0;
|
||||||
|
|
||||||
|
void handle_sig_pipe(int sig) {
|
||||||
|
if (sig == SIGPIPE) {
|
||||||
|
is_sig_pipe_occurred = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct SDArchiverInternalToWrite {
|
typedef struct SDArchiverInternalToWrite {
|
||||||
void *buf;
|
void *buf;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
@ -145,6 +154,9 @@ int write_files_fn(void *data, void *ud) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle SIGPIPE.
|
||||||
|
signal(SIGPIPE, handle_sig_pipe);
|
||||||
|
|
||||||
int pipe_into_cmd[2];
|
int pipe_into_cmd[2];
|
||||||
int pipe_outof_cmd[2];
|
int pipe_outof_cmd[2];
|
||||||
pid_t compressor_pid;
|
pid_t compressor_pid;
|
||||||
|
@ -219,6 +231,13 @@ int write_files_fn(void *data, void *ud) {
|
||||||
size_t read_count;
|
size_t read_count;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
while (!write_done || !read_done) {
|
while (!write_done || !read_done) {
|
||||||
|
if (is_sig_pipe_occurred) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to write to compressor (SIGPIPE)! Invalid "
|
||||||
|
"compressor cmd?\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Read from file.
|
// Read from file.
|
||||||
if (!write_done) {
|
if (!write_done) {
|
||||||
if (!write_again) {
|
if (!write_again) {
|
||||||
|
@ -231,10 +250,16 @@ int write_files_fn(void *data, void *ud) {
|
||||||
write_again = 1;
|
write_again = 1;
|
||||||
} else {
|
} else {
|
||||||
// Error during write.
|
// Error during write.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to write to compressor! Invalid "
|
||||||
|
"compressor cmd?\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if ((size_t)ret != write_count) {
|
} else if ((size_t)ret != write_count) {
|
||||||
// Error during write.
|
// Error during write.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to write to compressor! Invalid "
|
||||||
|
"compressor cmd?\n");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
write_again = 0;
|
write_again = 0;
|
||||||
|
@ -248,6 +273,9 @@ int write_files_fn(void *data, void *ud) {
|
||||||
// fprintf(stderr, "write_done\n");
|
// fprintf(stderr, "write_done\n");
|
||||||
} else if (ferror(file_fd)) {
|
} else if (ferror(file_fd)) {
|
||||||
// Error during read file.
|
// Error during read file.
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"WARNING: Failed to write to compressor (failed to read)!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,6 +288,9 @@ int write_files_fn(void *data, void *ud) {
|
||||||
read_count = fwrite(read_buf, 1, ret, tmp_fd);
|
read_count = fwrite(read_buf, 1, ret, tmp_fd);
|
||||||
if (read_count != (size_t)ret) {
|
if (read_count != (size_t)ret) {
|
||||||
// Write to tmp_fd error.
|
// Write to tmp_fd error.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to read from compressor! Invalid "
|
||||||
|
"compressor cmd?\n");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
// fprintf(stderr, "Written %zd bytes to tmp_fd.\n", read_count);
|
// fprintf(stderr, "Written %zd bytes to tmp_fd.\n", read_count);
|
||||||
|
@ -274,6 +305,9 @@ int write_files_fn(void *data, void *ud) {
|
||||||
// Nop.
|
// Nop.
|
||||||
} else {
|
} else {
|
||||||
// Read error.
|
// Read error.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to read from compressor! Invalid "
|
||||||
|
"compressor cmd?\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -282,6 +316,13 @@ int write_files_fn(void *data, void *ud) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_sig_pipe_occurred) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to write to compressor (SIGPIPE)! Invalid "
|
||||||
|
"compressor cmd?\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
waitpid(compressor_pid, NULL, 0);
|
waitpid(compressor_pid, NULL, 0);
|
||||||
|
|
||||||
uint16_t u16;
|
uint16_t u16;
|
||||||
|
@ -991,6 +1032,9 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
|
||||||
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
|
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
|
||||||
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
|
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
|
||||||
if (is_compressed) {
|
if (is_compressed) {
|
||||||
|
// Handle SIGPIPE.
|
||||||
|
signal(SIGPIPE, handle_sig_pipe);
|
||||||
|
|
||||||
int pipe_into_cmd[2];
|
int pipe_into_cmd[2];
|
||||||
int pipe_outof_cmd[2];
|
int pipe_outof_cmd[2];
|
||||||
pid_t decompressor_pid;
|
pid_t decompressor_pid;
|
||||||
|
@ -1025,6 +1069,9 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
|
||||||
// Failed to spawn compressor.
|
// Failed to spawn compressor.
|
||||||
close(pipe_into_cmd[1]);
|
close(pipe_into_cmd[1]);
|
||||||
close(pipe_outof_cmd[0]);
|
close(pipe_outof_cmd[0]);
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"WARNING: Failed to start decompressor cmd! Invalid cmd?\n");
|
||||||
return SDAS_INTERNAL_ERROR;
|
return SDAS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1077,6 +1124,13 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
|
||||||
char recv_buf[1024];
|
char recv_buf[1024];
|
||||||
size_t amount_to_read;
|
size_t amount_to_read;
|
||||||
while (!write_pipe_done || !read_pipe_done) {
|
while (!write_pipe_done || !read_pipe_done) {
|
||||||
|
if (is_sig_pipe_occurred) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to write to decompressor (SIGPIPE)! "
|
||||||
|
"Invalid decompressor cmd?\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Read from file.
|
// Read from file.
|
||||||
if (!write_pipe_done) {
|
if (!write_pipe_done) {
|
||||||
if (!write_again && compressed_file_size != 0) {
|
if (!write_again && compressed_file_size != 0) {
|
||||||
|
@ -1106,10 +1160,16 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
|
||||||
write_again = 1;
|
write_again = 1;
|
||||||
} else {
|
} else {
|
||||||
// Error.
|
// Error.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to write to decompressor! Invalid "
|
||||||
|
"decompressor cmd?\n");
|
||||||
return SDAS_INTERNAL_ERROR;
|
return SDAS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Should be unreachable, error.
|
// Should be unreachable, error.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to write to decompressor! Invalid "
|
||||||
|
"decompressor cmd?\n");
|
||||||
return SDAS_INTERNAL_ERROR;
|
return SDAS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1124,9 +1184,15 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
|
||||||
// Success.
|
// Success.
|
||||||
} else if (ferror(out_f)) {
|
} else if (ferror(out_f)) {
|
||||||
// Error.
|
// Error.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to read from decompressor! Invalid "
|
||||||
|
"decompressor cmd?\n");
|
||||||
return SDAS_INTERNAL_ERROR;
|
return SDAS_INTERNAL_ERROR;
|
||||||
} else {
|
} else {
|
||||||
// Invalid state, error.
|
// Invalid state, error.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to read from decompressor! Invalid "
|
||||||
|
"decompressor cmd?\n");
|
||||||
return SDAS_INTERNAL_ERROR;
|
return SDAS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
} else if (read_ret == -1) {
|
} else if (read_ret == -1) {
|
||||||
|
@ -1134,6 +1200,9 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
|
||||||
// No bytes to read yet.
|
// No bytes to read yet.
|
||||||
} else {
|
} else {
|
||||||
// Error.
|
// Error.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to read from decompressor! Invalid "
|
||||||
|
"decompressor cmd?\n");
|
||||||
return SDAS_INTERNAL_ERROR;
|
return SDAS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
} else if (read_ret == 0) {
|
} else if (read_ret == 0) {
|
||||||
|
@ -1143,11 +1212,21 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
|
||||||
free_FILE_helper(&out_f);
|
free_FILE_helper(&out_f);
|
||||||
} else {
|
} else {
|
||||||
// Invalid state (unreachable?), error.
|
// Invalid state (unreachable?), error.
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to read from decompressor! Invalid "
|
||||||
|
"decompressor cmd?\n");
|
||||||
return SDAS_INTERNAL_ERROR;
|
return SDAS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_sig_pipe_occurred) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Failed to write to decompressor (SIGPIPE)! "
|
||||||
|
"Invalid decompressor cmd?\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
waitpid(decompressor_pid, NULL, 0);
|
waitpid(decompressor_pid, NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
uint64_t compressed_file_size = u64;
|
uint64_t compressed_file_size = u64;
|
||||||
|
|
|
@ -90,6 +90,7 @@ int main(int argc, const char **argv) {
|
||||||
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
|
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
|
||||||
if (ret != SDAS_SUCCESS) {
|
if (ret != SDAS_SUCCESS) {
|
||||||
unlink(parsed.filename);
|
unlink(parsed.filename);
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if ((parsed.flags & 3) == 2) {
|
} else if ((parsed.flags & 3) == 2) {
|
||||||
|
@ -97,7 +98,7 @@ int main(int argc, const char **argv) {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
fprintf(stderr, "ERROR: Failed to open \"%s\" for reading!\n",
|
fprintf(stderr, "ERROR: Failed to open \"%s\" for reading!\n",
|
||||||
parsed.filename);
|
parsed.filename);
|
||||||
return 3;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = simple_archiver_parse_archive_info(file, 0, NULL);
|
int ret = simple_archiver_parse_archive_info(file, 0, NULL);
|
||||||
|
@ -112,7 +113,7 @@ int main(int argc, const char **argv) {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
fprintf(stderr, "ERROR: Failed to open \"%s\" for reading!\n",
|
fprintf(stderr, "ERROR: Failed to open \"%s\" for reading!\n",
|
||||||
parsed.filename);
|
parsed.filename);
|
||||||
return 3;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((cleanup(simple_archiver_free_state)))
|
__attribute__((cleanup(simple_archiver_free_state)))
|
||||||
|
|
Loading…
Reference in a new issue