Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unpack: make sure stdout is locked #301

Merged
merged 1 commit into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions tools/include/sqshtools_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,17 @@ void print_raw(const char *segment, size_t segment_size);

void print_escaped(const char *segment, size_t segment_size);

void locked_perror(const char *msg);

void locked_sqsh_perror(int error_code, const char *msg);

void locked_perror(const char *msg);

__attribute__((__format__(__printf__, 2, 0))) void
locked_fprintf(FILE *stream, const char *format, ...);

void locked_fputs(const char *s, FILE *stream);

int locked_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

#endif /* TOOLS_COMMON_H */
61 changes: 53 additions & 8 deletions tools/src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,52 @@
* @created Wednesday Jun 07, 2023 15:41:30 CEST
*/

#include "sqsh_error.h"
#include <pthread.h>
#include <sqshtools_common.h>
#include <stdarg.h>

pthread_mutex_t output_lock = PTHREAD_MUTEX_INITIALIZER;

void
locked_perror(const char *msg) {
pthread_mutex_lock(&output_lock);
perror(msg);
pthread_mutex_unlock(&output_lock);
}

Check warning on line 47 in tools/src/common.c

View check run for this annotation

Codecov / codecov/patch

tools/src/common.c#L43-L47

Added lines #L43 - L47 were not covered by tests

void
locked_fprintf(FILE *stream, const char *format, ...) {

Check warning on line 50 in tools/src/common.c

View check run for this annotation

Codecov / codecov/patch

tools/src/common.c#L50

Added line #L50 was not covered by tests
va_list args;
va_start(args, format);
pthread_mutex_lock(&output_lock);
vfprintf(stream, format, args);
pthread_mutex_unlock(&output_lock);
va_end(args);
}

Check warning on line 57 in tools/src/common.c

View check run for this annotation

Codecov / codecov/patch

tools/src/common.c#L52-L57

Added lines #L52 - L57 were not covered by tests

void
locked_fputs(const char *s, FILE *stream) {
pthread_mutex_lock(&output_lock);
fputs(s, stream);
pthread_mutex_unlock(&output_lock);
}

int
locked_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
int ret;
pthread_mutex_lock(&output_lock);
ret = fwrite(ptr, size, nmemb, stream);
pthread_mutex_unlock(&output_lock);
return ret;
}

void
locked_sqsh_perror(int error_code, const char *msg) {
pthread_mutex_lock(&output_lock);
sqsh_perror(error_code, msg);
pthread_mutex_unlock(&output_lock);
}

struct SqshArchive *
open_archive(const char *image_path, uint64_t offset, int *err) {
Expand All @@ -55,27 +100,27 @@

void
print_raw(const char *segment, size_t segment_size) {
fwrite(segment, 1, segment_size, stdout);
locked_fwrite(segment, 1, segment_size, stdout);
}

void
print_escaped(const char *segment, size_t segment_size) {
for (size_t i = 0; i < segment_size; i++) {
switch (segment[i]) {
case '\n':
fputs("\\n", stdout);
locked_fputs("\\n", stdout);

Check warning on line 111 in tools/src/common.c

View check run for this annotation

Codecov / codecov/patch

tools/src/common.c#L111

Added line #L111 was not covered by tests
break;
case '\r':
fputs("\\r", stdout);
locked_fputs("\\r", stdout);

Check warning on line 114 in tools/src/common.c

View check run for this annotation

Codecov / codecov/patch

tools/src/common.c#L114

Added line #L114 was not covered by tests
break;
case '\t':
fputs("\\t", stdout);
locked_fputs("\\t", stdout);

Check warning on line 117 in tools/src/common.c

View check run for this annotation

Codecov / codecov/patch

tools/src/common.c#L117

Added line #L117 was not covered by tests
break;
case '\\':
fputs("\\\\", stdout);
locked_fputs("\\\\", stdout);

Check warning on line 120 in tools/src/common.c

View check run for this annotation

Codecov / codecov/patch

tools/src/common.c#L120

Added line #L120 was not covered by tests
break;
case '\x1b':
fputs("\\e", stdout);
locked_fputs("\\e", stdout);
break;
case 0x01:
case 0x02:
Expand Down Expand Up @@ -106,10 +151,10 @@
case 0x1f:
case 0x20:
case 0x7f:
printf("\\x%02x", segment[i]);
locked_fprintf(stdout, "\\x%02x", segment[i]);

Check warning on line 154 in tools/src/common.c

View check run for this annotation

Codecov / codecov/patch

tools/src/common.c#L154

Added line #L154 was not covered by tests
break;
default:
putchar(segment[i]);
locked_fputs((char[2]){segment[i], 0}, stdout);
break;
}
}
Expand Down
33 changes: 16 additions & 17 deletions tools/src/unpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
Expand Down Expand Up @@ -88,14 +87,14 @@
times[0].tv_sec = times[1].tv_sec = sqsh_file_modified_time(file);
rv = utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW);
if (rv < 0) {
perror(path);
locked_perror(path);

Check warning on line 90 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L90

Added line #L90 was not covered by tests
goto out;
}

uint16_t mode = sqsh_file_permission(file);
rv = fchmodat(AT_FDCWD, path, mode, AT_SYMLINK_NOFOLLOW);
if (rv < 0) {
perror(path);
locked_perror(path);

Check warning on line 97 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L97

Added line #L97 was not covered by tests
goto out;
}

Expand All @@ -105,7 +104,7 @@

rv = chown(path, uid, gid);
if (rv < 0) {
perror(path);
locked_perror(path);

Check warning on line 107 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L107

Added line #L107 was not covered by tests
goto out;
}
}
Expand All @@ -122,17 +121,17 @@
struct stat st;
rv = stat(path, &st);
if (rv < 0) {
perror(path);
locked_perror(path);

Check warning on line 124 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L124

Added line #L124 was not covered by tests
goto out;
}
if (!S_ISDIR(st.st_mode)) {
errno = EEXIST;
perror(path);
locked_perror(path);

Check warning on line 129 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L129

Added line #L129 was not covered by tests
goto out;
}

} else if (rv < 0) {
perror(path);
locked_perror(path);

Check warning on line 134 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L134

Added line #L134 was not covered by tests
goto out;
}

