static VALUE load_path_getcwd(void) { char *cwd = my_getcwd(); VALUE cwd_str = rb_filesystem_str_new_cstr(cwd); xfree(cwd); return cwd_str; }
/* * Returns system configuration directory. * * This is typically "/etc", but is modified by the prefix used when Ruby was * compiled. For example, if Ruby is built and installed in /usr/local, returns * "/usr/local/etc". */ static VALUE etc_sysconfdir(VALUE obj) { #ifdef _WIN32 return rb_w32_special_folder(CSIDL_COMMON_APPDATA); #else return rb_filesystem_str_new_cstr(SYSCONFDIR); #endif }
/* * Returns system temporary directory. */ static VALUE etc_systmpdir(void) { #ifdef _WIN32 WCHAR path[_MAX_PATH]; UINT len = rb_w32_system_tmpdir(path, numberof(path)); if (!len) return Qnil; return rb_w32_conv_from_wchar(path, rb_filesystem_encoding()); #else return rb_filesystem_str_new_cstr("/tmp"); #endif }
/* * Returns system temporary directory; typically "/tmp". */ static VALUE etc_systmpdir(void) { VALUE tmpdir; #ifdef _WIN32 WCHAR path[_MAX_PATH]; UINT len = rb_w32_system_tmpdir(path, numberof(path)); if (!len) return Qnil; tmpdir = rb_w32_conv_from_wchar(path, rb_filesystem_encoding()); #else tmpdir = rb_filesystem_str_new_cstr("/tmp"); #endif FL_UNSET(tmpdir, FL_TAINT); return tmpdir; }
static int search_required(VALUE fname, volatile VALUE *path, int safe_level) { VALUE tmp; char *ext, *ftptr; int type, ft = 0; const char *loading; *path = 0; ext = strrchr(ftptr = RSTRING_PTR(fname), '.'); if (ext && !strchr(ext, '/')) { if (IS_RBEXT(ext)) { if (rb_feature_p(ftptr, ext, TRUE, FALSE, &loading)) { if (loading) *path = rb_filesystem_str_new_cstr(loading); return 'r'; } if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading) *path = tmp; return 'r'; } return 0; } else if (IS_SOEXT(ext)) { if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) { if (loading) *path = rb_filesystem_str_new_cstr(loading); return 's'; } tmp = rb_str_subseq(fname, 0, ext - RSTRING_PTR(fname)); #ifdef DLEXT2 OBJ_FREEZE(tmp); if (rb_find_file_ext_safe(&tmp, loadable_ext + 1, safe_level)) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading) *path = tmp; return 's'; } #else rb_str_cat2(tmp, DLEXT); OBJ_FREEZE(tmp); if ((tmp = rb_find_file_safe(tmp, safe_level)) != 0) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading) *path = tmp; return 's'; } #endif } else if (IS_DLEXT(ext)) { if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) { if (loading) *path = rb_filesystem_str_new_cstr(loading); return 's'; } if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading) *path = tmp; return 's'; } } } else if ((ft = rb_feature_p(ftptr, 0, FALSE, FALSE, &loading)) == 'r') { if (loading) *path = rb_filesystem_str_new_cstr(loading); return 'r'; } tmp = fname; type = rb_find_file_ext_safe(&tmp, loadable_ext, safe_level); switch (type) { case 0: if (ft) goto statically_linked; ftptr = RSTRING_PTR(tmp); return rb_feature_p(ftptr, 0, FALSE, TRUE, 0); default: if (ft) { statically_linked: if (loading) *path = rb_filesystem_str_new_cstr(loading); return ft; } case 1: ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); if (rb_feature_p(ftptr, ext, !--type, TRUE, &loading) && !loading) break; *path = tmp; } return type ? 's' : 'r'; }
static VALUE safe_setup_filesystem_str(const char *str) { if (str == 0) str = ""; return rb_filesystem_str_new_cstr(str); }
// TODO: can we fail allocating memory? static VALUE fenix_file_expand_path_plain(int argc, VALUE *argv) { size_t size = 0, wpath_len = 0, wdir_len = 0, whome_len = 0; size_t buffer_len = 0; char *fullpath = NULL; wchar_t *wfullpath = NULL, *wpath = NULL, *wpath_pos = NULL, *wdir = NULL; wchar_t *whome = NULL, *buffer = NULL, *buffer_pos = NULL; UINT cp; VALUE result = Qnil, path = Qnil, dir = Qnil; // retrieve path and dir from argv rb_scan_args(argc, argv, "11", &path, &dir); // coerce them to string path = fenix_coerce_to_path(path); if (!NIL_P(dir)) dir = fenix_coerce_to_path(dir); // convert char * to wchar_t // path if (!NIL_P(path)) { size = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(path), -1, NULL, 0) + 1; wpath = wpath_pos = (wchar_t *)malloc(size * sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(path), -1, wpath, size); wpath_len = wcslen(wpath); // wprintf(L"wpath: '%s' with (%i) characters long.\n", wpath, wpath_len); } // dir if (!NIL_P(dir)) { size = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(dir), -1, NULL, 0) + 1; wdir = (wchar_t *)malloc(size * sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(dir), -1, wdir, size); wdir_len = wcslen(wdir); // wprintf(L"wdir: '%s' with (%i) characters long.\n", wdir, wdir_len); } /* determine if we need the user's home directory */ if ((wpath_len == 1 && wpath_pos[0] == L'~') || (wpath_len >= 2 && wpath_pos[0] == L'~' && IS_DIR_SEPARATOR_P(wpath_pos[1]))) { // wprintf(L"wpath requires expansion.\n"); whome = fenix_home_dir(); whome_len = wcslen(whome); // wprintf(L"whome: '%s' with (%i) characters long.\n", whome, whome_len); /* ignores dir since we are expading home */ wdir_len = 0; /* exclude ~ from the result */ wpath_pos++; wpath_len--; /* exclude separator if present */ if (wpath_len && IS_DIR_SEPARATOR_P(wpath_pos[0])) { // wprintf(L"excluding expansion character and separator\n"); wpath_pos++; wpath_len--; } } else if (wpath_len >= 2 && wpath_pos[1] == L':') { /* ignore dir since path contains a drive letter */ // wprintf(L"Ignore dir since we have drive letter\n"); wdir_len = 0; } // wprintf(L"wpath_len: %i\n", wpath_len); // wprintf(L"wdir_len: %i\n", wdir_len); // wprintf(L"whome_len: %i\n", whome_len); buffer_len = wpath_len + 1 + wdir_len + 1 + whome_len + 1; // wprintf(L"buffer_len: %i\n", buffer_len + 1); buffer = buffer_pos = (wchar_t *)malloc((buffer_len + 1) * sizeof(wchar_t)); /* add home */ if (whome_len) { // wprintf(L"Copying whome...\n"); wcsncpy(buffer_pos, whome, whome_len); buffer_pos += whome_len; } /* Add separator if required */ if (whome_len && wcsrchr(L"\\/:", buffer_pos[-1]) == NULL) { // wprintf(L"Adding separator after whome\n"); buffer_pos[0] = L'\\'; buffer_pos++; } if (wdir_len) { // wprintf(L"Copying wdir...\n"); wcsncpy(buffer_pos, wdir, wdir_len); buffer_pos += wdir_len; } /* add separator if required */ if (wdir_len && wcsrchr(L"\\/:", buffer_pos[-1]) == NULL) { // wprintf(L"Adding separator after wdir\n"); buffer_pos[0] = L'\\'; buffer_pos++; } /* now deal with path */ if (wpath_len) { // wprintf(L"Copying wpath...\n"); wcsncpy(buffer_pos, wpath_pos, wpath_len); buffer_pos += wpath_len; } /* GetFullPathNameW requires at least "." to determine current directory */ if (wpath_len == 0) { // wprintf(L"Adding '.' to buffer\n"); buffer_pos[0] = L'.'; buffer_pos++; } /* Ensure buffer is NULL terminated */ buffer_pos[0] = L'\0'; // wprintf(L"buffer: '%s'\n", buffer); // FIXME: Make this more robust // Determine require buffer size size = GetFullPathNameW(buffer, 0, NULL, NULL); if (size) { // allocate enough memory to contain the response wfullpath = (wchar_t *)malloc(size * sizeof(wchar_t)); GetFullPathNameW(buffer, size, wfullpath, NULL); /* Calculate the new size and leave the garbage out */ size = wcslen(wfullpath); /* Remove any trailing slashes */ if (IS_DIR_SEPARATOR_P(wfullpath[size - 1]) && wfullpath[size - 2] != L':') { // wprintf(L"Removing trailing slash\n"); wfullpath[size - 1] = L'\0'; } // sanitize backslashes with forwardslashes fenix_replace_wchar(wfullpath, L'\\', L'/'); // wprintf(L"wfullpath: '%s'\n", wfullpath); // What CodePage should we use? cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP; // convert to char * size = WideCharToMultiByte(cp, 0, wfullpath, -1, NULL, 0, NULL, NULL) + 1; fullpath = (char *)malloc(size * sizeof(char)); WideCharToMultiByte(cp, 0, wfullpath, -1, fullpath, size, NULL, NULL); // convert to VALUE and set the filesystem encoding result = rb_filesystem_str_new_cstr(fullpath); } // TODO: better cleanup if (buffer) free(buffer); if (wpath) free(wpath); if (wdir) free(wdir); if (whome) free(whome); if (wfullpath) free(wfullpath); if (fullpath) free(fullpath); return result; }