Mirror of the Vim source from https://github.com/vim/vim
Revisão | d0cf8c843186301d546870c2661cfa3e8526b3e4 (tree) |
---|---|
Hora | 2007-09-07 00:39:22 |
Autor | vimboss |
Commiter | vimboss |
updated for version 7.1-100
@@ -24,11 +24,6 @@ | ||
24 | 24 | /* not UNIX, must be WIN32 */ |
25 | 25 | # include "vimio.h" |
26 | 26 | # include <fcntl.h> |
27 | -# include <process.h> | |
28 | -# define STDIN_FILENO 0 | |
29 | -# define STDOUT_FILENO 1 | |
30 | -# define STDERR_FILENO 2 | |
31 | -# define pipe(fds) _pipe(fds, 256, O_TEXT|O_NOINHERIT) | |
32 | 27 | #endif |
33 | 28 | #include "if_cscope.h" |
34 | 29 |
@@ -65,7 +60,7 @@ | ||
65 | 60 | static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)); |
66 | 61 | static char * cs_pathcomponents __ARGS((char *path)); |
67 | 62 | static void cs_print_tags_priv __ARGS((char **, char **, int)); |
68 | -static int cs_read_prompt __ARGS((int )); | |
63 | +static int cs_read_prompt __ARGS((int)); | |
69 | 64 | static void cs_release_csp __ARGS((int, int freefnpp)); |
70 | 65 | static int cs_reset __ARGS((exarg_T *eap)); |
71 | 66 | static char * cs_resolve_file __ARGS((int, char *)); |
@@ -504,7 +499,7 @@ | ||
504 | 499 | #if defined(UNIX) |
505 | 500 | else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) |
506 | 501 | #else |
507 | - /* substitute define S_ISREG from os_unix.h */ | |
502 | + /* WIN32 - substitute define S_ISREG from os_unix.h */ | |
508 | 503 | else if (((statbuf.st_mode) & S_IFMT) == S_IFREG) |
509 | 504 | #endif |
510 | 505 | { |
@@ -717,17 +712,23 @@ | ||
717 | 712 | cs_create_connection(i) |
718 | 713 | int i; |
719 | 714 | { |
720 | - int to_cs[2], from_cs[2], len; | |
721 | - char *prog, *cmd, *ppath = NULL; | |
722 | -#ifndef UNIX | |
723 | - int in_save, out_save, err_save; | |
724 | - long_i ph; | |
725 | -# ifdef FEAT_GUI | |
726 | - HWND activewnd = NULL; | |
727 | - HWND consolewnd = NULL; | |
728 | -# endif | |
715 | +#ifdef UNIX | |
716 | + int to_cs[2], from_cs[2]; | |
717 | +#endif | |
718 | + int len; | |
719 | + char *prog, *cmd, *ppath = NULL; | |
720 | +#ifdef WIN32 | |
721 | + int fd; | |
722 | + SECURITY_ATTRIBUTES sa; | |
723 | + PROCESS_INFORMATION pi; | |
724 | + STARTUPINFO si; | |
725 | + BOOL pipe_stdin = FALSE, pipe_stdout = FALSE; | |
726 | + HANDLE stdin_rd, stdout_rd; | |
727 | + HANDLE stdout_wr, stdin_wr; | |
728 | + BOOL created; | |
729 | 729 | #endif |
730 | 730 | |
731 | +#if defined(UNIX) | |
731 | 732 | /* |
732 | 733 | * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from |
733 | 734 | * from_cs[0] and writes to to_cs[1]. |
@@ -748,18 +749,12 @@ | ||
748 | 749 | return CSCOPE_FAILURE; |
749 | 750 | } |
750 | 751 | |
751 | -#if defined(UNIX) | |
752 | 752 | switch (csinfo[i].pid = fork()) |
753 | 753 | { |
754 | 754 | case -1: |
755 | 755 | (void)EMSG(_("E622: Could not fork for cscope")); |
756 | 756 | goto err_closing; |
757 | 757 | case 0: /* child: run cscope. */ |
758 | -#else | |
759 | - in_save = dup(STDIN_FILENO); | |
760 | - out_save = dup(STDOUT_FILENO); | |
761 | - err_save = dup(STDERR_FILENO); | |
762 | -#endif | |
763 | 758 | if (dup2(to_cs[0], STDIN_FILENO) == -1) |
764 | 759 | PERROR("cs_create_connection 1"); |
765 | 760 | if (dup2(from_cs[1], STDOUT_FILENO) == -1) |
@@ -768,15 +763,32 @@ | ||
768 | 763 | PERROR("cs_create_connection 3"); |
769 | 764 | |
770 | 765 | /* close unused */ |
771 | -#if defined(UNIX) | |
772 | 766 | (void)close(to_cs[1]); |
773 | 767 | (void)close(from_cs[0]); |
774 | 768 | #else |
775 | - /* On win32 we must close opposite ends because we are the parent */ | |
776 | - (void)close(to_cs[0]); | |
777 | - to_cs[0] = -1; | |
778 | - (void)close(from_cs[1]); | |
779 | - from_cs[1] = -1; | |
769 | + /* WIN32 */ | |
770 | + /* Create pipes to communicate with cscope */ | |
771 | + sa.nLength = sizeof(SECURITY_ATTRIBUTES); | |
772 | + sa.bInheritHandle = TRUE; | |
773 | + sa.lpSecurityDescriptor = NULL; | |
774 | + | |
775 | + if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0)) | |
776 | + || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0))) | |
777 | + { | |
778 | + (void)EMSG(_("E566: Could not create cscope pipes")); | |
779 | +err_closing: | |
780 | + if (pipe_stdin) | |
781 | + { | |
782 | + CloseHandle(stdin_rd); | |
783 | + CloseHandle(stdin_wr); | |
784 | + } | |
785 | + if (pipe_stdout) | |
786 | + { | |
787 | + CloseHandle(stdout_rd); | |
788 | + CloseHandle(stdout_wr); | |
789 | + } | |
790 | + return CSCOPE_FAILURE; | |
791 | + } | |
780 | 792 | #endif |
781 | 793 | /* expand the cscope exec for env var's */ |
782 | 794 | if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL) |
@@ -784,6 +796,7 @@ | ||
784 | 796 | #ifdef UNIX |
785 | 797 | return CSCOPE_FAILURE; |
786 | 798 | #else |
799 | + /* WIN32 */ | |
787 | 800 | goto err_closing; |
788 | 801 | #endif |
789 | 802 | } |
@@ -800,6 +813,7 @@ | ||
800 | 813 | #ifdef UNIX |
801 | 814 | return CSCOPE_FAILURE; |
802 | 815 | #else |
816 | + /* WIN32 */ | |
803 | 817 | goto err_closing; |
804 | 818 | #endif |
805 | 819 | } |
@@ -818,6 +832,7 @@ | ||
818 | 832 | #ifdef UNIX |
819 | 833 | return CSCOPE_FAILURE; |
820 | 834 | #else |
835 | + /* WIN32 */ | |
821 | 836 | goto err_closing; |
822 | 837 | #endif |
823 | 838 | } |
@@ -826,6 +841,7 @@ | ||
826 | 841 | #if defined(UNIX) |
827 | 842 | (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname); |
828 | 843 | #else |
844 | + /* WIN32 */ | |
829 | 845 | (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname); |
830 | 846 | #endif |
831 | 847 | if (csinfo[i].ppath != NULL) |
@@ -851,60 +867,6 @@ | ||
851 | 867 | exit(127); |
852 | 868 | /* NOTREACHED */ |
853 | 869 | default: /* parent. */ |
854 | -#else | |
855 | -# ifdef FEAT_GUI | |
856 | - activewnd = GetForegroundWindow(); /* on win9x cscope steals focus */ | |
857 | - /* Dirty hack to hide annoying console window */ | |
858 | - if (AllocConsole()) | |
859 | - { | |
860 | - char *title; | |
861 | - title = (char *)alloc(1024); | |
862 | - if (title == NULL) | |
863 | - FreeConsole(); | |
864 | - else | |
865 | - { | |
866 | - GetConsoleTitle(title, 1024); /* save for future restore */ | |
867 | - SetConsoleTitle( | |
868 | - "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS"); | |
869 | - Sleep(40); /* as stated in MS KB we must wait 40 ms */ | |
870 | - consolewnd = FindWindow(NULL, | |
871 | - "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS"); | |
872 | - if (consolewnd != NULL) | |
873 | - ShowWindow(consolewnd, SW_HIDE); | |
874 | - SetConsoleTitle(title); | |
875 | - vim_free(title); | |
876 | - } | |
877 | - } | |
878 | -# endif | |
879 | - /* May be use &shell, &shellquote etc */ | |
880 | -# ifdef __BORLANDC__ | |
881 | - /* BCC 5.5 uses a different function name for spawnlp */ | |
882 | - ph = (long_i)spawnlp(P_NOWAIT, prog, cmd, NULL); | |
883 | -# else | |
884 | - ph = (long_i)_spawnlp(_P_NOWAIT, prog, cmd, NULL); | |
885 | -# endif | |
886 | - vim_free(prog); | |
887 | - vim_free(cmd); | |
888 | -# ifdef FEAT_GUI | |
889 | - /* Dirty hack part two */ | |
890 | - if (activewnd != NULL) | |
891 | - /* restoring focus */ | |
892 | - SetForegroundWindow(activewnd); | |
893 | - if (consolewnd != NULL) | |
894 | - FreeConsole(); | |
895 | - | |
896 | -# endif | |
897 | - if (ph == -1) | |
898 | - { | |
899 | - PERROR(_("cs_create_connection exec failed")); | |
900 | - (void)EMSG(_("E623: Could not spawn cscope process")); | |
901 | - goto err_closing; | |
902 | - } | |
903 | - /* else */ | |
904 | - csinfo[i].pid = 0; | |
905 | - csinfo[i].hProc = (HANDLE)ph; | |
906 | - | |
907 | -#endif /* !UNIX */ | |
908 | 870 | /* |
909 | 871 | * Save the file descriptors for later duplication, and |
910 | 872 | * reopen as streams. |
@@ -914,22 +876,52 @@ | ||
914 | 876 | if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) |
915 | 877 | PERROR(_("cs_create_connection: fdopen for fr_fp failed")); |
916 | 878 | |
917 | -#if defined(UNIX) | |
918 | 879 | /* close unused */ |
919 | 880 | (void)close(to_cs[0]); |
920 | 881 | (void)close(from_cs[1]); |
921 | 882 | |
922 | 883 | break; |
923 | 884 | } |
885 | + | |
924 | 886 | #else |
925 | - /* restore stdhandles */ | |
926 | - dup2(in_save, STDIN_FILENO); | |
927 | - dup2(out_save, STDOUT_FILENO); | |
928 | - dup2(err_save, STDERR_FILENO); | |
929 | - close(in_save); | |
930 | - close(out_save); | |
931 | - close(err_save); | |
932 | -#endif | |
887 | + /* WIN32 */ | |
888 | + /* Create a new process to run cscope and use pipes to talk with it */ | |
889 | + GetStartupInfo(&si); | |
890 | + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; | |
891 | + si.wShowWindow = SW_HIDE; /* Hide child application window */ | |
892 | + si.hStdOutput = stdout_wr; | |
893 | + si.hStdError = stdout_wr; | |
894 | + si.hStdInput = stdin_rd; | |
895 | + created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, | |
896 | + NULL, NULL, &si, &pi); | |
897 | + vim_free(prog); | |
898 | + vim_free(cmd); | |
899 | + | |
900 | + if (!created) | |
901 | + { | |
902 | + PERROR(_("cs_create_connection exec failed")); | |
903 | + (void)EMSG(_("E623: Could not spawn cscope process")); | |
904 | + goto err_closing; | |
905 | + } | |
906 | + /* else */ | |
907 | + csinfo[i].pid = pi.dwProcessId; | |
908 | + csinfo[i].hProc = pi.hProcess; | |
909 | + CloseHandle(pi.hThread); | |
910 | + | |
911 | + /* TODO - tidy up after failure to create files on pipe handles. */ | |
912 | + if (((fd = _open_osfhandle((intptr_t)stdin_wr, _O_TEXT|_O_APPEND)) < 0) | |
913 | + || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL)) | |
914 | + PERROR(_("cs_create_connection: fdopen for to_fp failed")); | |
915 | + if (((fd = _open_osfhandle((intptr_t)stdout_rd, _O_TEXT|_O_RDONLY)) < 0) | |
916 | + || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL)) | |
917 | + PERROR(_("cs_create_connection: fdopen for fr_fp failed")); | |
918 | + | |
919 | + /* Close handles for file descriptors inherited by the cscope process */ | |
920 | + CloseHandle(stdin_rd); | |
921 | + CloseHandle(stdout_wr); | |
922 | + | |
923 | +#endif /* !UNIX */ | |
924 | + | |
933 | 925 | return CSCOPE_SUCCESS; |
934 | 926 | } /* cs_create_connection */ |
935 | 927 |
@@ -2097,8 +2089,8 @@ | ||
2097 | 2089 | /* |
2098 | 2090 | * PRIVATE: cs_release_csp |
2099 | 2091 | * |
2100 | - * does the actual free'ing for the cs ptr with an optional flag of whether | |
2101 | - * or not to free the filename. called by cs_kill and cs_reset. | |
2092 | + * Does the actual free'ing for the cs ptr with an optional flag of whether | |
2093 | + * or not to free the filename. Called by cs_kill and cs_reset. | |
2102 | 2094 | */ |
2103 | 2095 | static void |
2104 | 2096 | cs_release_csp(i, freefnpp) |
@@ -2116,10 +2108,13 @@ | ||
2116 | 2108 | (void)fputs("q\n", csinfo[i].to_fp); |
2117 | 2109 | (void)fflush(csinfo[i].to_fp); |
2118 | 2110 | } |
2119 | - /* give cscope chance to exit normally */ | |
2120 | - if (csinfo[i].hProc != NULL | |
2121 | - && WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) | |
2122 | - TerminateProcess(csinfo[i].hProc, 0); | |
2111 | + if (csinfo[i].hProc != NULL) | |
2112 | + { | |
2113 | + /* Give cscope a chance to exit normally */ | |
2114 | + if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) | |
2115 | + TerminateProcess(csinfo[i].hProc, 0); | |
2116 | + CloseHandle(csinfo[i].hProc); | |
2117 | + } | |
2123 | 2118 | #endif |
2124 | 2119 | |
2125 | 2120 | if (csinfo[i].fr_fp != NULL) |
@@ -2302,6 +2297,21 @@ | ||
2302 | 2297 | return CSCOPE_SUCCESS; |
2303 | 2298 | } /* cs_show */ |
2304 | 2299 | |
2300 | + | |
2301 | +/* | |
2302 | + * PUBLIC: cs_end | |
2303 | + * | |
2304 | + * Only called when VIM exits to quit any cscope sessions. | |
2305 | + */ | |
2306 | + void | |
2307 | +cs_end() | |
2308 | +{ | |
2309 | + int i; | |
2310 | + | |
2311 | + for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) | |
2312 | + cs_release_csp(i, TRUE); | |
2313 | +} | |
2314 | + | |
2305 | 2315 | #endif /* FEAT_CSCOPE */ |
2306 | 2316 | |
2307 | 2317 | /* the end */ |
@@ -72,7 +72,7 @@ | ||
72 | 72 | ino_t st_ino; /* inode number of cscope db */ |
73 | 73 | #else |
74 | 74 | # if defined(WIN32) |
75 | - int pid; /* Can't get pid so set it to 0 ;) */ | |
75 | + DWORD pid; /* PID of the connected cscope process. */ | |
76 | 76 | HANDLE hProc; /* cscope process handle */ |
77 | 77 | DWORD nVolume; /* Volume serial number, instead of st_dev */ |
78 | 78 | DWORD nIndexHigh; /* st_ino has no meaning in the Windows */ |
@@ -1331,6 +1331,9 @@ | ||
1331 | 1331 | #ifdef FEAT_NETBEANS_INTG |
1332 | 1332 | netbeans_end(); |
1333 | 1333 | #endif |
1334 | +#ifdef FEAT_CSCOPE | |
1335 | + cs_end(); | |
1336 | +#endif | |
1334 | 1337 | |
1335 | 1338 | mch_exit(exitval); |
1336 | 1339 | } |
@@ -3671,7 +3674,13 @@ | ||
3671 | 3674 | mainerr_arg_missing((char_u *)filev[-1]); |
3672 | 3675 | if (mch_dirname(cwd, MAXPATHL) != OK) |
3673 | 3676 | return NULL; |
3674 | - if ((p = vim_strsave_escaped_ext(cwd, PATH_ESC_CHARS, '\\', TRUE)) == NULL) | |
3677 | + if ((p = vim_strsave_escaped_ext(cwd, | |
3678 | +#ifdef BACKSLASH_IN_FILENAME | |
3679 | + "", /* rem_backslash() will tell what chars to escape */ | |
3680 | +#else | |
3681 | + PATH_ESC_CHARS, | |
3682 | +#endif | |
3683 | + '\\', TRUE)) == NULL) | |
3675 | 3684 | return NULL; |
3676 | 3685 | ga_init2(&ga, 1, 100); |
3677 | 3686 | ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd "); |
@@ -6,4 +6,5 @@ | ||
6 | 6 | void cs_free_tags __ARGS((void)); |
7 | 7 | void cs_print_tags __ARGS((void)); |
8 | 8 | int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath)); |
9 | +void cs_end __ARGS((void)); | |
9 | 10 | /* vim: set ft=c : */ |
@@ -667,6 +667,8 @@ | ||
667 | 667 | static int included_patches[] = |
668 | 668 | { /* Add new patch number below this line */ |
669 | 669 | /**/ |
670 | + 100, | |
671 | +/**/ | |
670 | 672 | 99, |
671 | 673 | /**/ |
672 | 674 | 98, |