comparison src/if_cscope.c @ 1575:0e3e601e66cf v7.1.288

updated for version 7.1-288
author vimboss
date Tue, 01 Apr 2008 12:31:14 +0000
parents f0cfff4dcc2f
children 9e0174515abb
comparison
equal deleted inserted replaced
1574:f1d121474467 1575:0e3e601e66cf
2128 (void)fputs("q\n", csinfo[i].to_fp); 2128 (void)fputs("q\n", csinfo[i].to_fp);
2129 (void)fflush(csinfo[i].to_fp); 2129 (void)fflush(csinfo[i].to_fp);
2130 } 2130 }
2131 #if defined(UNIX) 2131 #if defined(UNIX)
2132 { 2132 {
2133 int waitpid_errno;
2133 int pstat; 2134 int pstat;
2134 pid_t pid; 2135 pid_t pid;
2135 2136
2136 # if defined(HAVE_SIGACTION) 2137 # if defined(HAVE_SIGACTION)
2137 struct sigaction sa, old; 2138 struct sigaction sa, old;
2143 sigaction(SIGALRM, &sa, &old); 2144 sigaction(SIGALRM, &sa, &old);
2144 alarm(2); /* 2 sec timeout */ 2145 alarm(2); /* 2 sec timeout */
2145 2146
2146 /* Block until cscope exits or until timer expires */ 2147 /* Block until cscope exits or until timer expires */
2147 pid = waitpid(csinfo[i].pid, &pstat, 0); 2148 pid = waitpid(csinfo[i].pid, &pstat, 0);
2149 waitpid_errno = errno;
2148 2150
2149 /* cancel pending alarm if still there and restore signal */ 2151 /* cancel pending alarm if still there and restore signal */
2150 alarm(0); 2152 alarm(0);
2151 sigaction(SIGALRM, &old, NULL); 2153 sigaction(SIGALRM, &old, NULL);
2152 # else 2154 # else
2156 * to give cscope a chance to exit quickly. */ 2158 * to give cscope a chance to exit quickly. */
2157 sleep(0); 2159 sleep(0);
2158 for (waited = 0; waited < 40; ++waited) 2160 for (waited = 0; waited < 40; ++waited)
2159 { 2161 {
2160 pid = waitpid(csinfo[i].pid, &pstat, WNOHANG); 2162 pid = waitpid(csinfo[i].pid, &pstat, WNOHANG);
2163 waitpid_errno = errno;
2161 if (pid != 0) 2164 if (pid != 0)
2162 break; /* break unless the process is still running */ 2165 break; /* break unless the process is still running */
2163 mch_delay(50, FALSE); /* sleep 50 ms */ 2166 mch_delay(50, FALSE); /* sleep 50 ms */
2164 } 2167 }
2165 # endif 2168 # endif
2168 * Safety check: If the PID would be zero here, the entire X session 2171 * Safety check: If the PID would be zero here, the entire X session
2169 * would be killed. -1 and 1 are dangerous as well. 2172 * would be killed. -1 and 1 are dangerous as well.
2170 */ 2173 */
2171 if (pid < 0 && csinfo[i].pid > 1) 2174 if (pid < 0 && csinfo[i].pid > 1)
2172 { 2175 {
2173 kill(csinfo[i].pid, SIGKILL); 2176 # ifdef ECHILD
2174 (void)waitpid(csinfo[i].pid, &pstat, 0); 2177 int alive = TRUE;
2178
2179 if (waitpid_errno == ECHILD)
2180 {
2181 /*
2182 * When using 'vim -g', vim is forked and cscope process is
2183 * no longer a child process but a sibling. So waitpid()
2184 * fails with errno being ECHILD (No child processes).
2185 * Don't send SIGKILL to cscope immediately but wait
2186 * (polling) for it to exit normally as result of sending
2187 * the "q" command, hence giving it a chance to clean up
2188 * its temporary files.
2189 */
2190 int waited;
2191
2192 sleep(0);
2193 for (waited = 0; waited < 40; ++waited)
2194 {
2195 /* Check whether cscope process is still alive */
2196 if (kill(csinfo[i].pid, 0) != 0)
2197 {
2198 alive = FALSE; /* cscope process no longer exists */
2199 break;
2200 }
2201 mch_delay(50, FALSE); /* sleep 50ms */
2202 }
2203 }
2204 if (alive)
2205 # endif
2206 {
2207 kill(csinfo[i].pid, SIGKILL);
2208 (void)waitpid(csinfo[i].pid, &pstat, 0);
2209 }
2175 } 2210 }
2176 } 2211 }
2177 #else /* !UNIX */ 2212 #else /* !UNIX */
2178 if (csinfo[i].hProc != NULL) 2213 if (csinfo[i].hProc != NULL)
2179 { 2214 {