diff options
| author | Eli Zaretskii | 2012-02-24 12:13:20 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2012-02-24 12:13:20 +0200 |
| commit | 58b65bf58c3527e862afd40b64fb54dc116538d5 (patch) | |
| tree | e9a112ff0cebef7a0e2892032fe1265d0eb0a644 | |
| parent | 9486df08b798f31960779d86c60cc341e606b864 (diff) | |
| download | emacs-58b65bf58c3527e862afd40b64fb54dc116538d5.tar.gz emacs-58b65bf58c3527e862afd40b64fb54dc116538d5.zip | |
Fix bug #10674 with infinite re-spawning of cmdproxy.exe.
nt/cmdproxy.c (main): Bypass conversion of the file name in argv[0]
and our own module name to short 8+3 aliases, if the original file
names compare equal. If GetShortPathName fails, compare the base
names of the two file names, and only re-spawn the command line if
the base-name comparison also fails.
| -rw-r--r-- | nt/ChangeLog | 11 | ||||
| -rw-r--r-- | nt/cmdproxy.c | 79 |
2 files changed, 77 insertions, 13 deletions
diff --git a/nt/ChangeLog b/nt/ChangeLog index 919decfbc53..e5358841274 100644 --- a/nt/ChangeLog +++ b/nt/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2012-02-24 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | Prevent endless re-spawning of cmdproxy.exe when some of its | ||
| 4 | parent directories have access limitations. | ||
| 5 | |||
| 6 | * cmdproxy.c (main): Bypass conversion of the file name in argv[0] | ||
| 7 | and our own module name to short 8+3 aliases, if the original file | ||
| 8 | names compare equal. If GetShortPathName fails, compare the base | ||
| 9 | names of the two file names, and only re-spawn the command line if | ||
| 10 | the base-name comparison also fails. (Bug#10674) | ||
| 11 | |||
| 1 | 2012-02-23 Dani Moncayo <dmoncayo@gmail.com> (tiny change) | 12 | 2012-02-23 Dani Moncayo <dmoncayo@gmail.com> (tiny change) |
| 2 | 13 | ||
| 3 | * makefile.w32-in (maybe-copy-distfiles-SH): Fix typo. | 14 | * makefile.w32-in (maybe-copy-distfiles-SH): Fix typo. |
diff --git a/nt/cmdproxy.c b/nt/cmdproxy.c index 980dc5bacd8..7c522440072 100644 --- a/nt/cmdproxy.c +++ b/nt/cmdproxy.c | |||
| @@ -512,7 +512,7 @@ main (int argc, char ** argv) | |||
| 512 | char modname[MAX_PATH]; | 512 | char modname[MAX_PATH]; |
| 513 | char path[MAX_PATH]; | 513 | char path[MAX_PATH]; |
| 514 | char dir[MAX_PATH]; | 514 | char dir[MAX_PATH]; |
| 515 | 515 | int status; | |
| 516 | 516 | ||
| 517 | interactive = TRUE; | 517 | interactive = TRUE; |
| 518 | 518 | ||
| @@ -551,20 +551,73 @@ main (int argc, char ** argv) | |||
| 551 | 551 | ||
| 552 | /* Although Emacs always sets argv[0] to an absolute pathname, we | 552 | /* Although Emacs always sets argv[0] to an absolute pathname, we |
| 553 | might get run in other ways as well, so convert argv[0] to an | 553 | might get run in other ways as well, so convert argv[0] to an |
| 554 | absolute name before comparing to the module name. Don't get | 554 | absolute name before comparing to the module name. */ |
| 555 | caught out by mixed short and long names. */ | ||
| 556 | GetShortPathName (modname, modname, sizeof (modname)); | ||
| 557 | path[0] = '\0'; | 555 | path[0] = '\0'; |
| 558 | if (!SearchPath (NULL, argv[0], ".exe", sizeof (path), path, &progname) | 556 | /* The call to SearchPath will find argv[0] in the current |
| 559 | || !GetShortPathName (path, path, sizeof (path)) | 557 | directory, append ".exe" to it if needed, and also canonicalize |
| 560 | || stricmp (modname, path) != 0) | 558 | it, to resolve references to ".", "..", etc. */ |
| 559 | status = SearchPath (NULL, argv[0], ".exe", sizeof (path), path, | ||
| 560 | &progname); | ||
| 561 | if (!(status > 0 && stricmp (modname, path) == 0)) | ||
| 561 | { | 562 | { |
| 562 | /* We are being used as a helper to run a DOS app; just pass | 563 | if (status <= 0) |
| 563 | command line to DOS app without change. */ | 564 | { |
| 564 | /* TODO: fill in progname. */ | 565 | char *s; |
| 565 | if (spawn (NULL, GetCommandLine (), dir, &rc)) | 566 | |
| 566 | return rc; | 567 | /* Make sure we have argv[0] in path[], as the failed |
| 567 | fail ("Could not run %s\n", GetCommandLine ()); | 568 | SearchPath might not have copied it there. */ |
| 569 | strcpy (path, argv[0]); | ||
| 570 | /* argv[0] could include forward slashes; convert them all | ||
| 571 | to backslashes, for strrchr calls below to DTRT. */ | ||
| 572 | for (s = path; *s; s++) | ||
| 573 | if (*s == '/') | ||
| 574 | *s = '\\'; | ||
| 575 | } | ||
| 576 | /* Perhaps MODNAME and PATH use mixed short and long file names. */ | ||
| 577 | if (!(GetShortPathName (modname, modname, sizeof (modname)) | ||
| 578 | && GetShortPathName (path, path, sizeof (path)) | ||
| 579 | && stricmp (modname, path) == 0)) | ||
| 580 | { | ||
| 581 | /* Sometimes GetShortPathName fails because one or more | ||
| 582 | directories leading to argv[0] have issues with access | ||
| 583 | rights. In that case, at least we can compare the | ||
| 584 | basenames. Note: this disregards the improbable case of | ||
| 585 | invoking a program of the same name from another | ||
| 586 | directory, since the chances of that other executable to | ||
| 587 | be both our namesake and a 16-bit DOS application are nil. */ | ||
| 588 | char *p = strrchr (path, '\\'); | ||
| 589 | char *q = strrchr (modname, '\\'); | ||
| 590 | char *pdot, *qdot; | ||
| 591 | |||
| 592 | if (!p) | ||
| 593 | p = strchr (path, ':'); | ||
| 594 | if (!p) | ||
| 595 | p = path; | ||
| 596 | else | ||
| 597 | p++; | ||
| 598 | if (!q) | ||
| 599 | q = strchr (modname, ':'); | ||
| 600 | if (!q) | ||
| 601 | q = modname; | ||
| 602 | else | ||
| 603 | q++; | ||
| 604 | |||
| 605 | pdot = strrchr (p, '.'); | ||
| 606 | if (!pdot || stricmp (pdot, ".exe") != 0) | ||
| 607 | pdot = p + strlen (p); | ||
| 608 | qdot = strrchr (q, '.'); | ||
| 609 | if (!qdot || stricmp (qdot, ".exe") != 0) | ||
| 610 | qdot = q + strlen (q); | ||
| 611 | if (pdot - p != qdot - q || strnicmp (p, q, pdot - p) != 0) | ||
| 612 | { | ||
| 613 | /* We are being used as a helper to run a DOS app; just | ||
| 614 | pass command line to DOS app without change. */ | ||
| 615 | /* TODO: fill in progname. */ | ||
| 616 | if (spawn (NULL, GetCommandLine (), dir, &rc)) | ||
| 617 | return rc; | ||
| 618 | fail ("Could not run %s\n", GetCommandLine ()); | ||
| 619 | } | ||
| 620 | } | ||
| 568 | } | 621 | } |
| 569 | 622 | ||
| 570 | /* Process command line. If running interactively (-c or /c not | 623 | /* Process command line. If running interactively (-c or /c not |