Expand All @@ -147,7 +146,7 @@
int rv = 0;
rv = chmod(path, sqsh_file_permission(file));
if (rv < 0) {
perror(path);
locked_perror(path);

Check warning on line 149 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L149

Added line #L149 was not covered by tests
goto out;
}

Expand Down Expand Up @@ -180,7 +179,7 @@
int rv = 0;
struct ExtractFileData *data = d;
if (err < 0) {
sqsh_perror(err, data->path);
locked_sqsh_perror(err, data->path);

Check warning on line 182 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L182

Added line #L182 was not covered by tests
}

rv = rename(data->tmp_filename, data->path);
Expand All @@ -194,7 +193,7 @@
out:
cx_semaphore_post(&file_descriptor_sem);
if (rv < 0) {
sqsh_perror(rv, data->path);
locked_sqsh_perror(rv, data->path);

Check warning on line 196 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L196

Added line #L196 was not covered by tests
}
extract_file_cleanup(data, NULL);
}
Expand Down Expand Up @@ -261,7 +260,7 @@
}
out:
if (rv < 0) {
sqsh_perror(rv, path);
locked_sqsh_perror(rv, path);

Check warning on line 263 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L263

Added line #L263 was not covered by tests
extract_file_cleanup(data, stream);
if (fd > 0) {
close(fd);
Expand Down Expand Up @@ -389,7 +388,7 @@
} else {
file = sqsh_tree_traversal_open_file(iter, &rv);
if (rv < 0) {
sqsh_perror(rv, path);
locked_sqsh_perror(rv, path);

Check warning on line 391 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L391

Added line #L391 was not covered by tests
goto out;
}

Expand Down Expand Up @@ -423,14 +422,14 @@

iter = sqsh_tree_traversal_new(base, &rv);
if (rv < 0) {
sqsh_perror(rv, image_path);
locked_sqsh_perror(rv, image_path);

Check warning on line 425 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L425

Added line #L425 was not covered by tests
goto out;
}

bool has_next = sqsh_tree_traversal_next(iter, &rv);
if (!has_next) {
rv = -SQSH_ERROR_INTERNAL;
sqsh_perror(rv, image_path);
locked_sqsh_perror(rv, image_path);

Check warning on line 432 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L432

Added line #L432 was not covered by tests
goto out;
}

Expand All @@ -441,7 +440,7 @@
}
}
if (rv < 0) {
sqsh_perror(rv, image_path);
locked_sqsh_perror(rv, image_path);

Check warning on line 443 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L443

Added line #L443 was not covered by tests
goto out;
}

Expand Down Expand Up @@ -505,7 +504,7 @@

sqsh = open_archive(image_path, offset, &rv);
if (rv < 0) {
sqsh_perror(rv, image_path);
locked_sqsh_perror(rv, image_path);
rv = EXIT_FAILURE;
goto out;
}
Expand All @@ -528,7 +527,7 @@

src_root = sqsh_lopen(sqsh, src_path, &rv);
if (rv < 0) {
sqsh_perror(rv, src_path);
locked_sqsh_perror(rv, src_path);

Check warning on line 530 in tools/src/unpack.c

View check run for this annotation

Codecov / codecov/patch

tools/src/unpack.c#L530

Added line #L530 was not covered by tests
rv = EXIT_FAILURE;
goto out;
}
Expand Down
Loading