25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

168 lines
3.6 KiB

  1. inline proc get_cwd() -> char* {
  2. const int buf_size = 2048;
  3. char* res = (char*)malloc(buf_size * sizeof(char));
  4. #ifdef _MSC_VER
  5. _getcwd(res, buf_size);
  6. #else
  7. getcwd(res, buf_size);
  8. #endif
  9. return res;
  10. }
  11. inline proc change_cwd(char* dir) -> void {
  12. #ifdef _MSC_VER
  13. _chdir(dir);
  14. #else
  15. chdir(dir);
  16. #endif
  17. }
  18. #ifdef _MSC_VER
  19. int vasprintf(char **strp, const char *fmt, va_list ap) {
  20. // _vscprintf tells you how big the buffer needs to be
  21. int len = _vscprintf(fmt, ap);
  22. if (len == -1) {
  23. return -1;
  24. }
  25. size_t size = (size_t)len + 1;
  26. char *str = malloc(size);
  27. if (!str) {
  28. return -1;
  29. }
  30. // _vsprintf_s is the "secure" version of vsprintf
  31. int r = _vsprintf_s(str, len + 1, fmt, ap);
  32. if (r == -1) {
  33. free(str);
  34. return -1;
  35. }
  36. *strp = str;
  37. return r;
  38. }
  39. int asprintf(char **strp, const char *fmt, ...) {
  40. va_list ap;
  41. va_start(ap, fmt);
  42. int r = vasprintf(strp, fmt, ap);
  43. va_end(ap);
  44. return r;
  45. }
  46. #endif
  47. proc get_exe_dir() -> char* {
  48. #ifdef _MSC_VER
  49. DWORD last_error;
  50. DWORD result;
  51. DWORD path_size = 1024;
  52. char* path = (char*)malloc(1024);
  53. while (true) {
  54. memset(path, 0, path_size);
  55. result = GetModuleFileName(0, path, path_size - 1);
  56. last_error = GetLastError();
  57. if (0 == result) {
  58. free(path);
  59. path = 0;
  60. break;
  61. }
  62. else if (result == path_size - 1) {
  63. free(path);
  64. /* May need to also check for ERROR_SUCCESS here if XP/2K */
  65. if (ERROR_INSUFFICIENT_BUFFER != last_error) {
  66. path = 0;
  67. break;
  68. }
  69. path_size = path_size * 2;
  70. path = (char*)malloc(path_size);
  71. }
  72. else
  73. break;
  74. }
  75. if (!path) {
  76. fprintf(stderr, "Failure: %ld\n", last_error);
  77. return nullptr;
  78. }
  79. else {
  80. // remove the exe name, so we are only left with the path
  81. int index_in_path = -1;
  82. int last_backslash = -1;
  83. char c;
  84. while ((c = path[++index_in_path]) != '\0') {
  85. if (c == '\\')
  86. last_backslash = index_in_path;
  87. }
  88. // we are assuming there are some backslashes
  89. path[last_backslash+1] = '\0';
  90. return path;
  91. }
  92. #else
  93. ssize_t size = 512, i, n;
  94. char *path, *temp;
  95. while (1) {
  96. size_t used;
  97. path = (char*)malloc(size);
  98. if (!path) {
  99. errno = ENOMEM;
  100. return NULL;
  101. }
  102. used = readlink("/proc/self/exe", path, size);
  103. if (used == -1) {
  104. const int saved_errno = errno;
  105. free(path);
  106. errno = saved_errno;
  107. return NULL;
  108. } else
  109. if (used < 1) {
  110. free(path);
  111. errno = EIO;
  112. return NULL;
  113. }
  114. if ((size_t)used >= size) {
  115. free(path);
  116. size = (size | 2047) + 2049;
  117. continue;
  118. }
  119. size = (size_t)used;
  120. break;
  121. }
  122. /* Find final slash. */
  123. n = 0;
  124. for (i = 0; i < size; i++)
  125. if (path[i] == '/')
  126. n = i;
  127. /* Optimize allocated size,
  128. ensuring there is room for
  129. a final slash and a
  130. string-terminating '\0', */
  131. temp = path;
  132. path = (char*)realloc(temp, n + 2);
  133. if (!path) {
  134. free(temp);
  135. errno = ENOMEM;
  136. return NULL;
  137. }
  138. /* and properly trim and terminate the path string. */
  139. path[n+0] = '/';
  140. path[n+1] = '\0';
  141. return path;
  142. #endif
  143. }