1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2012 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #pragma prototyped
23 /*
24 * Glenn Fowler
25 * AT&T Research
26 *
27 * return the full path of the current program in path
28 * command!=0 is used as a default
29 */
30
31 #include <ast.h>
32
33 #if _WINIX
34 #include <ast_windows.h>
35 #include <ctype.h>
36 #endif
37
38 #include "FEATURE/prog"
39
40 #if _hdr_macho_o_dyld && _lib__NSGetExecutablePath
41 #include <mach-o/dyld.h>
42 #else
43 #undef _lib__NSGetExecutablePath
44 #endif
45
46 static size_t
prog(const char * command,char * path,size_t size)47 prog(const char* command, char* path, size_t size)
48 {
49 ssize_t n;
50 char* s;
51 #if _WINIX
52 char* t;
53 char* e;
54 int c;
55 int q;
56 #endif
57 #if _lib__NSGetExecutablePath
58 uint32_t z;
59 #endif
60
61 #ifdef _PROC_PROG
62 if ((n = readlink(_PROC_PROG, path, size)) > 0 && *path == '/')
63 {
64 if (n < size)
65 path[n] = 0;
66 return n;
67 }
68 #endif
69 #if _lib_getexecname
70 if ((s = (char*)getexecname()) && *s == '/')
71 goto found;
72 #endif
73 #if _lib__NSGetExecutablePath
74 z = size;
75 if (!_NSGetExecutablePath(path, &z) && *path == '/')
76 return strlen(path);
77 #endif
78 #if _WINIX
79 if (s = GetCommandLine())
80 {
81 n = 0;
82 q = 0;
83 t = path;
84 e = path + size - 1;
85 while (c = *s++)
86 {
87 if (c == q)
88 q = 0;
89 else if (!q && c == '"')
90 q = c;
91 else if (!q && isspace(c))
92 break;
93 else if (t < e)
94 *t++ = c == '\\' ? '/' : c;
95 else
96 n++;
97 }
98 if (t < e)
99 *t = 0;
100 return (t - path) + n;
101 }
102 #endif
103 if (command)
104 {
105 s = (char*)command;
106 goto found;
107 }
108 return 0;
109 found:
110 n = strlen(s);
111 if (n < size)
112 memcpy(path, s, n + 1);
113 return n;
114 }
115
116 size_t
pathprog(const char * command,char * path,size_t size)117 pathprog(const char* command, char* path, size_t size)
118 {
119 char* rel;
120 ssize_t n;
121
122 if ((n = prog(command, path, size)) > 0 && n < size && *path != '/' && (rel = strdup(path)))
123 {
124 n = pathpath(rel, NiL, PATH_REGULAR|PATH_EXECUTE, path, size) ? strlen(path) : 0;
125 free(rel);
126 }
127 return n;
128 }
129