You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

171 lines
4.3 KiB

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