Changeset 3904
- Timestamp:
- Oct 23, 2014, 11:45:51 PM (11 years ago)
- Location:
- trunk/libc
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libc/include/stdlib.h
r3897 r3904 474 474 const char *, const char *); 475 475 int _path (char *, const char *); 476 int _path2(const char *pszName, const char *pszSuffixes, char *pszDst, size_t cbDst); 476 477 int _read_kbd (int, int, int); 477 478 void _remext (char *); … … 480 481 void _scrsize (int *); 481 482 void _searchenv (const char *, const char *, char *); 483 int _searchenv2(const char *pszEnvVar, const char *pszName, unsigned fFlags, const char *pszSuffixes, 484 char *pszDst, size_t cbDst); 485 int _searchenv2_value(const char *pszSearchPath, const char *pszName, unsigned fFlags, const char *pszSuffixes, 486 char *pszDst, size_t cbDst); 487 int _searchenv2_has_suffix(const char *pszName, size_t cchName, const char *pszSuffixes); 488 int _searchenv2_one_file(char *pszDst, size_t cbDst, size_t cchName, unsigned fFlags, const char *pszSuffixes); 489 /** @name _SEARCHENV2_F_XXX - Flags for _searchenv2(), _searchenv2_value() 490 * and _searchenv2_one_file(). 491 * @{ */ 492 /** Indicates that we're searching for an executable file. */ 493 #define _SEARCHENV2_F_EXEC_FILE 1 494 /** Indicates that we shouldn't explicitly check the current directory before 495 * searching the search path. */ 496 #define _SEARCHENV2_F_SKIP_CURDIR 2 497 /** @} */ 498 482 499 void _sfnlwr (const char *); 483 500 unsigned _sleep2 (unsigned); -
trunk/libc/include/sys/cdefs.h
r3897 r3904 61 61 /** @} */ 62 62 63 /** @name Path Macros 64 * @{ */ 65 /** @def __KLIBC_PATH_SLASH 66 * The default slash character (path component separator). */ 67 /** @def __KLIBC_PATH_SLASH_ALT 68 * Alternative slash character (path component separator). Optional. */ 69 /** @def __KLIBC_PATH_HAVE_DRIVE_LETTERS 70 * Defined if we have driver letters on this platform. */ 71 /** @def __KLIBC_PATH_HAVE_DRIVES 72 * Defined if we have UNC paths on this platform. */ 73 #if defined(__OS2__) || defined(_WIN32) || defined(_WIN64) || defined(__NT__) 74 # define __KLIBC_PATH_SLASH '\\' 75 # define __KLIBC_PATH_SLASH_ALT '/' 76 # define __KLIBC_PATH_HAVE_DRIVE_LETTERS 1 77 # define __KLIBC_PATH_HAVE_UNC 1 78 #else 79 # define __KLIBC_PATH_SLASH '/' 80 # undef __KLIBC_PATH_SLASH_ALT 81 # undef __KLIBC_PATH_HAVE_DRIVE_LETTERS 82 # undef __KLIBC_PATH_HAVE_UNC 83 #endif 84 /** @def __KLIBC_PATH_IS_SLASH 85 * Checks if @a a_ch is a slash character. 86 * @param a_ch The character. */ 87 #ifdef __KLIBC_PATH_SLASH_ALT 88 # define __KLIBC_PATH_IS_SLASH(a_ch) ((a_ch) == __KLIBC_PATH_SLASH || (a_ch) == __KLIBC_PATH_SLASH_ALT) 89 #else 90 # define __KLIBC_PATH_IS_SLASH(a_ch) ((a_ch) == __KLIBC_PATH_SLASH) 91 #endif 92 /** @} */ 93 63 94 /* 64 95 * Compiler checks. … … 177 208 /** @} */ 178 209 210 179 211 /** @name Misc 180 212 * @{ */ -
trunk/libc/src/kNIX/os2/__spawnve.c
r3862 r3904 557 557 /* 558 558 * Resolve the interpreter name. 559 * If the specified name fails, we'll try search the path for it and560 * also adding an .exe extension before we give up.561 * We omit any specified path since we're frequently faced with path562 * differencesbetween OS/2 and the UNIX where the script originated.559 * Try the unchanged name first, then the name with .exe suffix, 560 * then the PATH. In the latter case we skip the directory path 561 * if given, since we're frequently faced with path differences 562 * between OS/2 and the UNIX where the script originated. 563 563 */ 564 564 rc = __libc_back_fsResolve(pszInterpreter, BACKFS_FLAGS_RESOLVE_FULL, &szNativePath[0], NULL); 565 565 if (rc) 566 566 { 567 psz = _getname(pszInterpreter); 568 char szPath[512]; 569 _searchenv(psz, "PATH", szPath); /** @todo _searchenv is not safe, it can easily overflow szPath! */ 570 if (!szPath[0]) 571 { 572 cch = strlen(psz); 573 memcpy(szNativePath, psz, cch + 1); 574 _defext(szNativePath, "exe"); 575 if (szNativePath[cch]) 576 _searchenv(szNativePath, "PATH", szPath); 577 } 578 if (szPath[0]) 567 char szPath[PATH_MAX]; 568 if ( _path2(pszInterpreter, ".exe", szPath, sizeof(szPath)) == 0 569 || ( (psz = _getname(pszInterpreter)) != pszInterpreter 570 && _path2(psz, ".exe", szPath, sizeof(szPath)) == 0) ) 579 571 rc = __libc_back_fsResolve(szPath, BACKFS_FLAGS_RESOLVE_FULL, &szNativePath[0], NULL); 580 572 if (rc) -
trunk/libc/src/libc/emxload/emxloadp.c
r3876 r3904 10 10 int _emxload_prog (const char *name, int seconds) 11 11 { 12 char buf1[MAXPATHLEN];13 12 char buf2[MAXPATHLEN]; 14 13 15 14 if (seconds != _EMXLOAD_INDEFINITE && seconds < 0) 16 15 return -1; 17 _strncpy (buf1, name, sizeof (buf1)); 18 _defext (buf1, "exe"); 19 if (_path (buf2, buf1) != 0 || _abspath (buf2, buf2, sizeof (buf2)) != 0) 16 if ( _path2 (name, ".exe", buf2, sizeof (buf2)) != 0 17 || _abspath (buf2, buf2, sizeof (buf2)) != 0) 20 18 return -1; 21 19 return _emxload_request (_EMXLOAD_LOAD, buf2, seconds); -
trunk/libc/src/libc/libc.def
r3838 r3904 2004 2004 "___libc_Back_fsFileOwnerSet" @2000 2005 2005 "___libc_Back_fsFileOwnerSetFH" @2001 2006 "__path2" @2002 2007 "__searchenv2" @2003 2008 "__searchenv2_has_suffix" @2004 2009 "__searchenv2_one_file" @2005 2010 "__searchenv2_value" @2006 2011 -
trunk/libc/src/libc/misc/path.c
r3879 r3904 1 /* path.c (emx+gcc) -- Copyright (c) 1990-1995 by Eberhard Mattes */ 1 /* $Id$ */ 2 /** @file 3 * kLibC - Implementation of _path() and _path2(). 4 * 5 * @copyright Copyright (C) 2014 knut st. osmundsen <bird-klibc-spam-xiv@anduin.net> 6 * @licenses MIT, BSD2, BSD3, BSD4, LGPLv2.1, LGPLv3, LGPLvFuture. 7 */ 2 8 9 10 /******************************************************************************* 11 * Header Files * 12 *******************************************************************************/ 3 13 #include "libc-alias.h" 14 #include <string.h> 4 15 #include <stdlib.h> 5 #include <string.h>6 #include <io.h>7 16 #include <errno.h> 17 #include <sys/cdefs.h> 18 #include <sys/syslimits.h> 8 19 9 int _path (char *dst, const char *name) 20 21 /** 22 * Find an executable file using the PATH variables. 23 * 24 * If the specified filename includes a volume or/and a path, the environment 25 * variables will not be searched. Instead the file name is taken as it is and 26 * checked whether it is a file we can execute. 27 * 28 * If no volume or path is specified in the filename, the EMXPATH and PATH 29 * environment variables will be searched. 30 * 31 * @returns 0 on success, -1 and errno (ENOENT, EISDIR, EINVAL, EOVERFLOW) on 32 * failure. 33 * @param pszName The file to search for. 34 * @param pszSuffixes Semicolon separated list of suffixes to append to 35 * the filename while searching. Only done if the 36 * specified filename does not already end with one of the 37 * specified extensions. Pass NULL to skip this feature. 38 * @param pszDst Where to store the result if found. This may be used 39 * for temporary buffering while searching. It will be an 40 * empty string on failure. 41 * @param cbDst The size of the destination buffer. 42 * 43 * @since kLIBC v0.6.6 44 */ 45 int _path2(const char *pszName, const char *pszSuffixes, char *pszDst, size_t cbDst) 10 46 { 11 if (strpbrk (name, "/\\:") != NULL) 47 int rc; 48 49 /* 50 * Validate the input. 51 */ 52 if ( cbDst > 1 53 && pszDst 54 && (!pszSuffixes || *pszSuffixes) 55 && pszName) 12 56 { 13 if (access (name, 4) == 0) 14 strcpy (dst, name); 15 else 16 dst[0] = 0; 57 /* 58 * Path or volume specified? 59 */ 60 size_t cchName = strlen(pszName); 61 if ( memchr(pszName, __KLIBC_PATH_SLASH, cchName) != NULL 62 #ifdef __KLIBC_PATH_SLASH_ALT 63 || memchr(pszName, __KLIBC_PATH_SLASH_ALT, cchName) != NULL 64 #endif 65 #ifdef __KLIBC_PATH_HAVE_DRIVE_LETTERS 66 || (cchName >= 2 && pszName[1] == ':') 67 #endif 68 ) 69 { 70 if (cchName < cbDst) 71 { 72 memcpy(pszDst, pszName, cchName + 1); 73 rc = _searchenv2_one_file(pszDst, cbDst, cchName, _SEARCHENV2_F_EXEC_FILE, 74 _searchenv2_has_suffix(pszName, cchName, pszSuffixes) ? NULL : pszSuffixes); 75 } 76 else 77 { 78 errno = EOVERFLOW; 79 rc = -1; 80 } 81 } 82 /* 83 * No path or volume, search the environment variables. 84 */ 85 else 86 { 87 rc = _searchenv2("EMXPATH", pszName, _SEARCHENV2_F_EXEC_FILE, pszSuffixes, pszDst, cbDst); 88 if (rc == -1 && errno == ENOENT) 89 rc = _searchenv2("PATH", pszName, _SEARCHENV2_F_EXEC_FILE | _SEARCHENV2_F_SKIP_CURDIR, 90 pszSuffixes, pszDst, cbDst); 91 } 17 92 } 18 else93 else 19 94 { 20 _searchenv (name, "EMXPATH", dst); 21 if (dst[0] == 0) 22 _searchenv (name, "PATH", dst); 95 errno = EINVAL; 96 rc = -1; 23 97 } 24 if (dst[0] == 0) 25 { 26 errno = ENOENT; 27 return -1; 28 } 29 return 0; 98 return rc; 30 99 } 100 101 102 /** 103 * Find an executable file using the PATH variables (insane version). 104 * 105 * If the specified filename includes a volume or/and a path, the environment 106 * variables will not be searched. Instead the file name is taken as it is and 107 * checked whether it is a file we can execute. 108 * 109 * If no volume or path is specified in the filename, the EMXPATH and PATH 110 * environment variables will be searched. 111 * 112 * @returns 0 on success, -1 and errno (ENOENT, EISDIR, EOVERFLOW) on failure. 113 * @param pszDst Where to store the result if found. This may be used 114 * for temporary buffering while searching. It will be an 115 * empty string on failure. The length of the buffer is 116 * assumed to be at least PATH_MAX. 117 * @param pszName The file to search for. 118 * 119 * @since The _path() function seems to be EMX specific. 120 */ 121 int _path(char *pszDst, const char *pszName) 122 { 123 return _path2(pszName, NULL /*pszSuffixes*/, pszDst, PATH_MAX); 124 } 125 -
trunk/libc/src/libc/misc/searchen.c
r3879 r3904 1 /* searchen.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */ 2 1 /* $Id$ */ 2 /** @file 3 * kLibC - Implementation of _searchenv() and _searchenv2(). 4 * 5 * @copyright Copyright (C) 2014 knut st. osmundsen <bird-klibc-spam-xiv@anduin.net> 6 * @licenses MIT, BSD2, BSD3, BSD4, LGPLv2.1, LGPLv3, LGPLvFuture. 7 */ 8 9 10 /******************************************************************************* 11 * Header Files * 12 *******************************************************************************/ 3 13 #include "libc-alias.h" 14 #include <ctype.h> 15 #include <errno.h> 4 16 #include <stdlib.h> 5 17 #include <string.h> 6 #include < io.h>18 #include <unistd.h> 7 19 #include <emx/io.h> 8 9 void _searchenv (const char *file, const char *var, char *path) 20 #include <sys/cdefs.h> 21 #include <sys/fcntl.h> 22 #include <sys/syslimits.h> 23 24 25 /** 26 * Worker for _searchenv2_value() and _path2() that looks for a file in the 27 * given path. 28 * 29 * @returns 0 on success. -1 is returned on failure together with errno and an 30 * empty string in @a pszDst (if possible). 31 * @errno ENOENT if not found 32 * @errno EISDIR if found but is directory or special file. 33 * @errno EOVERFLOW if any of the suffix combinations caused us to overlow 34 * (lower priority than EISDIR). 35 * 36 * @param pszDst The input / output buffer. This contains a 37 * filename of length @a cchName on input. This 38 * filename may have a suffix from @a pszSuffixes 39 * appended on successful return. On failure, it 40 * will be set to an empty string (if there is room 41 * for it). 42 * @param cbDst The size of the buffer @a pszDst points to. 43 * @param cchName The length of the incoming name. 44 * @param fFlags The search flags, see _SEARCHENV2_F_XXX. 45 * @param pszSuffixes Semicolon separated list of suffixes to append 46 * to the filename. Pass NULL if no suffixes 47 * should be appended. 48 * 49 * @remarks The caller is expected to have used _searchenv2_has_suffix() to 50 * check if the input filename already has an extension. 51 * 52 * @since kLIBC v0.6.6 53 */ 54 int _searchenv2_one_file(char *pszDst, size_t cbDst, size_t cchName, unsigned fFlags, const char *pszSuffixes) 10 55 { 11 char *list, *end; 12 int i; 13 14 strcpy (path, file); 15 if (access (path, 4) == 0) 16 return; 17 list = getenv (var); 18 if (list != NULL) 19 for (;;) 20 { 21 while (*list == ' ' || *list == '\t') ++list; 22 if (*list == 0) break; 23 end = list; 24 while (*end != 0 && *end != ';') ++end; 25 i = end - list; 26 while (i>0 && (list[i-1] == ' ' || list[i-1] == '\t')) --i; 27 if (i != 0) 28 { 29 memcpy (path, list, i); 30 if (!_trslash (list, i, 0)) 31 path[i++] = '\\'; 32 strcpy (path+i, file); 33 if (access (path, 4) == 0) 34 return; 35 } 36 if (*end == 0) break; 37 list = end + 1; 38 } 39 path[0] = 0; 56 int rc; 57 if ( cchName > 0 58 && cchName < cbDst) 59 { 60 int iRetErrno = ENOENT; 61 for (;;) 62 { 63 /* 64 * Check the accesss, making sure it's a regular file (no 65 * directories or other weird files). 66 */ 67 if (_STD(eaccess)(pszDst, fFlags & _SEARCHENV2_F_EXEC_FILE ? X_OK : R_OK) == 0) 68 { 69 struct stat St; 70 rc = _STD(stat)(pszDst, &St); 71 if (rc == 0 && S_ISREG(St.st_mode)) 72 return 0; 73 iRetErrno = EISDIR; 74 } 75 76 /* 77 * Try another suffix? 78 */ 79 if (!pszSuffixes) 80 break; 81 82 /* Find start and end of the next suffix (if there is one). */ 83 while (*pszSuffixes == ';') 84 pszSuffixes++; 85 if (!*pszSuffixes) 86 break; 87 const char *pszEnd = pszSuffixes; 88 while (*pszEnd && *pszEnd != ';') 89 pszEnd++; 90 91 /* Alter the filename. */ 92 size_t cchSuffix = pszEnd - pszSuffixes; 93 if (cchSuffix + cchName < cbDst) 94 { 95 _STD(memcpy)(&pszDst[cchName], pszSuffixes, cchSuffix); 96 pszDst[cchName + cchSuffix] = '\0'; 97 } 98 /* Lazy bird: Retry with the same file name on overflow. */ 99 else if (iRetErrno == ENOENT) 100 iRetErrno = EOVERFLOW; 101 102 /* Advance suffixes. */ 103 pszSuffixes = pszEnd; 104 } 105 106 /* Failed. */ 107 *pszDst = '\0'; 108 errno = iRetErrno; 109 rc = -1; 110 } 111 else 112 { 113 if (cbDst > 0 && pszDst) 114 *pszDst = '\0'; 115 errno = ENOENT; 116 rc = -1; 117 } 118 119 return rc; 40 120 } 121 122 123 /** 124 * Checks if @a pszName already has a suffix from the @a pszSuffix list. 125 * 126 * @returns 1 if it has a suffix from the list, 0 if not. 127 * 128 * @param pszName The filename name. 129 * @param cchName The length of the name. 130 * @param pszSuffixes The semicolon separated list of suffixes. Can 131 * be NULL. 132 * @since kLIBC v0.6.6 133 */ 134 int _searchenv2_has_suffix(const char *pszName, size_t cchName, const char *pszSuffixes) 135 { 136 /* 137 * Enumerate the suffix list (if we have one). 138 */ 139 if (pszSuffixes) 140 { 141 for (;;) 142 { 143 /* 144 * Find the start and end of the next suffix. 145 */ 146 while (*pszSuffixes == ';') 147 pszSuffixes++; 148 if (!*pszSuffixes) 149 break; 150 151 const char *pszEnd = pszSuffixes; 152 char ch; 153 while ((ch = *pszEnd) != '\0' && ch != ';') 154 pszEnd++; 155 156 /* 157 * Check if the filename has this suffix. 158 */ 159 size_t cchSuffix = pszEnd - pszSuffixes; 160 if ( cchSuffix < cchName 161 && _STD(strnicmp)(pszName + cchName - cchSuffix, pszSuffixes, cchSuffix) == 0) 162 { 163 /** @todo check that we didn't barge into a multibyte sequence! */ 164 return 1; 165 } 166 167 /* 168 * Next. 169 */ 170 pszSuffixes = pszEnd; 171 } 172 } 173 return 0; 174 } 175 176 177 /** 178 * Search for a file (@a pszName) using an search path (@a pszSearchPath) and 179 * optionally a list of suffixes. 180 * 181 * The search will first check the @a pszName without any path prepended, unless 182 * _SEARCHENV2_F_SKIP_CURDIR is specified. Then environment variable value will 183 * be taken, split up into a list of paths on semicolon and colon (except drive 184 * letters of course) boundraries, and each path is checked out individually in 185 * the order they appear. 186 * 187 * @returns 0 on success. On failure -1 is returned together with errno and an 188 * empty return string. 189 * @errno EINVAL if @a pszName or @a pszDst is NULL. 190 * @errno ENOENT if not found or if @a pszName is an empty string. 191 * @errno EOVERFLOW if pszName and any suffix is longer than the buffer. 192 * 193 * @param pszSearchPath The search path. 194 * @param pszName The name of the file we're searching for. 195 * @param fFlags Search flags, see _SEARCHENV2_F_XXX. 196 * @param pszSuffixes Semicolon separated list of suffixes to append 197 * to @a pszName while searching. If @a pszName 198 * already include one of the suffixes in this list 199 * (case insensitive check), no suffixes will be 200 * appended. Pass NULL to use @a pszName as it is. 201 * @param pszDst Where to store the filename we find, set to empty string 202 * if not found (errno set). 203 * @param cbDst The size of the buffer @a pszDst points to. 204 * 205 * 206 * @sa _searchenv2() 207 * 208 * @since kLIBC v0.6.6 209 */ 210 int _searchenv2_value(const char *pszSearchPath, const char *pszName, unsigned fFlags, const char *pszSuffixes, 211 char *pszDst, size_t cbDst) 212 { 213 int rc; 214 215 /* 216 * Validate input. 217 */ 218 if ( pszName 219 && *pszName 220 && (!pszSuffixes || *pszSuffixes) 221 && pszDst 222 && cbDst > 0) 223 { 224 /* 225 * If the filename already is using one of the specified suffixes, drop 226 * the suffix search. Quicker doing this up front than for each search 227 * path member. 228 */ 229 size_t const cchName = _STD(strlen)(pszName); 230 if (_searchenv2_has_suffix(pszName, cchName, pszSuffixes)) 231 pszSuffixes = NULL; 232 233 /* 234 * First try the file directly. If it overflows, we won't bother 235 * trying the search path since it'll just construct even longer names. 236 */ 237 if (cchName < cbDst) 238 { 239 if (!(fFlags & _SEARCHENV2_F_SKIP_CURDIR)) 240 { 241 _STD(memcpy)(pszDst, pszName, cchName + 1); 242 rc = _searchenv2_one_file(pszDst, cbDst, cchName, fFlags, pszSuffixes); 243 } 244 else 245 { 246 errno = ENOENT; 247 rc = -1; 248 } 249 if ( rc == -1 250 && errno != EOVERFLOW 251 && pszSearchPath) 252 { 253 /* 254 * Work the search path. We respect both ';' and ':' as 255 * separators here. 256 */ 257 for (;;) 258 { 259 /* 260 * Skip leading spaces and empty paths (we've already checked without 261 * a path above and if the caller used _SEARCHENV2_F_SKIP_CURDIR, we're 262 * still doing the correct thing as such). 263 */ 264 char ch; 265 while ( (ch = *pszSearchPath) == ';' 266 || ch == ':' 267 || isblank(ch)) 268 pszSearchPath++; 269 if (!ch) 270 break; 271 272 /* 273 * Find the end of the current path, using both colon (unix) and 274 * semicolon (DOS) as separators. 275 * 276 * The first char will not be a separator. With the second character 277 * we have to be careful with colon on platforms with drive letters. 278 */ 279 const char *pszStart = pszSearchPath; 280 const char *pszEnd = ++pszSearchPath; 281 ch = *pszSearchPath; 282 if ( ch != '\0' 283 && ch != ';' 284 #ifdef __KLIBC_PATH_HAVE_DRIVE_LETTERS 285 && (ch != ':' || isalpha(*pszStart)) 286 #else 287 && ch != ':' 288 #endif 289 ) 290 { 291 do 292 pszSearchPath++; 293 while ((ch = *pszSearchPath) != '\0' && ch != ';' && ch != ':'); 294 pszEnd = pszSearchPath; 295 296 /* Strip trailing blanks. */ 297 while ((uintptr_t)pszEnd > (uintptr_t)pszStart && isblank(pszEnd[-1])) 298 pszEnd--; 299 } 300 301 /* 302 * Try construct a new name. 303 */ 304 size_t cchPath = pszEnd - pszStart; 305 int cchSlash = _trslash(pszStart, cchPath, 0) == 0; 306 if (cchPath + cchSlash + cchName < cbDst) 307 { 308 _STD(memcpy)(pszDst, pszStart, cchPath); 309 if (cchSlash) 310 pszDst[cchPath++] = __KLIBC_PATH_SLASH; 311 _STD(memcpy)(&pszDst[cchPath], pszName, cchName + 1); 312 313 /* 314 * Test the filename + suffixes. 315 */ 316 rc = _searchenv2_one_file(pszDst, cbDst, cchPath + cchName, fFlags, pszSuffixes); 317 if (!rc) 318 return rc; 319 } 320 /* else: we overflowed - ignore. */ 321 } 322 323 /* Not found. We ignore EOVERFLOW and EISDIR errors here. */ 324 *pszDst = '\0'; 325 errno = ENOENT; 326 rc = -1; 327 } 328 /* else: maybe we found it, maybe we overflowed. */ 329 } 330 else 331 { 332 /* Buffer too small for the name. */ 333 *pszDst = '\0'; 334 errno = EOVERFLOW; 335 rc = -1; 336 } 337 } 338 else 339 { 340 /* Invalid parameter(s). */ 341 if (cbDst > 0 && pszDst) 342 *pszDst = '\0'; 343 errno = pszName && !*pszName ? ENOENT : EINVAL; 344 rc = -1; 345 } 346 return rc; 347 } 348 349 350 /** 351 * Search for a file (@a pszName) using an environment variable (@a pszEnvVar) 352 * and optionally a list of suffixes. 353 * 354 * The search will first check the @a pszName without any path prepended, unless 355 * _SEARCHENV2_F_SKIP_CURDIR is specified. Then environment variable value will 356 * be taken, split up into a list of paths on semicolon and colon (except drive 357 * letters of course) boundraries, and each path is checked out individually in 358 * the order they appear. 359 * 360 * @returns 0 on success. On failure -1 is returned together with errno and an 361 * empty return string. 362 * @errno EINVAL if @a pszName or @a pszDst is NULL. 363 * @errno ENOENT if not found or if @a pszName is an empty string. 364 * @errno EOVERFLOW if pszName and any suffix is longer than the buffer. 365 * 366 * @param pszEnvVar The environment variable. 367 * @param pszName The name of the file we're searching for. 368 * @param fFlags Search flags, see _SEARCHENV2_F_XXX. 369 * @param pszSuffixes Semicolon separated list of suffixes to append 370 * to @a pszName while searching. If @a pszName 371 * already include one of the suffixes in this list 372 * (case insensitive check), no suffixes will be 373 * appended. Pass NULL to use @a pszName as it is. 374 * @param pszDst Where to store the filename we find, set to empty string 375 * if not found (errno set). 376 * @param cbDst The size of the buffer @a pszDst points to. 377 * 378 * @sa _searchenv2_value() 379 * @since kLIBC v0.6.6 380 */ 381 int _searchenv2(const char *pszEnvVar, const char *pszName, unsigned fFlags, const char *pszSuffixes, 382 char *pszDst, size_t cbDst) 383 { 384 return _searchenv2_value(_STD(getenv)(pszEnvVar), pszName, fFlags, pszSuffixes, pszDst, cbDst); 385 } 386 387 388 /** 389 * Search for a file (@a pszName) using an environment variable (@a pszEnvVar), 390 * insane version. 391 * 392 * @errno EINVAL if @a pszName or @a pszDst is NULL. 393 * @errno ENOENT if not found or if @a pszName is an empty string. 394 * @errno EOVERFLOW if pszName and any suffix is longer than the buffer. 395 * 396 * @param pszName The name of the file we're searching for. 397 * @param pszEnvVar The environment variable name. 398 * @param pszDst Where to store the filename we find, set to empty string 399 * if not found (errno set). This buffer must be able to 400 * hold PATH_MAX chars (including the string terminator). 401 * 402 * @sa _searchenv2(), _searchenv2_value() 403 * 404 * @since The _searchenv() also exists in the microsoft runtime library and 405 * probably from the DOS days common to both OS/2 and windows 406 * compilers. 407 */ 408 void _searchenv(const char *pszName, const char *pszEnvVar, char *pszDst) 409 { 410 _searchenv2(pszEnvVar, pszName, _SEARCHENV2_F_EXEC_FILE, NULL /*pszSuffixes*/, pszDst, PATH_MAX); 411 } 412 -
trunk/libc/src/libc/process/spawnvpe.c
r3881 r3904 1 /* spawnvpe.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */ 1 /* $Id$ */ 2 /** @file 3 * kLibC - Implementation of spawnvpe(). 4 * 5 * @copyright Copyright (C) 2014 knut st. osmundsen <bird-klibc-spam-xiv@anduin.net> 6 * @licenses MIT, BSD2, BSD3, BSD4, LGPLv2.1, LGPLv3, LGPLvFuture. 7 */ 2 8 9 10 /******************************************************************************* 11 * Header Files * 12 *******************************************************************************/ 13 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_PROCESS 3 14 #include "libc-alias.h" 15 #include <InnoTekLIBC/logstrict.h> 4 16 #include <stdlib.h> 5 17 #include <process.h> 6 #include <string.h>7 #include <errno.h>8 18 #include <sys/syslimits.h> 9 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_PROCESS10 #include <InnoTekLIBC/logstrict.h>11 19 12 int _STD(spawnvpe)(int mode, const char *name, char * const argv[], char * const envp[]) 20 21 int _STD(spawnvpe)(int fMode, const char *pszName, char * const *papszArgs, char * const *papszEnv) 13 22 { 14 LIBCLOG_ENTER("mode=%#x name=%s argv=%p envp=%p\n", mode, name, argv, envp); 15 char exe[PATH_MAX]; 16 char path[PATH_MAX]; 17 int rc; 23 LIBCLOG_ENTER("fMode=%#x pszName=%s papszArgs=%p papszEnv=%p\n", fMode, pszName, papszArgs, papszEnv); 24 char szResolvedName[PATH_MAX]; 25 if (_path2(pszName, ".exe", szResolvedName, sizeof(szResolvedName)) == 0) 26 { 27 int rc = spawnve(fMode, szResolvedName, papszArgs, papszEnv); 28 LIBCLOG_MIX_RETURN_INT(rc); 29 } 30 LIBCLOG_ERROR_RETURN_INT(-1); 31 } 18 32 19 if (strlen(name) >= sizeof(exe) - 4)20 {21 errno = ENAMETOOLONG;22 LIBCLOG_ERROR_RETURN(-1, "ret -1 - name is too long, %d bytes: %s\n", strlen(name), name);23 }24 strcpy(exe, name);25 _defext(exe, "exe");26 if (_path(path, exe))27 LIBCLOG_ERROR_RETURN_INT(-1);28 rc = spawnve(mode, path, argv, envp);29 LIBCLOG_RETURN_INT(rc);30 }
Note:
See TracChangeset
for help on using the changeset viewer.