diff --git a/main/gbc/gb_file.c b/main/gbc/gb_file.c index c22dab400..e99e0c5de 100644 --- a/main/gbc/gb_file.c +++ b/main/gbc/gb_file.c @@ -21,4 +21,8 @@ ***************************************************************************/ +#include "gb_common.h" +#include "gb_error.h" +#include "gb_alloc.h" + #include "gb_file_temp.h" diff --git a/main/gbc/gbc_archive.c b/main/gbc/gbc_archive.c index 44b68d3d9..e39e55020 100644 --- a/main/gbc/gbc_archive.c +++ b/main/gbc/gbc_archive.c @@ -130,8 +130,11 @@ static void make_executable(void) if (rename(TEMP_EXEC, ARCH_output)) { - err = "Cannot create executable"; - goto __ERROR; + if (FILE_copy(TEMP_EXEC, ARCH_output)) + { + err = "Cannot create executable"; + goto __ERROR; + } } return; diff --git a/main/share/gb_file_share.h b/main/share/gb_file_share.h index b0461c117..7ab199933 100644 --- a/main/share/gb_file_share.h +++ b/main/share/gb_file_share.h @@ -133,6 +133,7 @@ void FILE_chgrp(const char *path, const char *group); bool FILE_exist(const char *path); time_t FILE_get_time(const char *path); +bool FILE_copy(const char *src, const char *dst); #endif diff --git a/main/share/gb_file_temp.h b/main/share/gb_file_temp.h index 5b6d7592c..2169a6776 100644 --- a/main/share/gb_file_temp.h +++ b/main/share/gb_file_temp.h @@ -1039,6 +1039,55 @@ time_t FILE_get_time(const char *path) return (time_t)-1L; } +bool FILE_copy(const char *src, const char *dst) +{ + int src_fd; + int dst_fd; + ssize_t len; + char *buf = NULL; + int save_errno; + + src_fd = open(src, O_RDONLY); + if (src_fd < 0) + return TRUE; + + dst_fd = open(dst, O_WRONLY); + if (dst_fd < 0) + { + save_errno = errno; + close(src_fd); + errno = save_errno; + return TRUE; + } + + ALLOC(&buf, MAX_IO); + + for(;;) + { + len = read(src_fd, buf, MAX_IO); + if (len == 0) + break; + if (len < 0 && errno == EINTR) + continue; + if (write(dst_fd, buf, len) < 0) + { + save_errno = errno; + close(src_fd); + close(dst_fd); + unlink(dst); + errno = save_errno; + IFREE(buf); + return TRUE; + } + } + + close(src_fd); + close(dst_fd); + IFREE(buf); + + return FALSE; +} + #endif const char *FILE_getcwd(const char *subdir)