annotate lib/findprog.c @ 5848:a48fb0e98c8c

*** empty log message ***
author Paul Eggert <eggert@cs.ucla.edu>
date Sat, 14 May 2005 06:03:57 +0000
parents eebff8c51a9b
children 96c32553b4c6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4294
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Locating a program in PATH.
5053
eebff8c51a9b Treat Cygwin like Windows regarding pathname syntax.
Bruno Haible <bruno@clisp.org>
parents: 4294
diff changeset
2 Copyright (C) 2001-2004 Free Software Foundation, Inc.
4294
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software; you can redistribute it and/or modify
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 the Free Software Foundation; either version 2, or (at your option)
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 any later version.
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 along with this program; if not, write to the Free Software Foundation,
5848
a48fb0e98c8c *** empty log message ***
Paul Eggert <eggert@cs.ucla.edu>
parents: 5053
diff changeset
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
4294
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 #ifdef HAVE_CONFIG_H
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 # include "config.h"
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #endif
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 /* Specification. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include "findprog.h"
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 #include <stdbool.h>
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 #include <stdlib.h>
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 #include <string.h>
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 #ifdef HAVE_UNISTD_H
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 # include <unistd.h>
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 #endif
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35 #include "xalloc.h"
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 #include "pathname.h"
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 const char *
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 find_in_path (const char *progname)
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 {
5053
eebff8c51a9b Treat Cygwin like Windows regarding pathname syntax.
Bruno Haible <bruno@clisp.org>
parents: 4294
diff changeset
42 #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
eebff8c51a9b Treat Cygwin like Windows regarding pathname syntax.
Bruno Haible <bruno@clisp.org>
parents: 4294
diff changeset
43 /* Win32, Cygwin, OS/2, DOS */
4294
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 /* The searching rules with .COM, .EXE, .BAT, .CMD etc. suffixes are
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 too complicated. Leave it to the OS. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 return progname;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 #else
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 /* Unix */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 char *path;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50 char *dir;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51 char *cp;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53 if (strchr (progname, '/') != NULL)
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 /* If progname contains a slash, it is either absolute or relative to
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 the current directory. PATH is not used. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56 return progname;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 path = getenv ("PATH");
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 if (path == NULL || *path == '\0')
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 /* If PATH is not set, the default search path is implementation
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 dependent. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 return progname;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 /* Make a copy, to prepare for destructive modifications. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 path = xstrdup (path);
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 for (dir = path; ; dir = cp + 1)
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 {
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 bool last;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 char *progpathname;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 /* Extract next directory in PATH. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 for (cp = dir; *cp != '\0' && *cp != ':'; cp++)
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 ;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 last = (*cp == '\0');
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 *cp = '\0';
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 /* Empty PATH components designate the current directory. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78 if (dir == cp)
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 dir = ".";
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81 /* Concatenate dir and progname. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 progpathname = concatenated_pathname (dir, progname, NULL);
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84 /* On systems which have the eaccess() system call, let's use it.
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85 On other systems, let's hope that this program is not installed
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86 setuid or setgid, so that it is ok to call access() despite its
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 design flaw. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 if (eaccess (progpathname, X_OK) == 0)
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
89 {
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90 /* Found! */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91 if (strcmp (progpathname, progname) == 0)
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92 {
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 free (progpathname);
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 /* Add the "./" prefix for real, that concatenated_pathname()
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96 optimized away. This avoids a second PATH search when the
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97 caller uses execlp/execvp. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98 progpathname = xmalloc (2 + strlen (progname) + 1);
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 progpathname[0] = '.';
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 progpathname[1] = '/';
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 memcpy (progpathname + 2, progname, strlen (progname) + 1);
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 }
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 free (path);
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105 return progpathname;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 }
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 free (progpathname);
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110 if (last)
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
111 break;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112 }
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
114 /* Not found in PATH. An error will be signalled at the first call. */
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
115 free (path);
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
116 return progname;
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
117 #endif
f292c9f75051 New module 'findprog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118 }