Skip to content

Commit

Permalink
Merge pull request #301 from Gottox/fix/unpack-unlocked-stdout
Browse files Browse the repository at this point in the history
unpack: make sure stdout is locked
  • Loading branch information
Gottox authored Dec 13, 2024
2 parents d1e8116 + 00bef59 commit 0ab77ca
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 25 deletions.
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);
}

void
locked_fprintf(FILE *stream, const char *format, ...) {
va_list args;
va_start(args, format);
pthread_mutex_lock(&output_lock);
vfprintf(stream, format, args);
pthread_mutex_unlock(&output_lock);
va_end(args);
}

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 @@ open_archive(const char *image_path, uint64_t offset, int *err) {

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);
break;
case '\r':
fputs("\\r", stdout);
locked_fputs("\\r", stdout);
break;
case '\t':
fputs("\\t", stdout);
locked_fputs("\\t", stdout);
break;
case '\\':
fputs("\\\\", stdout);
locked_fputs("\\\\", stdout);
break;
case '\x1b':
fputs("\\e", stdout);
locked_fputs("\\e", stdout);
break;
case 0x01:
case 0x02:
Expand Down Expand Up @@ -106,10 +151,10 @@ print_escaped(const char *segment, size_t segment_size) {
case 0x1f:
case 0x20:
case 0x7f:
printf("\\x%02x", segment[i]);
locked_fprintf(stdout, "\\x%02x", segment[i]);
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 @@ update_metadata(const char *path, const struct SqshFile *file) {
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);
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);
goto out;
}

Expand All @@ -105,7 +104,7 @@ update_metadata(const char *path, const struct SqshFile *file) {

rv = chown(path, uid, gid);
if (rv < 0) {
perror(path);
locked_perror(path);
goto out;
}
}
Expand All @@ -122,17 +121,17 @@ extract_dir(const char *path) {
struct stat st;
rv = stat(path, &st);
if (rv < 0) {
perror(path);
locked_perror(path);
goto out;
}
if (!S_ISDIR(st.st_mode)) {
errno = EEXIST;
perror(path);
locked_perror(path);
goto out;
}

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

Expand All @@ -147,7 +146,7 @@ update_metadata_dir(const char *path, const struct SqshFile *file) {
int rv = 0;
rv = chmod(path, sqsh_file_permission(file));
if (rv < 0) {
perror(path);
locked_perror(path);
goto out;
}

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

rv = rename(data->tmp_filename, data->path);
Expand All @@ -194,7 +193,7 @@ extract_file_after(
out:
cx_semaphore_post(&file_descriptor_sem);
if (rv < 0) {
sqsh_perror(rv, data->path);
locked_sqsh_perror(rv, data->path);
}
extract_file_cleanup(data, NULL);
}
Expand Down Expand Up @@ -261,7 +260,7 @@ extract_file(const char *path, const struct SqshFile *file) {
}
out:
if (rv < 0) {
sqsh_perror(rv, path);
locked_sqsh_perror(rv, path);
extract_file_cleanup(data, stream);
if (fd > 0) {
close(fd);
Expand Down Expand Up @@ -389,7 +388,7 @@ extract_from_traversal(
} else {
file = sqsh_tree_traversal_open_file(iter, &rv);
if (rv < 0) {
sqsh_perror(rv, path);
locked_sqsh_perror(rv, path);
goto out;
}

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

iter = sqsh_tree_traversal_new(base, &rv);
if (rv < 0) {
sqsh_perror(rv, image_path);
locked_sqsh_perror(rv, image_path);
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);
goto out;
}

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

Expand Down Expand Up @@ -505,7 +504,7 @@ main(int argc, char *argv[]) {

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 @@ main(int argc, char *argv[]) {

src_root = sqsh_lopen(sqsh, src_path, &rv);
if (rv < 0) {
sqsh_perror(rv, src_path);
locked_sqsh_perror(rv, src_path);
rv = EXIT_FAILURE;
goto out;
}
Expand Down

0 comments on commit 0ab77ca

Please sign in to comment.