summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/if_cscope.c204
-rw-r--r--src/if_cscope.h2
-rw-r--r--src/main.c11
-rw-r--r--src/proto/if_cscope.pro1
-rw-r--r--src/version.c2
5 files changed, 121 insertions, 99 deletions
diff --git a/src/if_cscope.c b/src/if_cscope.c
index 445494bcd..151dc91e0 100644
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -24,11 +24,6 @@
/* 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"
@@ -65,7 +60,7 @@ static char * cs_manage_matches __ARGS((char **, char **, int, mcmd_e));
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 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,7 +499,7 @@ staterr:
#if defined(UNIX)
else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
#else
- /* substitute define S_ISREG from os_unix.h */
+ /* WIN32 - substitute define S_ISREG from os_unix.h */
else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
#endif
{
@@ -717,17 +712,23 @@ cs_create_cmd(csoption, pattern)
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
+#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,18 +749,12 @@ err_closing:
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)
@@ -768,15 +763,32 @@ err_closing:
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;
+ /* 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,6 +796,7 @@ err_closing:
#ifdef UNIX
return CSCOPE_FAILURE;
#else
+ /* WIN32 */
goto err_closing;
#endif
}
@@ -800,6 +813,7 @@ err_closing:
#ifdef UNIX
return CSCOPE_FAILURE;
#else
+ /* WIN32 */
goto err_closing;
#endif
}
@@ -818,6 +832,7 @@ err_closing:
#ifdef UNIX
return CSCOPE_FAILURE;
#else
+ /* WIN32 */
goto err_closing;
#endif
}
@@ -826,6 +841,7 @@ err_closing:
#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,60 +867,6 @@ err_closing:
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.
@@ -914,22 +876,52 @@ err_closing:
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
+ /* 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,8 +2089,8 @@ cs_read_prompt(i)
/*
* 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.
+ * 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,10 +2108,13 @@ cs_release_csp(i, freefnpp)
(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);
+ 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)
@@ -2302,6 +2297,21 @@ cs_show(eap)
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 */
/* the end */
diff --git a/src/if_cscope.h b/src/if_cscope.h
index 5dc69e8ff..99d472b9c 100644
--- a/src/if_cscope.h
+++ b/src/if_cscope.h
@@ -72,7 +72,7 @@ typedef struct csi {
ino_t st_ino; /* inode number of cscope db */
#else
# if defined(WIN32)
- int pid; /* Can't get pid so set it to 0 ;) */
+ 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 */
diff --git a/src/main.c b/src/main.c
index ab5d31bf2..906d8bd5e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1331,6 +1331,9 @@ getout(exitval)
#ifdef FEAT_NETBEANS_INTG
netbeans_end();
#endif
+#ifdef FEAT_CSCOPE
+ cs_end();
+#endif
mch_exit(exitval);
}
@@ -3671,7 +3674,13 @@ build_drop_cmd(filec, filev, tabs, sendReply)
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)
+ 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 *)"<C-\\><C-N>:cd ");
diff --git a/src/proto/if_cscope.pro b/src/proto/if_cscope.pro
index 0617d13a9..555a0a4b5 100644
--- a/src/proto/if_cscope.pro
+++ b/src/proto/if_cscope.pro
@@ -6,4 +6,5 @@ int cs_fgets __ARGS((char_u *buf, int size));
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 : */
diff --git a/src/version.c b/src/version.c
index 3fb1ad9d0..761bff65c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -667,6 +667,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 100,
+/**/
99,
/**/
98,