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 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 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