Changeset 2020
- Timestamp:
- Jun 12, 2005, 1:52:12 PM (20 years ago)
- Location:
- trunk/src/emx
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/ChangeLog.LIBC
-
Property cvs2svn:cvs-rev
changed from
1.52
to1.53
r2019 r2020 3 3 2005-06-11: knut st. osmundsen <bird-gccos2-spam@anduin.net> 4 4 - libc: 5 o The smallcnv stuff is gone, waste of space since we're not really into 5 o The smallcnv stuff is gone, waste of space since we're not really into 6 6 static linking. Should've done this when switching to gdtoa. 7 7 o Ported the msun and some other math bits from current FreeBSD libc. … … 10 10 if we're gonna catch up on the C99 bits and make libstdc++ happy. 11 11 There are some new headers, complex.h and fenv.h being the importan ones. 12 float.h have gotten some updates while math.h is totally replaced. 12 float.h have gotten some updates while math.h is totally replaced. 13 13 More than 100 standard functions were added! 14 NOTE: msun is using MATH_ERREXCEPT (math_errhandling) and not 14 NOTE: msun is using MATH_ERREXCEPT (math_errhandling) and not 15 15 MATH_ERRNO for error reporting. 16 16 I really hope this is not gonna uncover more OS/2 387 mess. 17 o Handle .cmd, .bat, .btm and hash-bang script files if DosExecPgm() 18 fails. (I'm a little bit uncertain about argv[0], but it appears to work.) 17 19 18 20 2005-06-05: knut st. osmundsen <bird-gccos2-spam@anduin.net> -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/__spawnve.c
-
Property cvs2svn:cvs-rev
changed from
1.15
to1.16
r2019 r2020 11 11 #define INCL_DOSPROCESS 12 12 #define INCL_FSMACROS 13 #define INCL_DOSERRORS 13 14 #include <os2emx.h> 14 15 #include "b_fs.h" … … 114 115 115 116 #define ADD(n) do { \ 116 while ( arg_size + n > arg_alloc) \117 while (cbArgs + n > cbArgsBuf) \ 117 118 { \ 118 arg_alloc+= 512; \119 arg_buf = _trealloc (arg_buf, arg_alloc); \120 if ( arg_buf == NULL) \119 cbArgsBuf += 512; \ 120 pszArgsBuf = _trealloc (pszArgsBuf, cbArgsBuf); \ 121 if (pszArgsBuf == NULL) \ 121 122 { \ 122 123 errno = ENOMEM; \ 123 124 LIBCLOG_RETURN_INT(-1); \ 124 125 } \ 125 arg_ptr = arg_buf + arg_size; \126 pszArg = pszArgsBuf + cbArgs; \ 126 127 } \ 127 arg_size+= n; } while (0)128 129 130 int __spawnve 128 cbArgs += n; } while (0) 129 130 131 int __spawnve(struct _new_proc *np) 131 132 { 132 133 LIBCLOG_ENTER("np=%p:{mode=%#x}\n", (void *)np, np->mode); 133 __LIBC_PSPMPROCESS pEmbryo;134 ULONG mode;135 char *arg_ptr, *arg_buf;136 char *pgm_name, *base;137 const char *src, *s;138 size_t arg_size, arg_alloc, len;139 int i, quote, bs, method;140 134 FS_VAR(); 141 142 arg_buf = NULL; arg_alloc = 0; arg_size = 0; arg_ptr = NULL;143 135 144 136 /* 145 137 * Validate mode. 146 138 */ 147 mode = np->mode;148 switch ( mode & 0xff)139 ULONG ulMode = np->mode; 140 switch (ulMode & 0xff) 149 141 { 150 142 case P_WAIT: … … 154 146 default: 155 147 errno = EINVAL; 156 LIBC_ASSERTM_FAILED("invalid mode 0x%08lx\n", mode);148 LIBC_ASSERTM_FAILED("invalid mode 0x%08lx\n", ulMode); 157 149 LIBCLOG_RETURN_INT(-1); 158 150 } 159 151 160 152 /* 161 * Allocate space for the program name and check if it's an OS/2 shell.153 * Allocate space for the program name and resolve the filename. 162 154 */ 163 pgm_name = alloca (strlen ((const char *)np->fname_off) + 5); 164 strcpy (pgm_name, (const char *)np->fname_off); 165 _defext (pgm_name, "exe"); 166 base = _getname (pgm_name); 167 method = 0; 168 if (stricmp (base, "cmd.exe") == 0 || stricmp (base, "4os2.exe") == 0) 169 method = 1; 155 size_t cch = strlen((const char *)np->fname_off); 156 char *pszPgmName = alloca(cch + 5); 157 memcpy(pszPgmName, (const char *)np->fname_off, cch + 1); 158 _defext(pszPgmName, "exe"); 170 159 char szNativePath[PATH_MAX]; 171 int rc = __libc_back_fsResolve(p gm_name, BACKFS_FLAGS_RESOLVE_FULL, &szNativePath[0], NULL);160 int rc = __libc_back_fsResolve(pszPgmName, BACKFS_FLAGS_RESOLVE_FULL, &szNativePath[0], NULL); 172 161 if (rc) 173 162 { 174 LIBC_ASSERTM_FAILED("Failed to resolve program name: '%s' rc=%d.\n", pgm_name, rc); 175 errno = -rc; 176 LIBCLOG_RETURN_INT(-1); 163 if (pszPgmName[cch]) 164 { 165 pszPgmName[cch] = '\0'; 166 rc = __libc_back_fsResolve(pszPgmName, BACKFS_FLAGS_RESOLVE_FULL, &szNativePath[0], NULL); 167 } 168 if (rc) 169 { 170 LIBC_ASSERTM_FAILED("Failed to resolve program name: '%s' rc=%d.\n", pszPgmName, rc); 171 errno = -rc; 172 LIBCLOG_RETURN_INT(-1); 173 } 177 174 } 178 p gm_name = &szNativePath[0];175 pszPgmName = &szNativePath[0]; 179 176 180 177 /* 181 * Process arguments. 178 * cmd.exe and 4os2.exe needs different argument handling. 179 * (1 == cmd or 4os2 shell, 0 == anything else) 182 180 */ 183 src = (const char *)np->arg_off; 181 char *psz = _getname(pszPgmName); 182 int method = stricmp(psz, "cmd.exe") == 0 183 || stricmp(psz, "4os2.exe") == 0; 184 185 /* 186 * Construct the commandline. 187 */ 188 const char *pszSrc = (const char *)np->arg_off; 189 char *pszArgsBuf = NULL; 190 size_t cbArgsBuf = 0; 191 char *pszArg = NULL; 192 size_t cbArgs = 0; 184 193 if (np->arg_count > 0) 185 194 { 186 ++ src; /* skip flags byte */187 len = strlen (src) + 1;188 ADD (len);189 memcpy (arg_ptr, src, len);190 arg_ptr += len; src += len;195 ++pszSrc; /* skip flags byte */ 196 cch = strlen(pszSrc) + 1; 197 ADD(cch); 198 memcpy(pszArg, pszSrc, cch); 199 pszArg += cch; pszSrc += cch; 191 200 } 201 int i; 192 202 for (i = 1; i < np->arg_count; ++i) 193 203 { 194 204 if (i > 1) 195 205 { 196 ADD 197 * arg_ptr++ = ' ';198 } 199 ++ src; /* skip flags byte */200 quote = FALSE;201 if (* src == 0)202 quote = TRUE;203 else if ( mode & P_QUOTE)204 { 205 if ( src[0] == '@' && src[1] != 0)206 quote = TRUE;206 ADD(1); 207 *pszArg++ = ' '; 208 } 209 ++pszSrc; /* skip flags byte */ 210 BOOL fQuote = FALSE; 211 if (*pszSrc == 0) 212 fQuote = TRUE; 213 else if (ulMode & P_QUOTE) 214 { 215 if (pszSrc[0] == '@' && pszSrc[1] != 0) 216 fQuote = TRUE; 207 217 else 208 for ( s = src; *s != 0; ++s)209 if (* s == '?' || *s== '*')210 { 211 quote = TRUE;218 for (psz = (char *)pszSrc; *psz != 0; ++psz) 219 if (*psz == '?' || *psz == '*') 220 { 221 fQuote = TRUE; 212 222 break; 213 223 } 214 224 } 215 if (!quote) 216 for (s = src; *s != 0; ++s) 217 if (*s == ' ' || *s == '\t' || (*s == '"' && method == 1)) 218 { 219 quote = TRUE; 225 if (!fQuote) 226 { 227 for (psz = (char *)pszSrc; *psz != 0; ++psz) 228 if (*psz == ' ' || *psz == '\t' || (*psz == '"' && method == 1)) 229 { 230 fQuote = TRUE; 220 231 break; 221 232 } 222 if (quote) 223 { 224 ADD (1); 225 *arg_ptr++ = '"'; 226 } 227 bs = 0; 228 while (*src != 0) 229 { 230 if (*src == '"' && method == 0) 233 } 234 if (fQuote) 235 { 236 ADD(1); 237 *pszArg++ = '"'; 238 } 239 size_t bs = 0; 240 while (*pszSrc != 0) 241 { 242 if (*pszSrc == '"' && method == 0) 231 243 { 232 244 ++bs; 233 ADD 234 memset (arg_ptr, '\\', bs); arg_ptr+= bs;245 ADD(bs); 246 memset(pszArg, '\\', bs); pszArg += bs; 235 247 bs = 0; 236 248 } 237 else if (* src == '\\' && method == 0)249 else if (*pszSrc == '\\' && method == 0) 238 250 ++bs; 239 251 else 240 252 bs = 0; 241 ADD 242 * arg_ptr++ = *src;243 ++ src;244 } 245 if ( quote)246 { 247 ADD 248 memset (arg_ptr, '\\', bs); arg_ptr+= bs;249 * arg_ptr++ = '"';250 } 251 ++ src;253 ADD(1); 254 *pszArg++ = *pszSrc; 255 ++pszSrc; 256 } 257 if (fQuote) 258 { 259 ADD(1+bs); 260 memset(pszArg, '\\', bs); pszArg += bs; 261 *pszArg++ = '"'; 262 } 263 ++pszSrc; 252 264 } 253 265 /* The arguments are an array of zero terminated strings, ending with an empty string. */ 254 ADD 255 * arg_ptr++ = '\0';256 * arg_ptr++ = '\0';266 ADD(2); 267 *pszArg++ = '\0'; 268 *pszArg++ = '\0'; 257 269 258 270 … … 261 273 */ 262 274 _fmutex_request(&__libc_gmtxExec, 0); 263 pEmbryo = __libc_spmCreateEmbryo(getpid());275 __LIBC_PSPMPROCESS pEmbryo = __libc_spmCreateEmbryo(getpid()); 264 276 if (pEmbryo) 265 277 { … … 272 284 RESULTCODES resc; 273 285 char szObj[40]; 274 int rc;275 286 276 287 /* … … 278 289 */ 279 290 FS_SAVE_LOAD(); 280 LIBCLOG_MSG("Calling DosExecPgm pgm: %s args: %s\\0%s\\0\\0\n", pgm_name, arg_buf, arg_buf + strlen(arg_buf) + 1); 281 rc = DosExecPgm(szObj, sizeof(szObj), EXEC_ASYNCRESULT, (PCSZ)arg_buf, (PCSZ)np->env_off, &resc, (PCSZ)pgm_name); 291 LIBCLOG_MSG("Calling DosExecPgm pgm: %s args: %s\\0%s\\0\\0\n", pszPgmName, pszArgsBuf, pszArgsBuf + strlen(pszArgsBuf) + 1); 292 rc = DosExecPgm(szObj, sizeof(szObj), EXEC_ASYNCRESULT, (PCSZ)pszArgsBuf, (PCSZ)np->env_off, &resc, (PCSZ)pszPgmName); 293 int cTries = 3; 294 while ( ( rc == ERROR_INVALID_EXE_SIGNATURE 295 || rc == ERROR_BAD_EXE_FORMAT) 296 && --cTries > 0) 297 { 298 /* 299 * This could be a batch, rexx or hash bang script. 300 * The first two is recognized by the filename extension, the latter 301 * requires inspection of the first line of the file. 302 */ 303 char szLineBuf[256]; 304 const char *pszInterpreter = NULL; 305 const char *pszInterpreterArgs = NULL; 306 psz = _getext(pszPgmName); 307 if (psz && (!stricmp(psz, ".cmd") || !stricmp(psz, ".bat") || !stricmp(psz, ".btm"))) 308 { 309 pszInterpreterArgs = "/C"; 310 pszInterpreter = getenv("COMSPEC"); 311 if (!pszInterpreter) 312 { 313 pszInterpreter = getenv("OS2_SHELL"); 314 if (!pszInterpreter) 315 pszInterpreter = stricmp(psz, ".btm") ? "cmd.exe" : "4os2.exe"; 316 } 317 318 /* make sure the slashes in the script name goes the DOS way. */ 319 psz = szNativePath; 320 while ((psz = strchr(szNativePath, '/')) != NULL) 321 *psz++ = '\\'; 322 } 323 else 324 { 325 /* 326 * Read the first line of the file into szLineBuf and terminate 327 * it stripping trailing blanks. 328 */ 329 HFILE hFile = NULLHANDLE; 330 ULONG ulAction = 0; 331 int rc2 = DosOpen((PCSZ)pszPgmName, &hFile, &ulAction, 0, FILE_NORMAL, 332 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, 333 OPEN_FLAGS_SEQUENTIAL | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 334 NULL); 335 if (!rc2) 336 { 337 ULONG cbRead = 0; 338 rc2 = DosRead(hFile, szLineBuf, sizeof(szLineBuf) - 1, &cbRead); 339 DosClose(hFile); 340 if (!rc2) 341 { 342 szLineBuf[cbRead < sizeof(szLineBuf) ? cbRead : sizeof(szLineBuf) - 1] = '\0'; 343 psz = strpbrk(szLineBuf, "\r\n"); 344 if (psz) 345 { 346 register char ch; 347 while ((ch = *--psz) == ' ' || ch == '\t') 348 /* nothing */; 349 psz[1] = '\0'; 350 351 /* 352 * Check for '#[ \t]*!' 353 */ 354 psz = &szLineBuf[0]; 355 if (*psz++ == '#') 356 { 357 while ((ch = *psz) == ' ' && ch == '\t') 358 psz++; 359 if (*psz++ == '!') 360 { 361 while ((ch = *psz) == ' ' && ch == '\t') 362 psz++; 363 pszInterpreter = psz; 364 365 /* 366 * Find end of interpreter and start of potential arguments. 367 * I've never seen quoted interpreter names, so we won't bother with that yet. 368 */ 369 while ((ch = *psz) != ' ' && ch != '\t' && ch != '\0') 370 psz++; 371 if (ch) 372 { 373 *psz++ = '\0'; 374 while ((ch = *psz) == ' ' && ch == '\t') 375 psz++; 376 if (ch) 377 pszInterpreterArgs = psz; 378 } 379 } /* if bang */ 380 } /* if hash */ 381 } /* if full line */ 382 } /* if read */ 383 } /* if open */ 384 } 385 if (!pszInterpreter) 386 break; 387 388 /* 389 * Squeeze the interpreter arguments + the program name into 390 * the argument buffer after argv[0]. 391 * ASSUME that the arguments and program name require no escaping. 392 */ 393 size_t cchPgmName = strlen(pszPgmName); 394 int cchInterpreterArgs = pszInterpreterArgs ? strlen(pszInterpreterArgs) : -1; 395 BOOL fQuote = strpbrk(pszPgmName, " \t") != NULL; 396 cch = cchPgmName + cchInterpreterArgs + 2 + 2 * fQuote; 397 398 /* grow and shift the argument buffer. */ 399 ADD(cch); 400 psz = pszArgsBuf + strlen(pszArgsBuf) + 1; 401 memmove(psz + cch, psz, cbArgs); 402 403 /* add arguments */ 404 if (pszInterpreterArgs) 405 { 406 memcpy(psz, pszInterpreterArgs, cchInterpreterArgs); 407 psz += cchInterpreterArgs; 408 *psz++ = ' '; 409 } 410 411 /* script name */ 412 if (fQuote) 413 *psz++ = '"'; 414 memcpy(psz, pszPgmName, cchPgmName); 415 psz += cchPgmName; 416 if (fQuote) 417 *psz++ = '"'; 418 *psz++ = ' '; 419 420 /* 421 * Resolve the interpreter name. 422 * If the specified name fails, we'll try search the path for it and 423 * also adding an .exe extension before we give up. 424 */ 425 rc = __libc_back_fsResolve(pszInterpreter, BACKFS_FLAGS_RESOLVE_FULL, &szNativePath[0], NULL); 426 if (rc) 427 { 428 char szPath[512]; 429 _searchenv(pszInterpreter, "PATH", szPath); /** @todo _searchenv is not safe, it can easily overflow szPath! */ 430 if (!szPath[0]) 431 { 432 cch = strlen(pszInterpreter); 433 memcpy(szNativePath, pszInterpreter, cch + 1); 434 _defext(szNativePath, "exe"); 435 if (szNativePath[cch]) 436 _searchenv(szNativePath, "PATH", szPath); 437 } 438 if (szPath[0]) 439 rc = __libc_back_fsResolve(szPath, BACKFS_FLAGS_RESOLVE_FULL, &szNativePath[0], NULL); 440 if (rc) 441 break; 442 } 443 444 /* 445 * Try execute it. 446 */ 447 LIBCLOG_MSG("Calling DosExecPgm pgm: %s args: %s\\0%s\\0\\0\n", pszPgmName, pszArgsBuf, pszArgsBuf + strlen(pszArgsBuf) + 1); 448 rc = DosExecPgm(szObj, sizeof(szObj), EXEC_ASYNCRESULT, (PCSZ)pszArgsBuf, (PCSZ)np->env_off, &resc, (PCSZ)pszPgmName); 449 } /* while */ 282 450 FS_RESTORE(); 283 451 if (!rc) … … 290 458 __libc_spmRelease(pEmbryo); 291 459 doInheritDone(); 292 if ( arg_buf != NULL)293 _tfree (arg_buf);460 if (pszArgsBuf != NULL) 461 _tfree(pszArgsBuf); 294 462 _fmutex_release(&__libc_gmtxExec); 295 463 … … 297 465 * Exit depends on the mode. 298 466 */ 299 switch ( mode & 0xff)467 switch (ulMode & 0xff) 300 468 { 301 469 /* … … 332 500 LIBC_ASSERTM(pidEnded == pid, "Expected pid 0x%04lx and got 0x%04lx!\n", pid, pidEnded); 333 501 334 if ( mode == P_OVERLAY)502 if (ulMode == P_OVERLAY) 335 503 { 336 504 LIBCLOG_MSG("Calling DosExit(,0)\n"); … … 354 522 /* won't ever get here! */ 355 523 } 524 else if (rc > 0) 525 _sys_set_errno(rc); 356 526 else 357 _sys_set_errno (rc);527 errno = -rc; 358 528 doInheritDone(); 359 529 } … … 362 532 } 363 533 364 if ( arg_buf != NULL)365 _tfree (arg_buf);534 if (pszArgsBuf != NULL) 535 _tfree(pszArgsBuf); 366 536 _fmutex_release(&__libc_gmtxExec); 367 537 LIBCLOG_RETURN_INT(-1); -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.