Hi,

Attached is a patch against 7.1.082 to solve a number of issues with
cscope on Windows.  It no longer jumps through hoops to hide the console
(occasionally failing), fixes a handle leak when killing a connection, 
now reports a process id, and simplifies the Win32 code logic creating 
the connection.  One consequence of the change is that VIM now has to 
explicitly exit the processes running cscope. Windows has no concept of 
patent child processes like Unix - I assume _spawnl() used previously 
tracked child process ids and used an atexit() style method to clear 
them up.

I can't currently test Unix builds so I don't know if I have broken
them.  I haven't tested with BorlandC - from the documentation I have
seen it is all bog standard Win32 API, and should all work from Win98
onwards.  Problem reports more than welcome.

TTFN

Mike
-- 
I'm not tense, just terribly, terribly, terribly, alert.

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

*** vim71-cscope.a45e0b56d1b8/src/if_cscope.c   Mon Aug 20 08:47:12 2007
--- vim71-cscope/src/if_cscope.c        Mon Aug 20 08:47:12 2007
***************
*** 24,34 ****
      /* not UNIX, must be WIN32 */
  # include "vimio.h"
  # include <fcntl.h>
- # include <process.h>
- # 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 ----
***************
*** 509,515 ****
  #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
      {
--- 504,510 ----
  #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
      {
***************
*** 722,738 ****
  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].
--- 717,739 ----
  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].
***************
*** 753,770 ****
        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)
--- 754,765 ----
***************
*** 773,787 ****
            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)
--- 768,799 ----
            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)
***************
*** 789,794 ****
--- 801,807 ----
  #ifdef UNIX
            return CSCOPE_FAILURE;
  #else
+             /* WIN32 */
            goto err_closing;
  #endif
        }
***************
*** 805,810 ****
--- 818,824 ----
  #ifdef UNIX
                return CSCOPE_FAILURE;
  #else
+                 /* WIN32 */
                goto err_closing;
  #endif
            }
***************
*** 823,828 ****
--- 837,843 ----
  #ifdef UNIX
            return CSCOPE_FAILURE;
  #else
+             /* WIN32 */
            goto err_closing;
  #endif
        }
***************
*** 831,836 ****
--- 846,852 ----
  #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)
***************
*** 856,915 ****
        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.
--- 872,877 ----
***************
*** 919,940 ****
        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 */
  
--- 881,932 ----
        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 */
  
***************
*** 2118,2127 ****
        (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)
--- 2110,2122 ----
        (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)
***************
*** 2303,2308 ****
--- 2298,2319 ----
      wait_return(TRUE);
      return CSCOPE_SUCCESS;
  } /* cs_show */
+ 
+ 
+ /*
+  * PUBLIC: cs_end
+  *
+  * Only called when VIM exits to quit any cscope sessions.
+  */
+     void
+ cs_end(void)
+ {
+     int i;
+ 
+     for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++ )
+         cs_release_csp(i, TRUE);
+ 
+ } /* cs_end */
  
  #endif        /* FEAT_CSCOPE */
  
*** vim71-cscope.a45e0b56d1b8/src/if_cscope.h   Mon Aug 20 08:47:12 2007
--- vim71-cscope/src/if_cscope.h        Mon Aug 20 08:47:12 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 */
*** vim71-cscope.a45e0b56d1b8/src/main.c        Mon Aug 20 08:47:12 2007
--- vim71-cscope/src/main.c     Mon Aug 20 08:47:12 2007
***************
*** 1330,1335 ****
--- 1330,1338 ----
  #ifdef FEAT_NETBEANS_INTG
      netbeans_end();
  #endif
+ #ifdef FEAT_CSCOPE
+     cs_end();
+ #endif
  
      mch_exit(exitval);
  }
*** vim71-cscope.a45e0b56d1b8/src/proto/if_cscope.pro   Mon Aug 20 08:47:12 2007
--- vim71-cscope/src/proto/if_cscope.pro        Mon Aug 20 08:47:12 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 : */

Raspunde prin e-mail lui