From 347dba1533c051405090f354306bf057621d5323 Mon Sep 17 00:00:00 2001 From: wysiengnik11 <49038699+wysiengnik11@users.noreply.github.com> Date: Mon, 22 Jan 2024 00:00:03 +0100 Subject: [PATCH 1/4] Update nob_file_exists to distinguish between errors on windows. Update nob_file_exists to distinguish between "does not exists" and other windows errors (todo). Couldn't get nob to compile and thought #if _WIN32 was the cause, forked already, and then noticed that it doesn't matter, it was something on my end. So I decided to just go ahead and fix something, and #ifdef _WIN32 is now just a consistancy/cleanliness bonus. Had some trouble with FormatMessage, so helped myself to the answer from stackoverflow.com/questions/455434 --- src/nob.h | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/nob.h b/src/nob.h index b44d70e..82fc2ca 100644 --- a/src/nob.h +++ b/src/nob.h @@ -222,7 +222,7 @@ int nob_file_exists(const char *file_path); // TODO: add MinGW support for Go Rebuild Urself™ Technology #ifndef NOB_REBUILD_URSELF -# if _WIN32 +# ifdef _WIN32 # if defined(__GNUC__) # define NOB_REBUILD_URSELF(binary_path, source_path) "gcc", "-o", binary_path, source_path # elif defined(__clang__) @@ -1054,10 +1054,25 @@ bool nob_sv_eq(Nob_String_View a, Nob_String_View b) // -1 - error while checking if file exists. The error is logged int nob_file_exists(const char *file_path) { -#if _WIN32 - // TODO: distinguish between "does not exists" and other errors +#ifdef _WIN32 DWORD dwAttrib = GetFileAttributesA(file_path); - return dwAttrib != INVALID_FILE_ATTRIBUTES; + if (dwAttrib == INVALID_FILE_ATTRIBUTES) { + if (GetLastError() == 2) return 0; + + LPTSTR errorText = NULL; + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM + |FORMAT_MESSAGE_ALLOCATE_BUFFER + |FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&errorText, 0, NULL); + + nob_log(NOB_ERROR, "Could not check if file %s exists: %s", file_path, errorText); + LocalFree(errorText); + return -1; + } + return 1; #else struct stat statbuf; if (stat(file_path, &statbuf) < 0) { From 473e551ed86409029facf9dbd62ee34d9e71c6ac Mon Sep 17 00:00:00 2001 From: wysiengnik11 <49038699+wysiengnik11@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:40:14 +0100 Subject: [PATCH 2/4] Upgrade windows error handling Just made a little function and started blasting. --- src/nob.h | 82 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/src/nob.h b/src/nob.h index 82fc2ca..34eb3e8 100644 --- a/src/nob.h +++ b/src/nob.h @@ -1,5 +1,6 @@ // This is a complete backward incompatible rewrite of https://github.com/tsoding/nobuild // because I'm really unhappy with the direction it is going. It's gonna sit in this repo +// [Sir_Lurksal0t] I hereby yoink, repo referenced: https://github.com/tsoding/musializer // until it's matured enough and then I'll probably extract it to its own repo. // Copyright 2023 Alexey Kutepov @@ -235,6 +236,24 @@ int nob_file_exists(const char *file_path); # endif #endif +#ifdef _WIN32 +// utility function +// returns a pointer to a human readable string with the name of the last windows error (GetLastError()) +// YOU need to LocalFree( result ) after you're done with it! (just see how it's used below) +char* nob_get_last_windows_error_name() +{ + LPTSTR result = NULL; + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM + |FORMAT_MESSAGE_ALLOCATE_BUFFER + |FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&result, 0, NULL); + return result; +} +#endif //_WIN32 + // Go Rebuild Urself™ Technology // // How to use it: @@ -402,7 +421,9 @@ bool nob_copy_file(const char *src_path, const char *dst_path) nob_log(NOB_INFO, "copying %s -> %s", src_path, dst_path); #ifdef _WIN32 if (!CopyFile(src_path, dst_path, FALSE)) { - nob_log(NOB_ERROR, "Could not copy file: %lu", GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not copy file: %s", errorText); + LocalFree(errorText); return false; } return true; @@ -514,7 +535,9 @@ Nob_Proc nob_cmd_run_async(Nob_Cmd cmd) nob_sb_free(sb); if (!bSuccess) { - nob_log(NOB_ERROR, "Could not create child process: %lu", GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not create child process: %s", errorText); + LocalFree(errorText); return NOB_INVALID_PROC; } @@ -566,18 +589,24 @@ bool nob_proc_wait(Nob_Proc proc) ); if (result == WAIT_FAILED) { - nob_log(NOB_ERROR, "could not wait on child process: %lu", GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not wait on child process: %s", errorText); + LocalFree(errorText); return false; } DWORD exit_status; if (!GetExitCodeProcess(proc, &exit_status)) { - nob_log(NOB_ERROR, "could not get process exit code: %lu", GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not get process exit code: %s", errorText); + LocalFree(errorText); return false; } if (exit_status != 0) { - nob_log(NOB_ERROR, "command exited with exit code %lu", exit_status); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Command exited with exit code: %s", errorText); + LocalFree(errorText); return false; } @@ -716,7 +745,9 @@ Nob_File_Type nob_get_file_type(const char *path) #ifdef _WIN32 DWORD attr = GetFileAttributesA(path); if (attr == INVALID_FILE_ATTRIBUTES) { - nob_log(NOB_ERROR, "Could not get file attributes of %s: %lu", path, GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not get file attributes of %s: %s", path, errorText); + LocalFree(errorText); return -1; } @@ -872,14 +903,18 @@ int nob_needs_rebuild(const char *output_path, const char **input_paths, size_t if (output_path_fd == INVALID_HANDLE_VALUE) { // NOTE: if output does not exist it 100% must be rebuilt if (GetLastError() == ERROR_FILE_NOT_FOUND) return 1; - nob_log(NOB_ERROR, "Could not open file %s: %lu", output_path, GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not open file %s: %s", output_path, errorText); + LocalFree(errorText); return -1; } FILETIME output_path_time; bSuccess = GetFileTime(output_path_fd, NULL, NULL, &output_path_time); CloseHandle(output_path_fd); if (!bSuccess) { - nob_log(NOB_ERROR, "Could not get time of %s: %lu", output_path, GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not open file %s: %s", output_path, errorText); + LocalFree(errorText); return -1; } @@ -888,14 +923,18 @@ int nob_needs_rebuild(const char *output_path, const char **input_paths, size_t HANDLE input_path_fd = CreateFile(input_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if (input_path_fd == INVALID_HANDLE_VALUE) { // NOTE: non-existing input is an error cause it is needed for building in the first place - nob_log(NOB_ERROR, "Could not open file %s: %lu", input_path, GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not open file %s: %s", input_path, errorText); + LocalFree(errorText); return -1; } FILETIME input_path_time; bSuccess = GetFileTime(input_path_fd, NULL, NULL, &input_path_time); CloseHandle(input_path_fd); if (!bSuccess) { - nob_log(NOB_ERROR, "Could not get time of %s: %lu", input_path, GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not get time of %s: %s", input_path, errorText); + LocalFree(errorText); return -1; } @@ -938,15 +977,17 @@ int nob_needs_rebuild1(const char *output_path, const char *input_path) bool nob_rename(const char *old_path, const char *new_path) { - nob_log(NOB_INFO, "renaming %s -> %s", old_path, new_path); + nob_log(NOB_INFO, "Renaming %s -> %s", old_path, new_path); #ifdef _WIN32 if (!MoveFileEx(old_path, new_path, MOVEFILE_REPLACE_EXISTING)) { - nob_log(NOB_ERROR, "could not rename %s to %s: %lu", old_path, new_path, GetLastError()); + LPTSTR errorText = nob_get_last_windows_error_name(); + nob_log(NOB_ERROR, "Could not rename %s to %s: %s", old_path, new_path, errorText); + LocalFree(errorText); return false; } #else if (rename(old_path, new_path) < 0) { - nob_log(NOB_ERROR, "could not rename %s to %s: %s", old_path, new_path, strerror(errno)); + nob_log(NOB_ERROR, "Could not rename %s to %s: %s", old_path, new_path, strerror(errno)); return false; } #endif // _WIN32 @@ -1054,20 +1095,11 @@ bool nob_sv_eq(Nob_String_View a, Nob_String_View b) // -1 - error while checking if file exists. The error is logged int nob_file_exists(const char *file_path) { -#ifdef _WIN32 +#ifdef _WIN32 DWORD dwAttrib = GetFileAttributesA(file_path); if (dwAttrib == INVALID_FILE_ATTRIBUTES) { - if (GetLastError() == 2) return 0; - - LPTSTR errorText = NULL; - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM - |FORMAT_MESSAGE_ALLOCATE_BUFFER - |FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&errorText, 0, NULL); - + if (GetLastError() == ERROR_FILE_NOT_FOUND) return 0; + LPTSTR errorText = nob_get_last_windows_error_name(); nob_log(NOB_ERROR, "Could not check if file %s exists: %s", file_path, errorText); LocalFree(errorText); return -1; From 007daa258f364bed4832b5e587f5f3e8fd832304 Mon Sep 17 00:00:00 2001 From: wysiengnik11 <49038699+wysiengnik11@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:53:52 +0100 Subject: [PATCH 3/4] Update nob.h That wasn't supposed to be in there... --- src/nob.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nob.h b/src/nob.h index 34eb3e8..1fcdb2d 100644 --- a/src/nob.h +++ b/src/nob.h @@ -1,6 +1,5 @@ // This is a complete backward incompatible rewrite of https://github.com/tsoding/nobuild // because I'm really unhappy with the direction it is going. It's gonna sit in this repo -// [Sir_Lurksal0t] I hereby yoink, repo referenced: https://github.com/tsoding/musializer // until it's matured enough and then I'll probably extract it to its own repo. // Copyright 2023 Alexey Kutepov From 24994c93932ed79a93fdc80c029b23b55c0d9290 Mon Sep 17 00:00:00 2001 From: wysiengnik11 <49038699+wysiengnik11@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:55:35 +0100 Subject: [PATCH 4/4] Roll back an accidental over-eagarness When implementing previous changes to windows error reporting, exit status of user ran commands would get ran through nob_get_last_windows_error_name and return erroneous windows error messages. --- src/nob.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/nob.h b/src/nob.h index 1fcdb2d..692de42 100644 --- a/src/nob.h +++ b/src/nob.h @@ -603,9 +603,7 @@ bool nob_proc_wait(Nob_Proc proc) } if (exit_status != 0) { - LPTSTR errorText = nob_get_last_windows_error_name(); - nob_log(NOB_ERROR, "Command exited with exit code: %s", errorText); - LocalFree(errorText); + nob_log(NOB_ERROR, "Command exited with exit code: %d", exit_status); return false; }