Exemple #1
0
static VALUE
load_path_getcwd(void)
{
    char *cwd = my_getcwd();
    VALUE cwd_str = rb_filesystem_str_new_cstr(cwd);
    xfree(cwd);
    return cwd_str;
}
Exemple #2
0
/*
 * 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
}
Exemple #3
0
/*
 * 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
}
Exemple #4
0
/*
 * 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;
}
Exemple #5
0
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';
}
Exemple #6
0
static VALUE
safe_setup_filesystem_str(const char *str)
{
    if (str == 0) str = "";
    return rb_filesystem_str_new_cstr(str);
}
Exemple #7
0
// 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;
}