Skip to content

Commit

Permalink
add zsv_fopen_wx to util/file; use exclusive write for zvs_file_copy (#…
Browse files Browse the repository at this point in the history
…173)

fix configure/Makefile to work for compilers that do not work with -static
  • Loading branch information
liquidaty authored Jun 24, 2024
1 parent 1789992 commit 50a7c83
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 16 deletions.
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

0 comments on commit 50a7c83

Please sign in to comment.