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

add zsv_fopen_wx to util/file; use exclusive write for zvs_file_copy; update configure/Makefile #173

Merged
merged 1 commit into from
Jun 24, 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
2 changes: 1 addition & 1 deletion app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ CFLAGS+= -DUSE_JQ

STATIC_LIB_FLAGS=
ifneq ($(STATIC_LIBS),)
STATIC_LIB_FLAGS=-static ${STATIC_LIBS}
STATIC_LIB_FLAGS=${LDFLAGS_STATIC}
endif

STANDALONE_PFX=${BUILD_DIR}/bin/zsv_
Expand Down
56 changes: 41 additions & 15 deletions app/utils/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,28 @@ int zsv_file_exists(const char* filename) {
}
#endif

/**
* Open a file for exclusive write (same as fopen() but opens exclusively)
* mode must be 'w' or 'wb'
*/
FILE* zsv_fopen_wx(const char *filename, const char *mode) {
if(!mode || (strcmp(mode, "w") && strcmp(mode, "wb"))) {
fprintf(stderr, "fopen_wbx mode must be 'w' or 'wb'; got %s\n", mode ? mode : "(none)");
return NULL;
}

int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644); // exclusive binary write
if(fd == -1) {
return NULL;
}

FILE *file = fdopen(fd, "wb"); // Convert to FILE*
if(file == NULL)
close(fd);

return file;
}

/**
* Copy a file, given source and destination paths
* On error, output error message and return non-zero
Expand All @@ -133,16 +155,22 @@ int zsv_copy_file(const char *src, const char *dest) {
// copy the file
int err = 0;
FILE *fsrc = fopen(src, "rb");
if(!fsrc)
err = errno ? errno : -1, perror(src);
else {
FILE *fdest = fopen(dest, "wb");
if(!fdest)
err = errno ? errno : -1, perror(dest);
else {
if(!fsrc) {
err = errno ? errno : -1;
perror(src);
} else {
FILE *fdest = zsv_fopen_wx(dest, "wb");
if(!fdest) {
err = errno ? errno : -1;
perror(dest);
} else {
err = zsv_copy_file_ptr(fsrc, fdest);
if(err)
perror(dest);
if(err) {
if(err < 0)
fprintf(stderr, "Unknown error copying %s to %s\n", src, dest);
else
perror(dest);
}
fclose(fdest);
}
fclose(fsrc);
Expand All @@ -155,16 +183,14 @@ int zsv_copy_file(const char *src, const char *dest) {
* Return error number per errno.h
*/
int zsv_copy_file_ptr(FILE *src, FILE *dest) {
int err = 0;
errno = 0;
char buffer[4096];
size_t bytes_read;
while((bytes_read = fread(buffer, 1, sizeof(buffer), src)) > 0) {
if(fwrite(buffer, 1, bytes_read, dest) != bytes_read) {
err = errno ? errno : -1;
break;
}
if(fwrite(buffer, 1, bytes_read, dest) != bytes_read)
return errno ? errno : -1;
}
return err;
return errno;
}

size_t zsv_dir_len_basename(const char *filepath, const char **basename) {
Expand Down
2 changes: 2 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ _ACEOF
tryflag CFLAGS_TRY -Werror=unknown-warning-option
tryflag CFLAGS_TRY -Werror=unused-command-line-argument
tryflag CFLAGS_TRY -Werror=ignored-optimization-argument
tryldflag LDFLAGS_STATIC -static
tryldflag LDFLAGS_TRY -Werror=unknown-warning-option
tryldflag LDFLAGS_TRY -Werror=unused-command-line-argument
tryldflag LDFLAGS_TRY -Werror=ignored-optimization-argument
Expand Down Expand Up @@ -729,6 +730,7 @@ CFLAGS_PIC = $CFLAGS_PIC
LDFLAGS_PIC = $LDFLAGS_PIC
CFLAGS_PIE = $CFLAGS_PIE
LDFLAGS_PIE = $LDFLAGS_PIE
LDFLAGS_STATIC = $LDFLAGS_STATIC
USE_DEBUG_STDERR = $USE_DEBUG_STDERR
CFLAGS_VECTORIZE = $CFLAGS_VECTORIZE
CFLAGS_VECTORIZE_OPTIMIZED = $CFLAGS_VECTORIZE_OPTIMIZED
Expand Down
6 changes: 6 additions & 0 deletions include/zsv/utils/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ size_t zsv_filter_write(void *FILEp, unsigned char *buff, size_t bytes_read);
*/
size_t zsv_dir_len_basename(const char *filepath, const char **basename);

/**
* Open a file for exclusive write (same as fopen() but opens exclusively)
* mode must be 'w' or 'wb'
*/
FILE* zsv_fopen_wx(const char *filename, const char *mode);

/**
* Copy a file. Create any needed directories
* On error, prints error message and returns non-zero
Expand Down
Loading