10#include "nuitka/prelude.h"
13#if defined(__FreeBSD__) || defined(__OpenBSD__)
14#include <sys/sysctl.h>
33#include <mach-o/dyld.h>
38#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x))
41#include "nuitka/environment_variables_system.h"
42#include "nuitka/filesystem_paths.h"
43#include "nuitka/safe_string_ops.h"
45void normalizePath(filename_char_t *filename) {
46 filename_char_t *w = filename;
50 if (*w == FILENAME_SEP_CHAR) {
51 while (*(w + 1) == FILENAME_SEP_CHAR) {
52 filename_char_t *f = w;
75static wchar_t *stripFilenameW(
wchar_t *path) {
76 wchar_t *last_slash = NULL;
86 if (last_slash != NULL) {
93filename_char_t *stripBaseFilename(filename_char_t
const *filename) {
94 static wchar_t result[MAXPATHLEN + 1];
96 copyStringSafeW(result, filename,
sizeof(result) /
sizeof(
wchar_t));
97 stripFilenameW(result);
102filename_char_t *stripBaseFilename(filename_char_t
const *filename) {
103 static char result[MAXPATHLEN + 1];
104 copyStringSafe(result, filename,
sizeof(result));
106 return dirname(result);
111static void makeShortFilename(
wchar_t *filename,
size_t buffer_size) {
112#ifndef _NUITKA_EXPERIMENTAL_AVOID_SHORT_PATH
114 DWORD length = GetShortPathNameW(filename, NULL, 0);
119 wchar_t *short_filename = (
wchar_t *)malloc((length + 1) *
sizeof(wchar_t));
120 DWORD res = GetShortPathNameW(filename, short_filename, length);
123 if (unlikely(res > length)) {
128 appendWStringSafeW(filename, short_filename, buffer_size);
130 free(short_filename);
134static void makeShortDirFilename(
wchar_t *filename,
size_t buffer_size) {
135 wchar_t *changed = stripFilenameW(filename);
136 if (changed != NULL) {
137 changed = wcsdup(changed + 1);
141 makeShortFilename(filename, buffer_size);
143 if (changed != NULL) {
144 appendWCharSafeW(filename, FILENAME_SEP_CHAR, buffer_size);
145 appendWStringSafeW(filename, changed, buffer_size);
154filename_char_t *_getBinaryPath2(
void) {
155 static filename_char_t binary_filename[MAXPATHLEN] = {0};
156 const size_t buffer_size =
sizeof(binary_filename);
158 if (binary_filename[0] != 0) {
159 return binary_filename;
162#if defined(__APPLE__)
163 uint32_t bufsize = buffer_size;
164 int res = _NSGetExecutablePath(binary_filename, &bufsize);
166 if (unlikely(res != 0)) {
169#elif defined(__OpenBSD__) || defined(_AIX) || defined(_NUITKA_EXPERIMENTAL_FORCE_UNIX_BINARY_NAME)
170#if _NUITKA_DLL_MODE || _NUITKA_MODULE_MODE
171 const char *comm =
"invalid";
172 NUITKA_CANNOT_GET_HERE(
"Cannot query program name on this OS. Please help adding that.");
174 const char *comm = getOriginalArgv0();
177 bool success =
false;
180 copyStringSafe(binary_filename, comm, buffer_size);
183 if (getcwd(binary_filename, buffer_size) == NULL) {
187 appendCharSafe(binary_filename,
'/', buffer_size);
188 appendStringSafe(binary_filename, comm, buffer_size);
190 if (isExecutableFile(binary_filename)) {
193 char *path_environment_value = strdup(getenv(
"PATH"));
195 if (path_environment_value != NULL) {
197 char *path = strtok_r(path_environment_value,
":", &sp);
199 while (path != NULL) {
201 if (getcwd(binary_filename, buffer_size) == NULL) {
205 appendCharSafe(binary_filename,
'/', buffer_size);
207 binary_filename[0] = 0;
209 appendStringSafe(binary_filename, path, buffer_size);
210 appendCharSafe(binary_filename,
'/', buffer_size);
211 appendStringSafe(binary_filename, comm, buffer_size);
213 if (isExecutableFile(binary_filename)) {
218 path = strtok_r(NULL,
":", &sp);
221 free(path_environment_value);
226 if (success ==
true) {
231 normalizePath(binary_filename);
234 fprintf(stderr,
"Error, cannot resolve binary path %s from PATH or current directory.\n", comm);
237#elif defined(__FreeBSD__)
244 mib[2] = KERN_PROC_PATHNAME;
246 size_t cb = buffer_size;
247 int res = sysctl(mib, 4, binary_filename, &cb, NULL, 0);
249 if (unlikely(res != 0)) {
252#elif defined(__wasi__)
253 const char *wasi_filename =
"program.wasm";
254 copyStringSafe(binary_filename, wasi_filename, buffer_size);
260 memset(binary_filename, 0, buffer_size);
261 ssize_t res = readlink(
"/proc/self/exe", binary_filename, buffer_size - 1);
263 if (unlikely(res == -1)) {
267 return binary_filename;
271filename_char_t
const *getBinaryPath(
void) {
273 static filename_char_t binary_filename[MAXPATHLEN] = {0};
275 if (binary_filename[0] != 0) {
276 return binary_filename;
279 DWORD res = GetModuleFileNameW(NULL, binary_filename,
sizeof(binary_filename) /
sizeof(
wchar_t));
280 if (unlikely(res == 0)) {
284 return binary_filename;
286 return _getBinaryPath2();
290bool readFileChunk(FILE_HANDLE file_handle,
void *buffer,
size_t size) {
295 BOOL bool_res = ReadFile(file_handle, buffer, (DWORD)size, &read_size, NULL);
297 return bool_res && (read_size == size);
299 size_t read_size = fread(buffer, 1, size, file_handle);
301 return read_size == size;
305bool writeFileChunk(FILE_HANDLE target_file,
void const *chunk,
size_t chunk_size) {
307 DWORD write_size = 0;
308 return WriteFile(target_file, chunk, (DWORD)chunk_size, &write_size, NULL);
310 size_t written = fwrite(chunk, 1, chunk_size, target_file);
311 return written == chunk_size;
315FILE_HANDLE createFileForWriting(filename_char_t
const *filename) {
317 FILE_HANDLE result = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
319 FILE *result = fopen(filename,
"wb");
325FILE_HANDLE openFileForReading(filename_char_t
const *filename) {
327 FILE_HANDLE result = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
329 FILE *result = fopen(filename,
"rb");
335bool closeFile(FILE_HANDLE target_file) {
337 CloseHandle(target_file);
340 int r = fclose(target_file);
346int64_t getFileSize(FILE_HANDLE file_handle) {
349 DWORD file_size = GetFileSize(file_handle, NULL);
351 if (file_size == INVALID_FILE_SIZE) {
355 int res = fseek(file_handle, 0, SEEK_END);
357 if (unlikely(res != 0)) {
361 long file_size = ftell(file_handle);
363 res = fseek(file_handle, 0, SEEK_SET);
365 if (unlikely(res != 0)) {
370 return (int64_t)file_size;
374#if defined(__APPLE__)
377#if defined(__MSYS__) || defined(__HAIKU__) || defined(__OpenBSD__) || defined(_AIX) || defined(__wasi__)
378static bool sendfile(
int output_file,
int input_file, off_t *bytesCopied,
size_t count) {
384 ssize_t read_bytes = read(input_file, buffer, Py_MIN(
sizeof(buffer), count));
386 if (unlikely(read <= 0)) {
392 ssize_t written_bytes = write(output_file, buffer, read_bytes);
394 if (unlikely(written_bytes != read_bytes)) {
398 *bytesCopied += written_bytes;
403#elif !defined(__FreeBSD__)
404#include <sys/sendfile.h>
410bool isExecutableFile(filename_char_t
const *filename) {
411 int mode = getFileMode(filename);
416 return mode & S_IXUSR;
420int getFileMode(filename_char_t
const *filename) {
422 struct stat fileinfo = {0};
423 if (stat(filename, &fileinfo) == -1) {
427 return fileinfo.st_mode;
434bool copyFile(filename_char_t
const *source, filename_char_t
const *dest,
int mode) {
436 int input_file = open(source, O_RDONLY);
438 if (input_file == -1) {
442 int output_file = creat(dest, mode);
444 if (output_file == -1) {
449#if defined(__APPLE__)
451 bool result = fcopyfile(input_file, output_file, 0, COPYFILE_ALL) == 0;
452#elif defined(__FreeBSD__)
453 struct stat input_fileinfo = {0};
454 fstat(input_file, &input_fileinfo);
455 off_t bytesCopied = 0;
457 bool result = sendfile(output_file, input_file, 0, input_fileinfo.st_size, 0, &bytesCopied, 0);
460 struct stat fileinfo = {0};
461 fstat(input_file, &fileinfo);
463 off_t bytesCopied = 0;
464 bool result = sendfile(output_file, input_file, &bytesCopied, fileinfo.st_size) != -1;
472 return CopyFileW(source, dest, 0) != 0;
476bool deleteFile(filename_char_t
const *filename) {
478 return DeleteFileW(filename) != 0;
480 return unlink(filename) == 0;
484bool renameFile(filename_char_t
const *source, filename_char_t
const *dest) {
487 return _wrename(source, dest) == 0;
489 return rename(source, dest) == 0;
493#include "nuitka/checksum_tools.h"
495extern error_code_t getLastErrorCode(
void) {
497 return GetLastError();
507 char const *erroring_function;
508 unsigned char const *data;
511 HANDLE handle_mapping;
517 result.file_handle = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
518 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
520 if (result.file_handle == INVALID_HANDLE_VALUE) {
522 result.error_code = GetLastError();
523 result.erroring_function =
"CreateFileW";
528 result.file_size = getFileSize(result.file_handle);
530 if (result.file_size == -1) {
532 result.error_code = GetLastError();
533 result.erroring_function =
"GetFileSize";
535 CloseHandle(result.file_handle);
540 result.handle_mapping = CreateFileMappingW(result.file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
542 if (result.handle_mapping == NULL) {
544 result.error_code = GetLastError();
545 result.erroring_function =
"CreateFileMappingW";
547 CloseHandle(result.file_handle);
552 result.data = (
unsigned char const *)MapViewOfFile(result.handle_mapping, FILE_MAP_READ, 0, 0, 0);
554 if (unlikely(result.data == NULL)) {
556 result.error_code = GetLastError();
557 result.erroring_function =
"MapViewOfFile";
559 CloseHandle(result.handle_mapping);
560 CloseHandle(result.file_handle);
565 result.error =
false;
566 result.error_code = 0;
572 assert(!mapped_file->error);
574 UnmapViewOfFile(mapped_file->data);
575 CloseHandle(mapped_file->handle_mapping);
576 CloseHandle(mapped_file->file_handle);
583 char const *erroring_function;
584 unsigned char const *data;
592 result.file_handle = open(filename, O_RDONLY);
594 if (unlikely(result.file_handle == -1)) {
596 result.error_code = errno;
597 result.erroring_function =
"open";
598 result.file_size = -1;
602 result.file_size = lseek(result.file_handle, 0, SEEK_END);
603 if (unlikely(result.file_size == -1)) {
605 result.error_code = errno;
606 result.erroring_function =
"lseek";
608 close(result.file_handle);
612 off_t res = lseek(result.file_handle, 0, SEEK_SET);
614 if (unlikely(res == -1)) {
616 result.error_code = errno;
617 result.erroring_function =
"lseek";
619 close(result.file_handle);
624 result.data = (
unsigned char const *)mmap(NULL, result.file_size, PROT_READ, MAP_PRIVATE, result.file_handle, 0);
626 if (unlikely(result.data == MAP_FAILED)) {
628 result.error_code = errno;
629 result.erroring_function =
"mmap";
631 close(result.file_handle);
636 result.error =
false;
641 assert(!mapped_file->error);
643 munmap((
void *)mapped_file->data, mapped_file->file_size);
644 close(mapped_file->file_handle);
648uint32_t getFileCRC32(filename_char_t
const *filename) {
651 if (mapped_file.error) {
654 uint32_t result = calcCRC32(mapped_file.data, (
long)mapped_file.file_size);
661 unmapFileFromMemory(&mapped_file);
668static DWORD Nuitka_GetFinalPathNameByHandleW(HANDLE hFile, LPWSTR FilePath, DWORD cchFilePath, DWORD dwFlags) {
669 typedef DWORD(WINAPI * pfnGetFinalPathNameByHandleW)(HANDLE hFile, LPWSTR FilePath, DWORD cchFilePath,
672 pfnGetFinalPathNameByHandleW fnGetFinalPathNameByHandleW =
673 (pfnGetFinalPathNameByHandleW)GetProcAddress(GetModuleHandleA(
"Kernel32.dll"),
"GetFinalPathNameByHandleW");
675 if (fnGetFinalPathNameByHandleW != NULL) {
676 return fnGetFinalPathNameByHandleW(hFile, FilePath, cchFilePath, dwFlags);
683static void resolveFileSymbolicLink(
wchar_t *resolved_filename,
wchar_t const *filename, DWORD resolved_filename_size,
684 bool resolve_symlinks) {
688 if (resolve_symlinks) {
690 HANDLE file_handle = CreateFileW(filename, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
691 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
693 if (unlikely(file_handle == INVALID_HANDLE_VALUE)) {
699 copyStringSafeW(resolved_filename, filename, resolved_filename_size);
702 DWORD len = Nuitka_GetFinalPathNameByHandleW(file_handle, resolved_filename, resolved_filename_size,
703 FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
705 CloseHandle(file_handle);
707 if (unlikely(len >= resolved_filename_size)) {
713 if (wcsncmp(resolved_filename, L
"\\\\?\\", 4) == 0) {
714 if (wcscmp(resolved_filename + 4, filename) == 0) {
715 copyStringSafeW(resolved_filename, filename, resolved_filename_size);
716 }
else if (resolved_filename[5] == L
':') {
717 copyStringSafeW(resolved_filename, resolved_filename + 4, resolved_filename_size);
723 if (wcsncmp(resolved_filename, L
"\\\\?\\UNC\\", 8) == 0) {
724 copyStringSafeW(resolved_filename, resolved_filename + 6, resolved_filename_size);
725 resolved_filename[0] = L
'\\';
729 copyStringSafeW(resolved_filename, filename, resolved_filename_size);
735static void resolveFileSymbolicLink(
char *resolved_filename,
char const *filename,
size_t resolved_filename_size,
736 bool resolve_symlinks) {
738 copyStringSafe(resolved_filename, filename, resolved_filename_size);
740 if (resolve_symlinks) {
744 char buffer[MAXPATHLEN];
746 char *result = realpath(filename, buffer);
748 if (unlikely(result == NULL)) {
752 copyStringSafe(resolved_filename, buffer, resolved_filename_size);
754 copyStringSafe(resolved_filename, filename, resolved_filename_size);
761wchar_t const *getBinaryFilenameWideChars(
bool resolve_symlinks) {
762 static wchar_t binary_filename[MAXPATHLEN + 1] = {0};
763 static wchar_t binary_filename_resolved[MAXPATHLEN + 1] = {0};
765 wchar_t *buffer = resolve_symlinks ? binary_filename : binary_filename_resolved;
766 assert(
sizeof(binary_filename) ==
sizeof(binary_filename_resolved));
768 if (buffer[0] == 0) {
769 DWORD res = GetModuleFileNameW(NULL, buffer,
sizeof(binary_filename) /
sizeof(
wchar_t));
773 resolveFileSymbolicLink(buffer, buffer,
sizeof(binary_filename) /
sizeof(
wchar_t), resolve_symlinks);
774 makeShortDirFilename(binary_filename,
sizeof(binary_filename) /
sizeof(
wchar_t));
782extern wchar_t const *getBinaryFilenameWideChars(
bool resolve_symlinks);
784char const *getBinaryFilenameHostEncoded(
bool resolve_symlinks) {
785 static char *binary_filename = NULL;
786 static char *binary_filename_resolved = NULL;
788 char *binary_filename_target;
790 if (resolve_symlinks) {
791 binary_filename_target = binary_filename_resolved;
793 binary_filename_target = binary_filename;
796 if (binary_filename_target != NULL) {
797 return binary_filename_target;
799 wchar_t const *w = getBinaryFilenameWideChars(resolve_symlinks);
801 DWORD bufsize = WideCharToMultiByte(CP_ACP, 0, w, -1, NULL, 0, NULL, NULL);
802 assert(bufsize != 0);
804 binary_filename_target = (
char *)malloc(bufsize + 1);
805 assert(binary_filename_target);
807 DWORD res2 = WideCharToMultiByte(CP_ACP, 0, w, -1, binary_filename_target, bufsize, NULL, NULL);
810 if (unlikely(res2 > bufsize)) {
814 return (
char const *)binary_filename_target;
818char const *getBinaryFilenameHostEncoded(
bool resolve_symlinks) {
819 const int buffer_size = MAXPATHLEN + 1;
821 static char binary_filename[MAXPATHLEN + 1] = {0};
822 static char binary_filename_resolved[MAXPATHLEN + 1] = {0};
824 char *binary_filename_target;
826 if (resolve_symlinks) {
827 binary_filename_target = binary_filename_resolved;
829 binary_filename_target = binary_filename;
832 if (*binary_filename_target != 0) {
833 return binary_filename_target;
836 copyStringSafe(binary_filename_target, _getBinaryPath2(), buffer_size);
837 resolveFileSymbolicLink(binary_filename_target, binary_filename_target, buffer_size, resolve_symlinks);
839 return binary_filename_target;
852#ifndef CSIDL_LOCAL_APPDATA
853#define CSIDL_LOCAL_APPDATA 28
856#define CSIDL_PROFILE 40
861static bool appendStringCSIDLPathW(
wchar_t *target,
int csidl_id,
size_t buffer_size) {
862 wchar_t path_buffer[MAX_PATH];
863 int res = SHGetFolderPathW(NULL, csidl_id, NULL, 0, path_buffer);
868 appendWStringSafeW(target, path_buffer, buffer_size);
873bool expandTemplatePathW(
wchar_t *target,
wchar_t const *source,
size_t buffer_size) {
876 wchar_t var_name[1024];
879 bool var_started =
false;
881 while (*source != 0) {
882 if (*source == L
'{') {
883 assert(var_started ==
false);
892 }
else if (*source == L
'}') {
893 assert(var_started ==
true);
898 bool is_path =
false;
900 if (wcsicmp(var_name, L
"TEMP") == 0) {
901 GetTempPathW((DWORD)buffer_size, target);
903 }
else if (wcsicmp(var_name, L
"PROGRAM") == 0) {
904#if _NUITKA_ONEFILE_TEMP_BOOL
905 appendWStringSafeW(target, __wargv[0], buffer_size);
907 if (!GetModuleFileNameW(NULL, target, (DWORD)buffer_size)) {
911 }
else if (wcsicmp(var_name, L
"PROGRAM_BASE") == 0) {
912 if (expandTemplatePathW(target, L
"{PROGRAM}", buffer_size - wcslen(target)) ==
false) {
916 size_t length = wcslen(target);
918 if ((length >= 4) && (wcsicmp(target + length - 4, L
".exe") == 0)) {
919 target[length - 4] = 0;
921 }
else if (wcsicmp(var_name, L
"PROGRAM_DIR") == 0) {
922 if (expandTemplatePathW(target, L
"{PROGRAM}", buffer_size - wcslen(target)) ==
false) {
926 stripFilenameW(target);
927 }
else if (wcsicmp(var_name, L
"PID") == 0) {
929 environment_char_t
const *environment_value = NULL;
931#if _NUITKA_ONEFILE_MODE
932 environment_value = getEnvironmentVariable(
"NUITKA_ONEFILE_PARENT");
934 if (environment_value != NULL) {
935 checkWStringNumber(environment_value);
937 appendWStringSafeW(target, getEnvironmentVariable(
"NUITKA_ONEFILE_PARENT"), buffer_size);
939 char pid_buffer[128];
940 snprintf(pid_buffer,
sizeof(pid_buffer),
"%ld", GetCurrentProcessId());
941 appendStringSafeW(target, pid_buffer, buffer_size);
943 }
else if (wcsicmp(var_name, L
"HOME") == 0) {
944 if (appendStringCSIDLPathW(target, CSIDL_PROFILE, buffer_size) ==
false) {
948 }
else if (wcsicmp(var_name, L
"CACHE_DIR") == 0) {
949 if (appendStringCSIDLPathW(target, CSIDL_LOCAL_APPDATA, buffer_size) ==
false) {
953#ifdef NUITKA_COMPANY_NAME
954 }
else if (wcsicmp(var_name, L
"COMPANY") == 0) {
955 appendWStringSafeW(target, L
"" NUITKA_COMPANY_NAME, buffer_size);
957#ifdef NUITKA_PRODUCT_NAME
958 }
else if (wcsicmp(var_name, L
"PRODUCT") == 0) {
959 appendWStringSafeW(target, L
"" NUITKA_PRODUCT_NAME, buffer_size);
961#ifdef NUITKA_VERSION_COMBINED
962 }
else if (wcsicmp(var_name, L
"VERSION") == 0) {
963 appendWStringSafeW(target, L
"" NUITKA_VERSION_COMBINED, buffer_size);
965 }
else if (wcsicmp(var_name, L
"TIME") == 0) {
966 environment_char_t
const *environment_value = NULL;
968#if _NUITKA_ONEFILE_MODE
969 environment_value = getEnvironmentVariable(
"NUITKA_ONEFILE_START");
972 if (environment_value != NULL) {
973 appendWStringSafeW(target, getEnvironmentVariable(
"NUITKA_ONEFILE_START"), buffer_size);
975 wchar_t time_buffer[1024];
979 assert(
sizeof(time) ==
sizeof(FILETIME));
980 GetSystemTimeAsFileTime((LPFILETIME)&time);
982 swprintf(time_buffer,
sizeof(time_buffer), L
"%lld", time);
984#if _NUITKA_ONEFILE_MODE
985 setEnvironmentVariable(
"NUITKA_ONEFILE_START", time_buffer);
987 appendWStringSafeW(target, time_buffer, buffer_size);
1001 while (*(target - 1) == FILENAME_SEP_CHAR) {
1019 if (buffer_size < 1) {
1023 *target++ = *source++;
1030 assert(var_started ==
false);
1036bool expandTemplatePath(
char *target,
char const *source,
size_t buffer_size) {
1039 char var_name[1024];
1042 NUITKA_MAY_BE_UNUSED
bool var_started =
false;
1044 while (*source != 0) {
1045 if (*source ==
'{') {
1046 assert(var_started ==
false);
1055 }
else if (*source ==
'}') {
1056 assert(var_started ==
true);
1057 var_started =
false;
1060 bool is_path =
false;
1062 if (strcasecmp(var_name,
"TEMP") == 0) {
1063 char const *tmp_dir = getenv(
"TMPDIR");
1064 if (tmp_dir == NULL) {
1068 appendStringSafe(target, tmp_dir, buffer_size);
1070 }
else if (strcasecmp(var_name,
"PROGRAM") == 0) {
1071 char const *exe_name = getBinaryFilenameHostEncoded(
false);
1073 appendStringSafe(target, exe_name, buffer_size);
1074 }
else if (strcasecmp(var_name,
"PROGRAM_BASE") == 0) {
1075 if (expandTemplatePath(target,
"{PROGRAM}", buffer_size - strlen(target)) ==
false) {
1079 size_t length = strlen(target);
1081 if ((length >= 4) && (strcasecmp(target + length - 4,
".bin") == 0)) {
1082 target[length - 4] = 0;
1084 }
else if (strcasecmp(var_name,
"PROGRAM_DIR") == 0) {
1085 if (expandTemplatePath(target,
"{PROGRAM}", buffer_size - strlen(target)) ==
false) {
1089 size_t length = strlen(target);
1099 if (target[length] ==
'/') {
1107 }
else if (strcasecmp(var_name,
"PID") == 0) {
1109 environment_char_t
const *environment_value = NULL;
1111#if _NUITKA_ONEFILE_MODE
1112 environment_value = getEnvironmentVariable(
"NUITKA_ONEFILE_PARENT");
1114 if (environment_value != NULL) {
1115 checkStringNumber(environment_value);
1117 appendStringSafe(target, getEnvironmentVariable(
"NUITKA_ONEFILE_PARENT"), buffer_size);
1119 char pid_buffer[128];
1121 snprintf(pid_buffer,
sizeof(pid_buffer),
"%d", getpid());
1123 appendStringSafe(target, pid_buffer, buffer_size);
1125 }
else if (strcasecmp(var_name,
"HOME") == 0) {
1126 char const *home_path = getenv(
"HOME");
1127 if (home_path == NULL) {
1131 struct passwd *pw_data = getpwuid(getuid());
1133 if (unlikely(pw_data == NULL)) {
1137 home_path = pw_data->pw_dir;
1141 appendStringSafe(target, home_path, buffer_size);
1143 }
else if (strcasecmp(var_name,
"CACHE_DIR") == 0) {
1144 char const *xdg_cache_home = getenv(
"XDG_CACHE_HOME");
1146 if (xdg_cache_home != NULL && xdg_cache_home[0] ==
'/') {
1147 appendStringSafe(target, xdg_cache_home, buffer_size);
1149 if (expandTemplatePath(target,
"{HOME}/.cache", buffer_size - strlen(target)) ==
false) {
1154#ifdef NUITKA_COMPANY_NAME
1155 }
else if (strcasecmp(var_name,
"COMPANY") == 0) {
1156 appendStringSafe(target, NUITKA_COMPANY_NAME, buffer_size);
1158#ifdef NUITKA_PRODUCT_NAME
1159 }
else if (strcasecmp(var_name,
"PRODUCT") == 0) {
1160 appendStringSafe(target, NUITKA_PRODUCT_NAME, buffer_size);
1162#ifdef NUITKA_VERSION_COMBINED
1163 }
else if (strcasecmp(var_name,
"VERSION") == 0) {
1164 appendStringSafe(target, NUITKA_VERSION_COMBINED, buffer_size);
1166 }
else if (strcasecmp(var_name,
"TIME") == 0) {
1167 environment_char_t
const *environment_value = NULL;
1169#if _NUITKA_ONEFILE_MODE
1170 environment_value = getEnvironmentVariable(
"NUITKA_ONEFILE_START");
1173 if (environment_value != NULL) {
1174 appendStringSafe(target, getEnvironmentVariable(
"NUITKA_ONEFILE_START"), buffer_size);
1176 char time_buffer[1024];
1178 struct timeval current_time;
1179 gettimeofday(¤t_time, NULL);
1180 snprintf(time_buffer,
sizeof(time_buffer),
"%ld_%ld", current_time.tv_sec,
1181 (
long)current_time.tv_usec);
1183#if _NUITKA_ONEFILE_MODE
1184 setEnvironmentVariable(
"NUITKA_ONEFILE_START", time_buffer);
1187 appendStringSafe(target, time_buffer, buffer_size);
1199 while (*(target - 1) == FILENAME_SEP_CHAR) {
1217 if (buffer_size < 1) {
1221 *target++ = *source++;
1228 assert(var_started ==
false);
1234#if _NUITKA_DLL_MODE || _NUITKA_MODULE_MODE
1237static HMODULE getDllModuleHandle(
void) {
1238 static HMODULE hm = NULL;
1242 GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
1243 (LPCSTR)&getDllModuleHandle, &hm);
1253#include "AixDllAddr.c"
1256static filename_char_t
const *getDllFilename(
void) {
1258 static WCHAR dll_filename[MAXPATHLEN + 1] = {0};
1260 if (dll_filename[0] == 0) {
1261 int res = GetModuleFileNameW(getDllModuleHandle(), dll_filename, MAXPATHLEN);
1264 makeShortDirFilename(dll_filename,
sizeof(dll_filename) /
sizeof(
wchar_t));
1267 return dll_filename;
1272 NUITKA_MAY_BE_UNUSED
int res = dladdr((
void *)getDllDirectory, &where);
1276 return where.dli_fname;
1280filename_char_t
const *getDllDirectory(
void) {
1282 static WCHAR path[MAXPATHLEN + 1] = {0};
1284 copyStringSafeFilename(path, getDllFilename(), MAXPATHLEN);
1285 stripFilenameW(path);
1291 static char const *result = NULL;
1293 if (result == NULL) {
1297 NUITKA_MAY_BE_UNUSED
int res = dladdr((
void *)getDllDirectory, &where);
1301 result = dirname((
char *)strdup(where.dli_fname));
Definition HelpersFilesystemPaths.c:580