To: vim-dev@vim.org Subject: patch 7.1.100 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 7.1.100 Problem: Win32: Executing cscope doesn't always work properly. Solution: Use another way to invoke cscope. (Mike Williams) Files: src/if_cscope.c, src/if_cscope.h, src/main.c, src/proto/if_cscope.pro *** ../vim-7.1.099/src/if_cscope.c Tue Aug 21 18:02:58 2007 --- src/if_cscope.c Sun Sep 2 16:50:50 2007 *************** *** 24,34 **** /* not UNIX, must be WIN32 */ # include "vimio.h" # include - # include - # define STDIN_FILENO 0 - # define STDOUT_FILENO 1 - # define STDERR_FILENO 2 - # define pipe(fds) _pipe(fds, 256, O_TEXT|O_NOINHERIT) #endif #include "if_cscope.h" --- 24,29 ---- *************** *** 65,71 **** static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)); static char * cs_pathcomponents __ARGS((char *path)); static void cs_print_tags_priv __ARGS((char **, char **, int)); ! static int cs_read_prompt __ARGS((int )); static void cs_release_csp __ARGS((int, int freefnpp)); static int cs_reset __ARGS((exarg_T *eap)); static char * cs_resolve_file __ARGS((int, char *)); --- 60,66 ---- static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)); static char * cs_pathcomponents __ARGS((char *path)); static void cs_print_tags_priv __ARGS((char **, char **, int)); ! static int cs_read_prompt __ARGS((int)); static void cs_release_csp __ARGS((int, int freefnpp)); static int cs_reset __ARGS((exarg_T *eap)); static char * cs_resolve_file __ARGS((int, char *)); *************** *** 504,510 **** #if defined(UNIX) else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) #else ! /* substitute define S_ISREG from os_unix.h */ else if (((statbuf.st_mode) & S_IFMT) == S_IFREG) #endif { --- 499,505 ---- #if defined(UNIX) else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) #else ! /* WIN32 - substitute define S_ISREG from os_unix.h */ else if (((statbuf.st_mode) & S_IFMT) == S_IFREG) #endif { *************** *** 717,733 **** cs_create_connection(i) int i; { ! int to_cs[2], from_cs[2], len; ! char *prog, *cmd, *ppath = NULL; ! #ifndef UNIX ! int in_save, out_save, err_save; ! long_i ph; ! # ifdef FEAT_GUI ! HWND activewnd = NULL; ! HWND consolewnd = NULL; ! # endif #endif /* * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from * from_cs[0] and writes to to_cs[1]. --- 712,734 ---- cs_create_connection(i) int i; { ! #ifdef UNIX ! int to_cs[2], from_cs[2]; ! #endif ! int len; ! char *prog, *cmd, *ppath = NULL; ! #ifdef WIN32 ! int fd; ! SECURITY_ATTRIBUTES sa; ! PROCESS_INFORMATION pi; ! STARTUPINFO si; ! BOOL pipe_stdin = FALSE, pipe_stdout = FALSE; ! HANDLE stdin_rd, stdout_rd; ! HANDLE stdout_wr, stdin_wr; ! BOOL created; #endif + #if defined(UNIX) /* * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from * from_cs[0] and writes to to_cs[1]. *************** *** 748,765 **** return CSCOPE_FAILURE; } - #if defined(UNIX) switch (csinfo[i].pid = fork()) { case -1: (void)EMSG(_("E622: Could not fork for cscope")); goto err_closing; case 0: /* child: run cscope. */ - #else - in_save = dup(STDIN_FILENO); - out_save = dup(STDOUT_FILENO); - err_save = dup(STDERR_FILENO); - #endif if (dup2(to_cs[0], STDIN_FILENO) == -1) PERROR("cs_create_connection 1"); if (dup2(from_cs[1], STDOUT_FILENO) == -1) --- 749,760 ---- *************** *** 768,782 **** PERROR("cs_create_connection 3"); /* close unused */ - #if defined(UNIX) (void)close(to_cs[1]); (void)close(from_cs[0]); #else ! /* On win32 we must close opposite ends because we are the parent */ ! (void)close(to_cs[0]); ! to_cs[0] = -1; ! (void)close(from_cs[1]); ! from_cs[1] = -1; #endif /* expand the cscope exec for env var's */ if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL) --- 763,794 ---- PERROR("cs_create_connection 3"); /* close unused */ (void)close(to_cs[1]); (void)close(from_cs[0]); #else ! /* WIN32 */ ! /* Create pipes to communicate with cscope */ ! sa.nLength = sizeof(SECURITY_ATTRIBUTES); ! sa.bInheritHandle = TRUE; ! sa.lpSecurityDescriptor = NULL; ! ! if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0)) ! || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0))) ! { ! (void)EMSG(_("E566: Could not create cscope pipes")); ! err_closing: ! if (pipe_stdin) ! { ! CloseHandle(stdin_rd); ! CloseHandle(stdin_wr); ! } ! if (pipe_stdout) ! { ! CloseHandle(stdout_rd); ! CloseHandle(stdout_wr); ! } ! return CSCOPE_FAILURE; ! } #endif /* expand the cscope exec for env var's */ if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL) *************** *** 784,789 **** --- 796,802 ---- #ifdef UNIX return CSCOPE_FAILURE; #else + /* WIN32 */ goto err_closing; #endif } *************** *** 800,805 **** --- 813,819 ---- #ifdef UNIX return CSCOPE_FAILURE; #else + /* WIN32 */ goto err_closing; #endif } *************** *** 818,823 **** --- 832,838 ---- #ifdef UNIX return CSCOPE_FAILURE; #else + /* WIN32 */ goto err_closing; #endif } *************** *** 826,831 **** --- 841,847 ---- #if defined(UNIX) (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname); #else + /* WIN32 */ (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname); #endif if (csinfo[i].ppath != NULL) *************** *** 851,910 **** exit(127); /* NOTREACHED */ default: /* parent. */ - #else - # ifdef FEAT_GUI - activewnd = GetForegroundWindow(); /* on win9x cscope steals focus */ - /* Dirty hack to hide annoying console window */ - if (AllocConsole()) - { - char *title; - title = (char *)alloc(1024); - if (title == NULL) - FreeConsole(); - else - { - GetConsoleTitle(title, 1024); /* save for future restore */ - SetConsoleTitle( - "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS"); - Sleep(40); /* as stated in MS KB we must wait 40 ms */ - consolewnd = FindWindow(NULL, - "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS"); - if (consolewnd != NULL) - ShowWindow(consolewnd, SW_HIDE); - SetConsoleTitle(title); - vim_free(title); - } - } - # endif - /* May be use &shell, &shellquote etc */ - # ifdef __BORLANDC__ - /* BCC 5.5 uses a different function name for spawnlp */ - ph = (long_i)spawnlp(P_NOWAIT, prog, cmd, NULL); - # else - ph = (long_i)_spawnlp(_P_NOWAIT, prog, cmd, NULL); - # endif - vim_free(prog); - vim_free(cmd); - # ifdef FEAT_GUI - /* Dirty hack part two */ - if (activewnd != NULL) - /* restoring focus */ - SetForegroundWindow(activewnd); - if (consolewnd != NULL) - FreeConsole(); - - # endif - if (ph == -1) - { - PERROR(_("cs_create_connection exec failed")); - (void)EMSG(_("E623: Could not spawn cscope process")); - goto err_closing; - } - /* else */ - csinfo[i].pid = 0; - csinfo[i].hProc = (HANDLE)ph; - - #endif /* !UNIX */ /* * Save the file descriptors for later duplication, and * reopen as streams. --- 867,872 ---- *************** *** 914,935 **** if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) PERROR(_("cs_create_connection: fdopen for fr_fp failed")); - #if defined(UNIX) /* close unused */ (void)close(to_cs[0]); (void)close(from_cs[1]); break; } #else ! /* restore stdhandles */ ! dup2(in_save, STDIN_FILENO); ! dup2(out_save, STDOUT_FILENO); ! dup2(err_save, STDERR_FILENO); ! close(in_save); ! close(out_save); ! close(err_save); ! #endif return CSCOPE_SUCCESS; } /* cs_create_connection */ --- 876,927 ---- if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) PERROR(_("cs_create_connection: fdopen for fr_fp failed")); /* close unused */ (void)close(to_cs[0]); (void)close(from_cs[1]); break; } + #else ! /* WIN32 */ ! /* Create a new process to run cscope and use pipes to talk with it */ ! GetStartupInfo(&si); ! si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; ! si.wShowWindow = SW_HIDE; /* Hide child application window */ ! si.hStdOutput = stdout_wr; ! si.hStdError = stdout_wr; ! si.hStdInput = stdin_rd; ! created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, ! NULL, NULL, &si, &pi); ! vim_free(prog); ! vim_free(cmd); ! ! if (!created) ! { ! PERROR(_("cs_create_connection exec failed")); ! (void)EMSG(_("E623: Could not spawn cscope process")); ! goto err_closing; ! } ! /* else */ ! csinfo[i].pid = pi.dwProcessId; ! csinfo[i].hProc = pi.hProcess; ! CloseHandle(pi.hThread); ! ! /* TODO - tidy up after failure to create files on pipe handles. */ ! if (((fd = _open_osfhandle((intptr_t)stdin_wr, _O_TEXT|_O_APPEND)) < 0) ! || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL)) ! PERROR(_("cs_create_connection: fdopen for to_fp failed")); ! if (((fd = _open_osfhandle((intptr_t)stdout_rd, _O_TEXT|_O_RDONLY)) < 0) ! || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL)) ! PERROR(_("cs_create_connection: fdopen for fr_fp failed")); ! ! /* Close handles for file descriptors inherited by the cscope process */ ! CloseHandle(stdin_rd); ! CloseHandle(stdout_wr); ! ! #endif /* !UNIX */ ! return CSCOPE_SUCCESS; } /* cs_create_connection */ *************** *** 2097,2104 **** /* * PRIVATE: cs_release_csp * ! * does the actual free'ing for the cs ptr with an optional flag of whether ! * or not to free the filename. called by cs_kill and cs_reset. */ static void cs_release_csp(i, freefnpp) --- 2089,2096 ---- /* * PRIVATE: cs_release_csp * ! * Does the actual free'ing for the cs ptr with an optional flag of whether ! * or not to free the filename. Called by cs_kill and cs_reset. */ static void cs_release_csp(i, freefnpp) *************** *** 2116,2125 **** (void)fputs("q\n", csinfo[i].to_fp); (void)fflush(csinfo[i].to_fp); } ! /* give cscope chance to exit normally */ ! if (csinfo[i].hProc != NULL ! && WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) ! TerminateProcess(csinfo[i].hProc, 0); #endif if (csinfo[i].fr_fp != NULL) --- 2108,2120 ---- (void)fputs("q\n", csinfo[i].to_fp); (void)fflush(csinfo[i].to_fp); } ! if (csinfo[i].hProc != NULL) ! { ! /* Give cscope a chance to exit normally */ ! if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) ! TerminateProcess(csinfo[i].hProc, 0); ! CloseHandle(csinfo[i].hProc); ! } #endif if (csinfo[i].fr_fp != NULL) *************** *** 2301,2306 **** --- 2296,2316 ---- wait_return(TRUE); return CSCOPE_SUCCESS; } /* cs_show */ + + + /* + * PUBLIC: cs_end + * + * Only called when VIM exits to quit any cscope sessions. + */ + void + cs_end() + { + int i; + + for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + cs_release_csp(i, TRUE); + } #endif /* FEAT_CSCOPE */ *** ../vim-7.1.099/src/if_cscope.h Thu Jun 30 23:59:58 2005 --- src/if_cscope.h Sun Sep 2 16:51:08 2007 *************** *** 72,78 **** ino_t st_ino; /* inode number of cscope db */ #else # if defined(WIN32) ! int pid; /* Can't get pid so set it to 0 ;) */ HANDLE hProc; /* cscope process handle */ DWORD nVolume; /* Volume serial number, instead of st_dev */ DWORD nIndexHigh; /* st_ino has no meaning in the Windows */ --- 72,78 ---- ino_t st_ino; /* inode number of cscope db */ #else # if defined(WIN32) ! DWORD pid; /* PID of the connected cscope process. */ HANDLE hProc; /* cscope process handle */ DWORD nVolume; /* Volume serial number, instead of st_dev */ DWORD nIndexHigh; /* st_ino has no meaning in the Windows */ *** ../vim-7.1.099/src/main.c Thu Aug 30 12:24:21 2007 --- src/main.c Sun Sep 2 16:44:36 2007 *************** *** 1331,1336 **** --- 1331,1339 ---- #ifdef FEAT_NETBEANS_INTG netbeans_end(); #endif + #ifdef FEAT_CSCOPE + cs_end(); + #endif mch_exit(exitval); } *************** *** 3671,3677 **** mainerr_arg_missing((char_u *)filev[-1]); if (mch_dirname(cwd, MAXPATHL) != OK) return NULL; ! if ((p = vim_strsave_escaped_ext(cwd, PATH_ESC_CHARS, '\\', TRUE)) == NULL) return NULL; ga_init2(&ga, 1, 100); ga_concat(&ga, (char_u *)":cd "); --- 3674,3686 ---- mainerr_arg_missing((char_u *)filev[-1]); if (mch_dirname(cwd, MAXPATHL) != OK) return NULL; ! if ((p = vim_strsave_escaped_ext(cwd, ! #ifdef BACKSLASH_IN_FILENAME ! "", /* rem_backslash() will tell what chars to escape */ ! #else ! PATH_ESC_CHARS, ! #endif ! '\\', TRUE)) == NULL) return NULL; ga_init2(&ga, 1, 100); ga_concat(&ga, (char_u *)":cd "); *** ../vim-7.1.099/src/proto/if_cscope.pro Sat May 5 19:15:39 2007 --- src/proto/if_cscope.pro Sun Sep 2 16:51:34 2007 *************** *** 6,9 **** --- 6,10 ---- void cs_free_tags __ARGS((void)); void cs_print_tags __ARGS((void)); int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath)); + void cs_end __ARGS((void)); /* vim: set ft=c : */ *** ../vim-7.1.099/src/version.c Thu Sep 6 16:33:47 2007 --- src/version.c Thu Sep 6 17:27:51 2007 *************** *** 668,669 **** --- 668,671 ---- { /* Add new patch number below this line */ + /**/ + 100, /**/ -- I have to exercise early in the morning before my brain figures out what I'm doing. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ download, build and distribute -- http://www.A-A-P.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///