comparison lisp/process.el @ 859:84762348c6f9

[xemacs-hg @ 2002-06-01 08:06:46 by ben] fix process problems etc. process.el: Insert before, not after, point. buffer.c: Fix bug noted by someone. console-tty.h, device.h, emacs.c, filelock.c, nt.c, process-nt.c, process-unix.c, process.c, redisplay-tty.c, sysdep.c, sysproc.h, win32.c: Redo problem with syssignal.h/sysproc.h dependence noted by Didier -- rather than require one included before the other (error-prone), just include syssignal.h from sysproc.h where it's needed. inline.c: Include sysfile.h due to inline funs in that header. extents.c: Fix bug noted by Andrew Cohen <cohen@andy.bu.edu>. process-unix.c: Fix other bug noted by Andrew Cohen <cohen@andy.bu.edu>. process.c: Add process-has-separate-stderr-p, used by call-process-internal.
author ben
date Sat, 01 Jun 2002 08:06:55 +0000
parents 2b6fa2618f76
children 278c743f1578
comparison
equal deleted inserted replaced
858:2c12fe2da451 859:84762348c6f9
184 ;; end of buffer). 184 ;; end of buffer).
185 (if buffer 185 (if buffer
186 (set-marker (process-mark proc) (point buffer) buffer)) 186 (set-marker (process-mark proc) (point buffer) buffer))
187 (if errbuf 187 (if errbuf
188 (set-marker (process-stderr-mark proc) (point errbuf) errbuf)) 188 (set-marker (process-stderr-mark proc) (point errbuf) errbuf))
189 ;; now do I/O, very carefully! the unwind-protect makes sure 189 ;; bind a function to set the point(s) in buffer and
190 ;; to clear out the sentinel, since it does a `throw', which would 190 ;; stderr-buffer. this is because the documentation says to
191 ;; have no catch (or writes to a file -- we only want this on 191 ;; insert *BEFORE* point, but we end up inserting after because
192 ;; normal exit) 192 ;; only the process mark moves forward, not point. we
193 (unwind-protect 193 ;; synchronize after every place output might happen, in
194 ;; if not NO-WAIT, set a sentinel to return the exit 194 ;; sentinels, and in an unwind-protect, to make *SURE* that
195 ;; status. it will throw to this catch so we can exit 195 ;; point is correct. (We could do this more easily and perhaps
196 ;; properly. 196 ;; more safely using a process filter, but that would create a
197 (catch 'call-process-done 197 ;; LOT of garbage since all the data would get sent in
198 (set-process-sentinel 198 ;; strings.)
199 proc 199 (flet ((synchronize-point (proc)
200 (if no-wait 200 (let ((pb (process-buffer proc))
201 ;; we're trying really really hard to emulate 201 (pm (process-mark proc)))
202 ;; the old call-process, which would save the 202 (if (and pb (buffer-live-p pb) (marker-buffer pm))
203 ;; stderr to a file even if discarding output. so 203 (goto-char pm pb))
204 ;; we set a sentinel to save the output when 204 (if (process-has-separate-stderr-p proc)
205 ;; we finish. 205 (let ((pseb (process-stderr-buffer proc))
206 ;; 206 (psem (process-stderr-mark proc)))
207 ;; #### not clear if we should be doing this. 207 (if (and pseb (not (eq pb pseb))
208 ;; 208 (buffer-live-p pseb)
209 ;; NOTE NOTE NOTE: Due to the total bogosity of 209 (marker-buffer psem))
210 ;; dynamic scoping, and the lack of closures, we 210 (goto-char psem pseb)))))))
211 ;; have to be careful how we write the first 211 ;; now do I/O, very carefully! the unwind-protect makes sure
212 ;; sentinel below since it may be executed after 212 ;; to clear out the sentinel, since it does a `throw', which
213 ;; this function has returned -- thus we fake a 213 ;; would have no catch (or writes to a file -- we only want
214 ;; closure. (This doesn't apply to the second one, 214 ;; this on normal exit)
215 ;; which only gets executed within the 215 (unwind-protect
216 ;; unwind-protect.) 216 ;; if not NO-WAIT, set a sentinel to return the exit
217 (if (and errbuf stderr) 217 ;; status. it will throw to this catch so we can exit
218 (set-process-sentinel 218 ;; properly.
219 proc 219 (catch 'call-process-done
220 `(lambda (proc status) 220 (set-process-sentinel
221 (set-process-sentinel proc nil) 221 proc
222 (with-current-buffer ,errbuf 222 (if no-wait
223 (write-region-internal 223 ;; we're trying really really hard to emulate
224 1 (1+ (buffer-size)) 224 ;; the old call-process, which would save the
225 ,stderr 225 ;; stderr to a file even if discarding output. so
226 nil 'major-rms-kludge-city nil 226 ;; we set a sentinel to save the output when
227 coding-system-for-write)) 227 ;; we finish.
228 (kill-buffer ,errbuf)))) 228 ;;
229 ;; normal sentinel: maybe write out stderr and return 229 ;; #### not clear if we should be doing this.
230 ;; status. 230 ;;
231 #'(lambda (proc status) 231 ;; NOTE NOTE NOTE: Due to the total bogosity of
232 (when (and errbuf stderr) 232 ;; dynamic scoping, and the lack of closures, we
233 (with-current-buffer errbuf 233 ;; have to be careful how we write the first
234 (write-region-internal 234 ;; sentinel below since it may be executed after
235 1 (1+ (buffer-size)) stderr 235 ;; this function has returned -- thus we fake a
236 nil 'major-rms-kludge-city nil 236 ;; closure. (This doesn't apply to the second one,
237 coding-system-for-write))) 237 ;; which only gets executed within the
238 (cond ((eq 'exit (process-status proc)) 238 ;; unwind-protect.)
239 (set-process-sentinel proc nil) 239 (if (and errbuf stderr)
240 (throw 'call-process-done 240 (set-process-sentinel
241 (process-exit-status proc))) 241 proc
242 ((eq 'signal (process-status proc)) 242 `(lambda (proc status)
243 (set-process-sentinel proc nil) 243 (set-process-sentinel proc nil)
244 (throw 'call-process-done status)))))) 244 (synchronize-point proc)
245 (if (not no-wait) 245 (with-current-buffer ,errbuf
246 ;; we're waiting. send the input and loop forever, 246 (write-region-internal
247 ;; handling process output and maybe redisplaying. 247 1 (1+ (buffer-size))
248 ;; exit happens through the sentinel or C-g. if 248 ,stderr
249 ;; C-g, send SIGINT the first time, EOF if not 249 nil 'major-rms-kludge-city nil
250 ;; already done so (might make the process exit), 250 coding-system-for-write))
251 ;; and keep waiting. Another C-g will exit the 251 (kill-buffer ,errbuf))))
252 ;; whole function, and the unwind-protect will 252 ;; normal sentinel: maybe write out stderr and return
253 ;; kill the process. (Hence the documented semantics 253 ;; status.
254 ;; of SIGINT/SIGKILL.) 254 #'(lambda (proc status)
255 (let (eof-sent) 255 (synchronize-point proc)
256 (condition-case nil 256 (when (and errbuf stderr)
257 (progn 257 (with-current-buffer errbuf
258 (when inbuf 258 (write-region-internal
259 (process-send-region proc start end inbuf)) 259 1 (1+ (buffer-size)) stderr
260 (process-send-eof proc) 260 nil 'major-rms-kludge-city nil
261 (setq eof-sent t) 261 coding-system-for-write)))
262 (while t 262 (cond ((eq 'exit (process-status proc))
263 (accept-process-output proc) 263 (set-process-sentinel proc nil)
264 (if display (sit-for 0)))) 264 (throw 'call-process-done
265 (quit 265 (process-exit-status proc)))
266 (process-send-signal 'SIGINT proc) 266 ((eq 'signal (process-status proc))
267 (unless eof-sent 267 (set-process-sentinel proc nil)
268 (process-send-eof proc)) 268 (throw 'call-process-done status))))))
269 (while t 269 (if (not no-wait)
270 (accept-process-output proc) 270 ;; we're waiting. send the input and loop forever,
271 (if display (sit-for 0)))))) 271 ;; handling process output and maybe redisplaying.
272 ;; discard and no wait: send the input, set PROC 272 ;; exit happens through the sentinel or C-g. if
273 ;; and ERRBUF to nil so that the unwind-protect 273 ;; C-g, send SIGINT the first time, EOF if not
274 ;; forms don't erase the sentinel, kill the process, 274 ;; already done so (might make the process exit),
275 ;; or kill ERRBUF (the sentinel does that), and exit. 275 ;; and keep waiting. Another C-g will exit the
276 (when inbuf 276 ;; whole function, and the unwind-protect will
277 (process-send-region proc start end inbuf)) 277 ;; kill the process. (Hence the documented semantics
278 (process-send-eof proc) 278 ;; of SIGINT/SIGKILL.)
279 (setq errbuf nil) 279 (let (eof-sent)
280 (setq proc nil))) 280 (condition-case nil
281 (if proc (set-process-sentinel proc nil))))) 281 (progn
282 ;; unwind-protect forms. 282 (when inbuf
283 (process-send-region proc start end inbuf))
284 (process-send-eof proc)
285 (setq eof-sent t)
286 (while t
287 (accept-process-output proc)
288 (synchronize-point proc)
289 (if display (sit-for 0))))
290 (quit
291 (process-send-signal 'SIGINT proc)
292 (unless eof-sent
293 (process-send-eof proc))
294 (while t
295 (accept-process-output proc)
296 (synchronize-point proc)
297 (if display (sit-for 0))))))
298 ;; discard and no wait: send the input, set PROC
299 ;; and ERRBUF to nil so that the unwind-protect
300 ;; forms don't erase the sentinel, kill the process,
301 ;; or kill ERRBUF (the sentinel does that), and exit.
302 (when inbuf
303 (process-send-region proc start end inbuf))
304 (process-send-eof proc)
305 (setq errbuf nil)
306 (setq proc nil)))
307 ;; inner unwind-protect, once we're ready to do I/O.
308 (when proc
309 (set-process-sentinel proc nil)
310 (synchronize-point proc))))))
311 ;; outer unwind-protect forms, to make sure we always clean up.
283 (if (and inbuf kill-inbuf) (kill-buffer inbuf)) 312 (if (and inbuf kill-inbuf) (kill-buffer inbuf))
284 (if (and errbuf kill-errbuf) (kill-buffer errbuf)) 313 (if (and errbuf kill-errbuf) (kill-buffer errbuf))
285 (condition-case nil 314 (condition-case nil
286 (if (and proc (process-live-p proc)) (kill-process proc)) 315 (if (and proc (process-live-p proc)) (kill-process proc))
287 (error nil))))) 316 (error nil)))))