diff options
author | Havoc Pennington <hp@redhat.com> | 2000-10-09 16:24:57 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2000-10-09 16:24:57 +0000 |
commit | 8e3a3eef63c3c298c93fa8f8e827b10dd1b6327c (patch) | |
tree | f0c97f4c8d40039033a67ade0b0123413b9930b1 /gutils.c | |
parent | 18e7dc021591bcaedb922a553d5bc0e0b966b6d9 (diff) | |
download | glib-8e3a3eef63c3c298c93fa8f8e827b10dd1b6327c.tar.gz |
Add new files.
2000-10-09 Havoc Pennington <hp@redhat.com>
* Makefile.am, tests/Makefile.am: Add new files.
* tests/spawn-test.c, tests/shell-test.c: new tests for
the shell/spawn stuff
* gutils.c (g_find_program_in_path): convert a relative
program name into an absolute pathname to an existing
executable
* gspawn.h, gspawn.c: New fork/exec API
* gshell.h, gshell.c: Shell-related utilities, at the moment
simply routines to parse argv and quote/unquote strings
* guniprop.c (g_unichar_isspace): Return TRUE for the
ASCII space characters isspace() returns TRUE for.
* gfileutils.c (g_file_get_contents): Convenience function
to slurp entire file into a string and return it. Partially
written by Joel Becker.
(g_file_test): file test function
Diffstat (limited to 'gutils.c')
-rw-r--r-- | gutils.c | 100 |
1 files changed, 100 insertions, 0 deletions
@@ -143,6 +143,106 @@ g_atexit (GVoidFunc func) g_error ("Could not register atexit() function: %s", error); } +/* Based on execvp() from GNU Libc. + * Some of this code is cut-and-pasted into gspawn.c + */ + +static gchar* +my_strchrnul (const gchar *str, gchar c) +{ + gchar *p = (gchar*)str; + while (*p && (*p != c)) + ++p; + + return p; +} + +/** + * g_find_program_in_path: + * @file: a program name + * + * Locates the first executable named @file in the user's path, in the + * same way that execvp() would locate it. Returns an allocated string + * with the absolute path name, or NULL if the program is not found in + * the path. If @file is already an absolute path, returns a copy of + * @file if @file exists and is executable, and NULL otherwise. + * + * Return value: absolute path, or NULL + **/ +gchar* +g_find_program_in_path (const gchar *file) +{ + gchar *path, *p, *name, *freeme; + size_t len; + size_t pathlen; + + g_return_val_if_fail (file != NULL, NULL); + + if (*file == '/') + { + if (g_file_test (file, G_FILE_TEST_IS_EXECUTABLE)) + return g_strdup (file); + else + return NULL; + } + + path = g_getenv ("PATH"); + if (path == NULL) + { + /* There is no `PATH' in the environment. The default + * search path in libc is the current directory followed by + * the path `confstr' returns for `_CS_PATH'. + */ + + /* In GLib we put . last, for security, and don't use the + * unportable confstr(); UNIX98 does not actually specify + * what to search if PATH is unset. POSIX may, dunno. + */ + + path = "/bin:/usr/bin:."; + } + + len = strlen (file) + 1; + pathlen = strlen (path); + freeme = name = g_malloc (pathlen + len + 1); + + /* Copy the file name at the top, including '\0' */ + memcpy (name + pathlen + 1, file, len); + name = name + pathlen; + /* And add the slash before the filename */ + *name = '/'; + + p = path; + do + { + char *startp; + + path = p; + p = my_strchrnul (path, ':'); + + if (p == path) + /* Two adjacent colons, or a colon at the beginning or the end + * of `PATH' means to search the current directory. + */ + startp = name + 1; + else + startp = memcpy (name - (p - path), path, p - path); + + if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE)) + { + gchar *ret; + ret = g_strdup (startp); + g_free (freeme); + return ret; + } + } + while (*p++ != '\0'); + + g_free (freeme); + + return NULL; +} + gint g_snprintf (gchar *str, gulong n, |