Beispiel #1
0
/**
 * Get the full program path.
 *
 * @return a newly allocated string (through halloc()) that points to the
 * path of the program being run, NULL if we can't compute a suitable path.
 */
char *
file_program_path(const char *argv0)
{
	filestat_t buf;
	char *file = deconstify_char(argv0);
	char filepath[MAX_PATH_LEN + 1];

	if (is_running_on_mingw() && !is_strsuffix(argv0, (size_t) -1, ".exe")) {
		concat_strings(filepath, sizeof filepath, argv0, ".exe", NULL_PTR);
	} else {
		clamp_strcpy(filepath, sizeof filepath, argv0);
	}

	if (-1 == stat(filepath, &buf)) {
		int saved_errno = errno;
		file = file_locate_from_path(argv0);
		if (NULL == file) {
			errno = saved_errno;
			s_warning("%s(): could not stat() \"%s\": %m", G_STRFUNC, filepath);
			return NULL;
		}
	}

	if (file != NULL && file != argv0)
		return file;		/* Allocated by file_locate_from_path() */

	return h_strdup(filepath);
}
Beispiel #2
0
/**
 * Search executable within the user's PATH.
 *
 * @return full path if found, NULL otherwise.
 * The returned string is allocated with halloc().
 */
char *
file_locate_from_path(const char *argv0)
{
	static bool already_done;
	char *path;
	char *tok;
	char filepath[MAX_PATH_LEN + 1];
	char *result = NULL;
	char *ext = "";

	if (is_running_on_mingw() && !is_strsuffix(argv0, (size_t) -1, ".exe")) {
		ext = ".exe";
	}

	if (filepath_basename(argv0) != argv0) {
		if (!already_done) {
			s_warning("can't locate \"%s\" in PATH: name contains '%c' already",
				argv0,
				strchr(argv0, G_DIR_SEPARATOR) != NULL ? G_DIR_SEPARATOR : '/');
		}
		goto done;
	}

	path = getenv("PATH");
	if (NULL == path) {
		if (!already_done) {
			s_warning("can't locate \"%s\" in PATH: "
				"no such environment variable", argv0);
		}
		goto done;
	}

	path = h_strdup(path);

	tok = strtok(path, G_SEARCHPATH_SEPARATOR_S);
	while (NULL != tok) {
		const char *dir = tok;
		filestat_t buf;

		if ('\0' == *dir)
			dir = ".";
		concat_strings(filepath, sizeof filepath,
			dir, G_DIR_SEPARATOR_S, argv0, ext, NULL);

		if (-1 != stat(filepath, &buf)) {
			if (S_ISREG(buf.st_mode) && -1 != access(filepath, X_OK)) {
				result = h_strdup(filepath);
				break;
			}
		}
		tok = strtok(NULL, G_SEARCHPATH_SEPARATOR_S);
	}

	hfree(path);

done:
	already_done = TRUE;	/* No warning on subsequent invocation */
	return result;
}
Beispiel #3
0
/**
 * Search executable within the user's PATH.
 *
 * @return full path if found, NULL otherwise.
 * The returned string is allocated with halloc().
 */
char *
file_locate_from_path(const char *argv0)
{
	static bool already_done;
	char *path;
	char *tok;
	char filepath[MAX_PATH_LEN + 1];
	char *result = NULL;
	char *ext = "";

	if (is_running_on_mingw() && !is_strsuffix(argv0, (size_t) -1, ".exe")) {
		ext = ".exe";
	}

	if (filepath_basename(argv0) != argv0) {
		if (!already_done) {
			s_warning("can't locate \"%s\" in PATH: name contains '%c' already",
				argv0,
				strchr(argv0, G_DIR_SEPARATOR) != NULL ? G_DIR_SEPARATOR : '/');
		}
		result = h_strdup(argv0);
		goto done;
	}

	path = getenv("PATH");
	if (NULL == path) {
		if (!already_done) {
			s_warning("can't locate \"%s\" in PATH: "
				"no such environment variable", argv0);
		}
		goto done;
	}

	/*
	 * On Windows, we need to implicitly add "." to the path if not already
	 * present -- this is done by appending a separator and a dot, not by
	 * checking whether "." is already part of the path.
	 *
	 * The reason is that "." is implied, and also because one may omit the
	 * ".exe" extension when launching a program.  This means checks done
	 * in crash_init() for instance to see whether the file listed in
	 * argv[0] exists and which do not account for a missing ".exe" will
	 * attempt to locate the program in the PATH to get a full name and will
	 * fail if we do not add ".".
	 *
	 * On UNIX this cannot happen because there is no hidden extension and
	 * the "." is never made part of the PATH implictly.
	 *
	 *		--RAM, 2015-12-06
	 */

	if (is_running_on_mingw())
		path = h_strdup_printf("%s%c.", path, *G_SEARCHPATH_SEPARATOR_S);
	else
		path = h_strdup(path);

	path = h_strdup(path);

	/* FIXME: strtok() is not thread-safe --RAM, 2015-12-06 */

	tok = strtok(path, G_SEARCHPATH_SEPARATOR_S);
	while (NULL != tok) {
		const char *dir = tok;
		filestat_t buf;

		if ('\0' == *dir)
			dir = ".";
		concat_strings(filepath, sizeof filepath,
			dir, G_DIR_SEPARATOR_S, argv0, ext, NULL_PTR);

		if (-1 != stat(filepath, &buf)) {
			if (S_ISREG(buf.st_mode) && -1 != access(filepath, X_OK)) {
				result = h_strdup(filepath);
				break;
			}
		}
		tok = strtok(NULL, G_SEARCHPATH_SEPARATOR_S);
	}

	hfree(path);

done:
	already_done = TRUE;	/* No warning on subsequent invocation */
	return result;
}