Mercurial > hg > RemoteEditor > vim7
diff src/if_cscope.c @ 9:6a13985590e6
*** empty log message ***
author | axmo |
---|---|
date | Fri, 29 Aug 2008 15:41:29 +0900 |
parents | 76efa0be13f1 |
children | c16898406ff2 |
line wrap: on
line diff
--- a/src/if_cscope.c Wed Aug 13 17:54:25 2008 +0900 +++ b/src/if_cscope.c Fri Aug 29 15:41:29 2008 +0900 @@ -23,7 +23,6 @@ #else /* not UNIX, must be WIN32 */ # include "vimio.h" -# include <fcntl.h> #endif #include "if_cscope.h" @@ -75,7 +74,7 @@ { "add", cs_add, N_("Add a new database"), "add file|dir [pre-path] [flags]", 0 }, { "find", cs_find, - N_("Query for a pattern"), FIND_USAGE, 1 }, + N_("Query for a pattern"), "find c|d|e|f|g|i|s|t name", 1 }, { "help", cs_help, N_("Show this message"), "help", 0 }, { "kill", cs_kill, @@ -171,7 +170,7 @@ cs_init(); - if (eap->arg == NULL || strlen((const char *)(eap->arg)) == 0) + if (*eap->arg == NUL) { (void)EMSG(_("E562: Usage: cstag <ident>")); return; @@ -1181,7 +1180,16 @@ (void)smsg((char_u *)_("%-5s: %-30s (Usage: %s)"), cmdp->name, _(cmdp->help), cmdp->usage); if (strcmp(cmdp->name, "find") == 0) - MSG_PUTS(FIND_HELP); + MSG_PUTS(_("\n" + " c: Find functions calling this function\n" + " d: Find functions called by this function\n" + " e: Find this egrep pattern\n" + " f: Find this file\n" + " g: Find this definition\n" + " i: Find files #including this file\n" + " s: Find this C symbol\n" + " t: Find assignments to\n")); + cmdp++; } @@ -1225,7 +1233,7 @@ csinfo[i].nIndexHigh = 0; csinfo[i].nIndexLow = 0; #endif - csinfo[i].pid = -1; + csinfo[i].pid = 0; csinfo[i].fr_fp = NULL; csinfo[i].to_fp = NULL; #if defined(WIN32) @@ -1400,7 +1408,7 @@ return NULL; /* Store length of eap->arg before it gets modified by strtok(). */ - eap_arg_len = STRLEN(eap->arg); + eap_arg_len = (int)STRLEN(eap->arg); if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL) return NULL; @@ -2096,6 +2104,18 @@ return CSCOPE_SUCCESS; } +#if defined(UNIX) && defined(SIGALRM) +/* + * Used to catch and ignore SIGALRM below. + */ +/* ARGSUSED */ + static RETSIGTYPE +sig_handler SIGDEFARG(sigarg) +{ + /* do nothing */ + SIGRETURN; +} +#endif /* * PRIVATE: cs_release_csp @@ -2108,9 +2128,6 @@ int i; int freefnpp; { -#if defined(UNIX) - int pstat; -#else /* * Trying to exit normally (not sure whether it is fit to UNIX cscope */ @@ -2119,6 +2136,88 @@ (void)fputs("q\n", csinfo[i].to_fp); (void)fflush(csinfo[i].to_fp); } +#if defined(UNIX) + { + int waitpid_errno; + int pstat; + pid_t pid; + +# if defined(HAVE_SIGACTION) + struct sigaction sa, old; + + /* Use sigaction() to limit the waiting time to two seconds. */ + sigemptyset(&sa.sa_mask); + sa.sa_handler = sig_handler; + sa.sa_flags = SA_NODEFER; + sigaction(SIGALRM, &sa, &old); + alarm(2); /* 2 sec timeout */ + + /* Block until cscope exits or until timer expires */ + pid = waitpid(csinfo[i].pid, &pstat, 0); + waitpid_errno = errno; + + /* cancel pending alarm if still there and restore signal */ + alarm(0); + sigaction(SIGALRM, &old, NULL); +# else + int waited; + + /* Can't use sigaction(), loop for two seconds. First yield the CPU + * to give cscope a chance to exit quickly. */ + sleep(0); + for (waited = 0; waited < 40; ++waited) + { + pid = waitpid(csinfo[i].pid, &pstat, WNOHANG); + waitpid_errno = errno; + if (pid != 0) + break; /* break unless the process is still running */ + mch_delay(50L, FALSE); /* sleep 50 ms */ + } +# endif + /* + * If the cscope process is still running: kill it. + * Safety check: If the PID would be zero here, the entire X session + * would be killed. -1 and 1 are dangerous as well. + */ + if (pid < 0 && csinfo[i].pid > 1) + { +# ifdef ECHILD + int alive = TRUE; + + if (waitpid_errno == ECHILD) + { + /* + * When using 'vim -g', vim is forked and cscope process is + * no longer a child process but a sibling. So waitpid() + * fails with errno being ECHILD (No child processes). + * Don't send SIGKILL to cscope immediately but wait + * (polling) for it to exit normally as result of sending + * the "q" command, hence giving it a chance to clean up + * its temporary files. + */ + int waited; + + sleep(0); + for (waited = 0; waited < 40; ++waited) + { + /* Check whether cscope process is still alive */ + if (kill(csinfo[i].pid, 0) != 0) + { + alive = FALSE; /* cscope process no longer exists */ + break; + } + mch_delay(50L, FALSE); /* sleep 50ms */ + } + } + if (alive) +# endif + { + kill(csinfo[i].pid, SIGKILL); + (void)waitpid(csinfo[i].pid, &pstat, 0); + } + } + } +#else /* !UNIX */ if (csinfo[i].hProc != NULL) { /* Give cscope a chance to exit normally */ @@ -2133,18 +2232,6 @@ if (csinfo[i].to_fp != NULL) (void)fclose(csinfo[i].to_fp); - /* - * Safety check: If the PID would be zero here, the entire X session would - * be killed. -1 and 1 are dangerous as well. - */ -#if defined(UNIX) - if (csinfo[i].pid > 1) - { - kill(csinfo[i].pid, SIGTERM); - (void)waitpid(csinfo[i].pid, &pstat, 0); - } -#endif - if (freefnpp) { vim_free(csinfo[i].fname);