1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1985-2012 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * David Korn <dgk@research.att.com> *
19da2e3ebdSchin * Phong Vo <kpv@research.att.com> *
20da2e3ebdSchin * *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #pragma prototyped
23da2e3ebdSchin /*
2434f9b3eeSRoland Mainz * Glenn Fowler
2534f9b3eeSRoland Mainz * AT&T Research
2634f9b3eeSRoland Mainz *
2734f9b3eeSRoland Mainz * return the full path of the current program in path
2834f9b3eeSRoland Mainz * command!=0 is used as a default
29da2e3ebdSchin */
30da2e3ebdSchin
3134f9b3eeSRoland Mainz #include <ast.h>
32da2e3ebdSchin
3334f9b3eeSRoland Mainz #if _WINIX
3434f9b3eeSRoland Mainz #include <ast_windows.h>
3534f9b3eeSRoland Mainz #include <ctype.h>
3634f9b3eeSRoland Mainz #endif
37da2e3ebdSchin
3834f9b3eeSRoland Mainz #include "FEATURE/prog"
39da2e3ebdSchin
40*b30d1939SAndy Fiddaman #if _hdr_macho_o_dyld && _lib__NSGetExecutablePath
41*b30d1939SAndy Fiddaman #include <mach-o/dyld.h>
42*b30d1939SAndy Fiddaman #else
43*b30d1939SAndy Fiddaman #undef _lib__NSGetExecutablePath
44*b30d1939SAndy Fiddaman #endif
45*b30d1939SAndy Fiddaman
4634f9b3eeSRoland Mainz static size_t
prog(const char * command,char * path,size_t size)4734f9b3eeSRoland Mainz prog(const char* command, char* path, size_t size)
48da2e3ebdSchin {
4934f9b3eeSRoland Mainz ssize_t n;
5034f9b3eeSRoland Mainz char* s;
5134f9b3eeSRoland Mainz #if _WINIX
5234f9b3eeSRoland Mainz char* t;
5334f9b3eeSRoland Mainz char* e;
5434f9b3eeSRoland Mainz int c;
5534f9b3eeSRoland Mainz int q;
5634f9b3eeSRoland Mainz #endif
57*b30d1939SAndy Fiddaman #if _lib__NSGetExecutablePath
58*b30d1939SAndy Fiddaman uint32_t z;
59*b30d1939SAndy Fiddaman #endif
60da2e3ebdSchin
6134f9b3eeSRoland Mainz #ifdef _PROC_PROG
62*b30d1939SAndy Fiddaman if ((n = readlink(_PROC_PROG, path, size)) > 0 && *path == '/')
63da2e3ebdSchin {
6434f9b3eeSRoland Mainz if (n < size)
6534f9b3eeSRoland Mainz path[n] = 0;
6634f9b3eeSRoland Mainz return n;
67da2e3ebdSchin }
6834f9b3eeSRoland Mainz #endif
6934f9b3eeSRoland Mainz #if _lib_getexecname
70*b30d1939SAndy Fiddaman if ((s = (char*)getexecname()) && *s == '/')
71*b30d1939SAndy Fiddaman goto found;
72*b30d1939SAndy Fiddaman #endif
73*b30d1939SAndy Fiddaman #if _lib__NSGetExecutablePath
74*b30d1939SAndy Fiddaman z = size;
75*b30d1939SAndy Fiddaman if (!_NSGetExecutablePath(path, &z) && *path == '/')
76*b30d1939SAndy Fiddaman return strlen(path);
7734f9b3eeSRoland Mainz #endif
7834f9b3eeSRoland Mainz #if _WINIX
7934f9b3eeSRoland Mainz if (s = GetCommandLine())
8034f9b3eeSRoland Mainz {
8134f9b3eeSRoland Mainz n = 0;
8234f9b3eeSRoland Mainz q = 0;
8334f9b3eeSRoland Mainz t = path;
8434f9b3eeSRoland Mainz e = path + size - 1;
8534f9b3eeSRoland Mainz while (c = *s++)
8634f9b3eeSRoland Mainz {
8734f9b3eeSRoland Mainz if (c == q)
8834f9b3eeSRoland Mainz q = 0;
8934f9b3eeSRoland Mainz else if (!q && c == '"')
9034f9b3eeSRoland Mainz q = c;
9134f9b3eeSRoland Mainz else if (!q && isspace(c))
9234f9b3eeSRoland Mainz break;
9334f9b3eeSRoland Mainz else if (t < e)
9434f9b3eeSRoland Mainz *t++ = c == '\\' ? '/' : c;
9534f9b3eeSRoland Mainz else
9634f9b3eeSRoland Mainz n++;
9734f9b3eeSRoland Mainz }
9834f9b3eeSRoland Mainz if (t < e)
9934f9b3eeSRoland Mainz *t = 0;
10034f9b3eeSRoland Mainz return (t - path) + n;
10134f9b3eeSRoland Mainz }
10234f9b3eeSRoland Mainz #endif
10334f9b3eeSRoland Mainz if (command)
10434f9b3eeSRoland Mainz {
105*b30d1939SAndy Fiddaman s = (char*)command;
106*b30d1939SAndy Fiddaman goto found;
10734f9b3eeSRoland Mainz }
10834f9b3eeSRoland Mainz return 0;
109*b30d1939SAndy Fiddaman found:
110*b30d1939SAndy Fiddaman n = strlen(s);
111*b30d1939SAndy Fiddaman if (n < size)
112*b30d1939SAndy Fiddaman memcpy(path, s, n + 1);
113*b30d1939SAndy Fiddaman return n;
114da2e3ebdSchin }
115da2e3ebdSchin
11634f9b3eeSRoland Mainz size_t
pathprog(const char * command,char * path,size_t size)11734f9b3eeSRoland Mainz pathprog(const char* command, char* path, size_t size)
118da2e3ebdSchin {
119*b30d1939SAndy Fiddaman char* rel;
12034f9b3eeSRoland Mainz ssize_t n;
121da2e3ebdSchin
122*b30d1939SAndy Fiddaman if ((n = prog(command, path, size)) > 0 && n < size && *path != '/' && (rel = strdup(path)))
12334f9b3eeSRoland Mainz {
124*b30d1939SAndy Fiddaman n = pathpath(rel, NiL, PATH_REGULAR|PATH_EXECUTE, path, size) ? strlen(path) : 0;
125*b30d1939SAndy Fiddaman free(rel);
12634f9b3eeSRoland Mainz }
12734f9b3eeSRoland Mainz return n;
128da2e3ebdSchin }
129