Commit a26800c099
Changed files (4)
src/main.cpp
@@ -1309,7 +1309,7 @@ static int main0(int argc, char **argv) {
Buf *dest_path = buf_alloc();
os_path_join(final_output_dir_step, dest_basename, dest_path);
- if ((err = os_copy_file(&g->output_file_path, dest_path))) {
+ if ((err = os_update_file(&g->output_file_path, dest_path))) {
fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->output_file_path),
buf_ptr(dest_path), err_str(err));
return main_exit(root_progress_node, EXIT_FAILURE);
src/os.cpp
@@ -1029,6 +1029,110 @@ Error os_write_file(Buf *full_path, Buf *contents) {
return ErrorNone;
}
+static Error copy_open_files(FILE *src_f, FILE *dest_f) {
+ static const size_t buf_size = 2048;
+ char buf[buf_size];
+ for (;;) {
+ size_t amt_read = fread(buf, 1, buf_size, src_f);
+ if (amt_read != buf_size) {
+ if (ferror(src_f)) {
+ return ErrorFileSystem;
+ }
+ }
+ size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
+ if (amt_written != amt_read) {
+ return ErrorFileSystem;
+ }
+ if (feof(src_f)) {
+ return ErrorNone;
+ }
+ }
+}
+
+#if defined(ZIG_OS_WINDOWS)
+static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
+ mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
+ mtime->nsec = 0;
+}
+static FILETIME windows_os_timestamp_to_filetime(OsTimeStamp mtime) {
+ FILETIME result;
+ result.dwHighDateTime = mtime.sec >> 32;
+ result.dwLowDateTime = mtime.sec;
+ return result;
+}
+#endif
+
+static Error set_file_times(OsFile file, OsTimeStamp ts) {
+#if defined(ZIG_OS_WINDOWS)
+ const atime_ft = windows.nanoSecondsToFileTime(atime);
+ const mtime_ft = windows.nanoSecondsToFileTime(mtime);
+ return SetFileTime(file, null, &atime_ft, &mtime_ft);
+#else
+ struct timespec times[2] = {
+ { ts.sec, ts.nsec },
+ { ts.sec, ts.nsec },
+ };
+ if (futimens(file, times) == -1) {
+ switch (errno) {
+ case EBADF:
+ zig_panic("futimens EBADF");
+ default:
+ return ErrorUnexpected;
+ }
+ }
+ return ErrorNone;
+#endif
+}
+
+Error os_update_file(Buf *src_path, Buf *dst_path) {
+ Error err;
+
+ OsFile src_file;
+ OsFileAttr src_attr;
+ if ((err = os_file_open_r(src_path, &src_file, &src_attr))) {
+ return err;
+ }
+
+ OsFile dst_file;
+ OsFileAttr dst_attr;
+ if ((err = os_file_open_w(dst_path, &dst_file, &dst_attr, src_attr.mode))) {
+ os_file_close(&src_file);
+ return err;
+ }
+
+ if (src_attr.mtime.sec == dst_attr.mtime.sec &&
+ src_attr.mtime.nsec == dst_attr.mtime.nsec &&
+ src_attr.mode == dst_attr.mode)
+ {
+ os_file_close(&src_file);
+ os_file_close(&dst_file);
+ return ErrorNone;
+ }
+
+ FILE *src_libc_file = fdopen(src_file, "rb");
+ FILE *dst_libc_file = fdopen(dst_file, "wb");
+ assert(src_libc_file);
+ assert(dst_libc_file);
+ if (ftruncate(dst_file, 0) == -1) {
+ return ErrorUnexpected;
+ }
+ if ((err = copy_open_files(src_libc_file, dst_libc_file))) {
+ fclose(src_libc_file);
+ fclose(dst_libc_file);
+ return err;
+ }
+ if (fflush(src_libc_file) == -1) {
+ return ErrorUnexpected;
+ }
+ if (fflush(dst_libc_file) == -1) {
+ return ErrorUnexpected;
+ }
+ err = set_file_times(dst_file, src_attr.mtime);
+ fclose(src_libc_file);
+ fclose(dst_libc_file);
+ return err;
+}
+
Error os_copy_file(Buf *src_path, Buf *dest_path) {
FILE *src_f = fopen(buf_ptr(src_path), "rb");
if (!src_f) {
@@ -1055,30 +1159,10 @@ Error os_copy_file(Buf *src_path, Buf *dest_path) {
return ErrorFileSystem;
}
}
-
- static const size_t buf_size = 2048;
- char buf[buf_size];
- for (;;) {
- size_t amt_read = fread(buf, 1, buf_size, src_f);
- if (amt_read != buf_size) {
- if (ferror(src_f)) {
- fclose(src_f);
- fclose(dest_f);
- return ErrorFileSystem;
- }
- }
- size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
- if (amt_written != amt_read) {
- fclose(src_f);
- fclose(dest_f);
- return ErrorFileSystem;
- }
- if (feof(src_f)) {
- fclose(src_f);
- fclose(dest_f);
- return ErrorNone;
- }
- }
+ Error err = copy_open_files(src_f, dest_f);
+ fclose(src_f);
+ fclose(dest_f);
+ return err;
}
Error os_fetch_file_path(Buf *full_path, Buf *out_contents) {
@@ -1218,13 +1302,6 @@ Error os_rename(Buf *src_path, Buf *dest_path) {
return ErrorNone;
}
-#if defined(ZIG_OS_WINDOWS)
-static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
- mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
- mtime->nsec = 0;
-}
-#endif
-
OsTimeStamp os_timestamp_calendar(void) {
OsTimeStamp result;
#if defined(ZIG_OS_WINDOWS)
@@ -1733,10 +1810,15 @@ Error os_self_exe_shared_libs(ZigList<Buf *> &paths) {
#endif
}
-Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
+Error os_file_open_rw(Buf *full_path, OsFile *out_file, OsFileAttr *attr, bool need_write, uint32_t mode) {
#if defined(ZIG_OS_WINDOWS)
// TODO use CreateFileW
- HANDLE result = CreateFileA(buf_ptr(full_path), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+ HANDLE result = CreateFileA(buf_ptr(full_path),
+ need_write ? (GENERIC_READ|GENERIC_WRITE) : GENERIC_READ,
+ need_write ? 0 : FILE_SHARE_READ,
+ nullptr,
+ need_write ? OPEN_ALWAYS : OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, nullptr);
if (result == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
@@ -1769,12 +1851,14 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
}
windows_filetime_to_os_timestamp(&file_info.ftLastWriteTime, &attr->mtime);
attr->inode = (((uint64_t)file_info.nFileIndexHigh) << 32) | file_info.nFileIndexLow;
+ attr->mode = 0;
}
return ErrorNone;
#else
for (;;) {
- int fd = open(buf_ptr(full_path), O_RDONLY|O_CLOEXEC);
+ int fd = open(buf_ptr(full_path),
+ need_write ? (O_RDWR|O_CLOEXEC|O_CREAT) : (O_RDONLY|O_CLOEXEC), mode);
if (fd == -1) {
switch (errno) {
case EINTR:
@@ -1784,6 +1868,7 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
case EFAULT:
zig_unreachable();
case EACCES:
+ case EPERM:
return ErrorAccess;
case EISDIR:
return ErrorIsDir;
@@ -1813,12 +1898,21 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
attr->mtime.sec = statbuf.st_mtim.tv_sec;
attr->mtime.nsec = statbuf.st_mtim.tv_nsec;
#endif
+ attr->mode = statbuf.st_mode;
}
return ErrorNone;
}
#endif
}
+Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
+ return os_file_open_rw(full_path, out_file, attr, false, 0);
+}
+
+Error os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode) {
+ return os_file_open_rw(full_path, out_file, attr, true, mode);
+}
+
Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
#if defined(ZIG_OS_WINDOWS)
for (;;) {
@@ -1864,6 +1958,7 @@ Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
case EFAULT:
zig_unreachable();
case EACCES:
+ case EPERM:
return ErrorAccess;
case EISDIR:
return ErrorIsDir;
src/os.hpp
@@ -93,13 +93,14 @@ struct Termination {
#endif
struct OsTimeStamp {
- uint64_t sec;
- uint64_t nsec;
+ int64_t sec;
+ int64_t nsec;
};
struct OsFileAttr {
OsTimeStamp mtime;
uint64_t inode;
+ uint32_t mode;
};
int os_init(void);
@@ -121,6 +122,7 @@ Error ATTRIBUTE_MUST_USE os_make_path(Buf *path);
Error ATTRIBUTE_MUST_USE os_make_dir(Buf *path);
Error ATTRIBUTE_MUST_USE os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr);
+Error ATTRIBUTE_MUST_USE os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode);
Error ATTRIBUTE_MUST_USE os_file_open_lock_rw(Buf *full_path, OsFile *out_file);
Error ATTRIBUTE_MUST_USE os_file_read(OsFile file, void *ptr, size_t *len);
Error ATTRIBUTE_MUST_USE os_file_read_all(OsFile file, Buf *contents);
@@ -129,6 +131,7 @@ void os_file_close(OsFile *file);
Error ATTRIBUTE_MUST_USE os_write_file(Buf *full_path, Buf *contents);
Error ATTRIBUTE_MUST_USE os_copy_file(Buf *src_path, Buf *dest_path);
+Error ATTRIBUTE_MUST_USE os_update_file(Buf *src_path, Buf *dest_path);
Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents);
Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents);
CMakeLists.txt
@@ -565,12 +565,12 @@ set_target_properties(opt_c_util PROPERTIES
COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
)
-add_library(compiler STATIC ${ZIG_SOURCES})
-set_target_properties(compiler PROPERTIES
+add_library(zigcompiler STATIC ${ZIG_SOURCES})
+set_target_properties(zigcompiler PROPERTIES
COMPILE_FLAGS ${EXE_CFLAGS}
LINK_FLAGS ${EXE_LDFLAGS}
)
-target_link_libraries(compiler LINK_PUBLIC
+target_link_libraries(zigcompiler LINK_PUBLIC
zig_cpp
opt_c_util
${SOFTFLOAT_LIBRARIES}
@@ -580,15 +580,15 @@ target_link_libraries(compiler LINK_PUBLIC
${CMAKE_THREAD_LIBS_INIT}
)
if(NOT MSVC)
- target_link_libraries(compiler LINK_PUBLIC ${LIBXML2})
+ target_link_libraries(zigcompiler LINK_PUBLIC ${LIBXML2})
endif()
if(ZIG_DIA_GUIDS_LIB)
- target_link_libraries(compiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
+ target_link_libraries(zigcompiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
endif()
if(MSVC OR MINGW)
- target_link_libraries(compiler LINK_PUBLIC version)
+ target_link_libraries(zigcompiler LINK_PUBLIC version)
endif()
add_executable(zig0 "${ZIG_MAIN_SRC}" "${ZIG0_SHIM_SRC}")
@@ -596,12 +596,12 @@ set_target_properties(zig0 PROPERTIES
COMPILE_FLAGS ${EXE_CFLAGS}
LINK_FLAGS ${EXE_LDFLAGS}
)
-target_link_libraries(zig0 compiler)
+target_link_libraries(zig0 zigcompiler)
if(MSVC)
- set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/stage2.lib")
+ set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/zigstage2.lib")
else()
- set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libstage2.a")
+ set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libzigstage2.a")
endif()
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(LIBSTAGE2_RELEASE_ARG "")
@@ -615,11 +615,12 @@ else()
endif()
set(BUILD_LIBSTAGE2_ARGS "build-lib"
+ "src-self-hosted/stage2.zig"
+ --name zigstage2
--override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
--cache on
--output-dir "${CMAKE_BINARY_DIR}"
${LIBSTAGE2_RELEASE_ARG}
- "src-self-hosted/stage2.zig"
--disable-gen-h
--bundle-compiler-rt
-fPIC
@@ -639,7 +640,7 @@ set_target_properties(zig PROPERTIES
COMPILE_FLAGS ${EXE_CFLAGS}
LINK_FLAGS ${EXE_LDFLAGS}
)
-target_link_libraries(zig compiler "${LIBSTAGE2}")
+target_link_libraries(zig zigcompiler "${LIBSTAGE2}")
if(MSVC)
target_link_libraries(zig ntdll.lib)
elseif(MINGW)