Mercurial > emacs
comparison src/process.c @ 31806:b148beb59511
(process_sent_to): New variable.
(send_process): Workaround for a crash on sparc-sun-solaris-2.6
with GCC 2.95.2 caused by a parameter being clobbered by longjmp.
Declare more parameters volatile.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Thu, 21 Sep 2000 11:48:48 +0000 |
parents | bd258f4dc0fa |
children | 633b826a56f3 |
comparison
equal
deleted
inserted
replaced
31805:5210694a17b4 | 31806:b148beb59511 |
---|---|
3136 } | 3136 } |
3137 | 3137 |
3138 /* Sending data to subprocess */ | 3138 /* Sending data to subprocess */ |
3139 | 3139 |
3140 jmp_buf send_process_frame; | 3140 jmp_buf send_process_frame; |
3141 Lisp_Object process_sent_to; | |
3141 | 3142 |
3142 SIGTYPE | 3143 SIGTYPE |
3143 send_process_trap () | 3144 send_process_trap () |
3144 { | 3145 { |
3145 #ifdef BSD4_1 | 3146 #ifdef BSD4_1 |
3162 This function can evaluate Lisp code and can garbage collect. */ | 3163 This function can evaluate Lisp code and can garbage collect. */ |
3163 | 3164 |
3164 void | 3165 void |
3165 send_process (proc, buf, len, object) | 3166 send_process (proc, buf, len, object) |
3166 volatile Lisp_Object proc; | 3167 volatile Lisp_Object proc; |
3167 unsigned char *buf; | 3168 unsigned char *volatile buf; |
3168 int len; | 3169 volatile int len; |
3169 Lisp_Object object; | 3170 volatile Lisp_Object object; |
3170 { | 3171 { |
3171 /* Use volatile to protect variables from being clobbered by longjmp. */ | 3172 /* Use volatile to protect variables from being clobbered by longjmp. */ |
3172 int rv; | 3173 int rv; |
3173 struct coding_system *coding; | 3174 struct coding_system *coding; |
3174 struct gcpro gcpro1; | 3175 struct gcpro gcpro1; |
3217 coding->dst_multibyte = 0; | 3218 coding->dst_multibyte = 0; |
3218 | 3219 |
3219 if (CODING_REQUIRE_ENCODING (coding)) | 3220 if (CODING_REQUIRE_ENCODING (coding)) |
3220 { | 3221 { |
3221 int require = encoding_buffer_size (coding, len); | 3222 int require = encoding_buffer_size (coding, len); |
3222 int from_byte = -1, from, to; | 3223 int from_byte = -1, from = -1, to = -1; |
3223 unsigned char *temp_buf = NULL; | 3224 unsigned char *temp_buf = NULL; |
3224 | 3225 |
3225 if (BUFFERP (object)) | 3226 if (BUFFERP (object)) |
3226 { | 3227 { |
3227 from_byte = BUF_PTR_BYTE_POS (XBUFFER (object), buf); | 3228 from_byte = BUF_PTR_BYTE_POS (XBUFFER (object), buf); |
3245 buf = (BUFFERP (object) | 3246 buf = (BUFFERP (object) |
3246 ? BUF_BYTE_ADDRESS (XBUFFER (object), from_byte) | 3247 ? BUF_BYTE_ADDRESS (XBUFFER (object), from_byte) |
3247 : XSTRING (object)->data + from_byte); | 3248 : XSTRING (object)->data + from_byte); |
3248 | 3249 |
3249 object = XPROCESS (proc)->encoding_buf; | 3250 object = XPROCESS (proc)->encoding_buf; |
3250 encode_coding (coding, buf, XSTRING (object)->data, | 3251 encode_coding (coding, (char *) buf, XSTRING (object)->data, |
3251 len, STRING_BYTES (XSTRING (object))); | 3252 len, STRING_BYTES (XSTRING (object))); |
3252 len = coding->produced; | 3253 len = coding->produced; |
3253 buf = XSTRING (object)->data; | 3254 buf = XSTRING (object)->data; |
3254 if (temp_buf) | 3255 if (temp_buf) |
3255 xfree (temp_buf); | 3256 xfree (temp_buf); |
3259 vs = get_vms_process_pointer (p->pid); | 3260 vs = get_vms_process_pointer (p->pid); |
3260 if (vs == 0) | 3261 if (vs == 0) |
3261 error ("Could not find this process: %x", p->pid); | 3262 error ("Could not find this process: %x", p->pid); |
3262 else if (write_to_vms_process (vs, buf, len)) | 3263 else if (write_to_vms_process (vs, buf, len)) |
3263 ; | 3264 ; |
3264 #else | 3265 #else /* not VMS */ |
3265 | 3266 |
3266 if (pty_max_bytes == 0) | 3267 if (pty_max_bytes == 0) |
3267 { | 3268 { |
3268 #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) | 3269 #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) |
3269 pty_max_bytes = fpathconf (XFASTINT (XPROCESS (proc)->outfd), | 3270 pty_max_bytes = fpathconf (XFASTINT (XPROCESS (proc)->outfd), |
3275 #endif | 3276 #endif |
3276 /* Deduct one, to leave space for the eof. */ | 3277 /* Deduct one, to leave space for the eof. */ |
3277 pty_max_bytes--; | 3278 pty_max_bytes--; |
3278 } | 3279 } |
3279 | 3280 |
3281 /* 2000-09-21: Emacs 20.7, sparc-sun-solaris-2.6, GCC 2.95.2, | |
3282 CFLAGS="-g -O": The value of the parameter `proc' is clobbered | |
3283 when returning with longjmp despite being declared volatile. */ | |
3280 if (!setjmp (send_process_frame)) | 3284 if (!setjmp (send_process_frame)) |
3281 while (len > 0) | 3285 { |
3282 { | 3286 process_sent_to = proc; |
3283 int this = len; | 3287 while (len > 0) |
3284 SIGTYPE (*old_sigpipe)(); | 3288 { |
3285 | 3289 int this = len; |
3286 /* Decide how much data we can send in one batch. | 3290 SIGTYPE (*old_sigpipe)(); |
3287 Long lines need to be split into multiple batches. */ | 3291 |
3288 if (!NILP (XPROCESS (proc)->pty_flag)) | 3292 /* Decide how much data we can send in one batch. |
3289 { | 3293 Long lines need to be split into multiple batches. */ |
3290 /* Starting this at zero is always correct when not the first iteration | 3294 if (!NILP (XPROCESS (proc)->pty_flag)) |
3291 because the previous iteration ended by sending C-d. | 3295 { |
3292 It may not be correct for the first iteration | 3296 /* Starting this at zero is always correct when not the first iteration |
3293 if a partial line was sent in a separate send_process call. | 3297 because the previous iteration ended by sending C-d. |
3294 If that proves worth handling, we need to save linepos | 3298 It may not be correct for the first iteration |
3295 in the process object. */ | 3299 if a partial line was sent in a separate send_process call. |
3296 int linepos = 0; | 3300 If that proves worth handling, we need to save linepos |
3297 unsigned char *ptr = buf; | 3301 in the process object. */ |
3298 unsigned char *end = buf + len; | 3302 int linepos = 0; |
3299 | 3303 unsigned char *ptr = (unsigned char *) buf; |
3300 /* Scan through this text for a line that is too long. */ | 3304 unsigned char *end = (unsigned char *) buf + len; |
3301 while (ptr != end && linepos < pty_max_bytes) | 3305 |
3302 { | 3306 /* Scan through this text for a line that is too long. */ |
3303 if (*ptr == '\n') | 3307 while (ptr != end && linepos < pty_max_bytes) |
3304 linepos = 0; | 3308 { |
3305 else | 3309 if (*ptr == '\n') |
3306 linepos++; | 3310 linepos = 0; |
3307 ptr++; | 3311 else |
3308 } | 3312 linepos++; |
3309 /* If we found one, break the line there | 3313 ptr++; |
3310 and put in a C-d to force the buffer through. */ | 3314 } |
3311 this = ptr - buf; | 3315 /* If we found one, break the line there |
3312 } | 3316 and put in a C-d to force the buffer through. */ |
3313 | 3317 this = ptr - buf; |
3314 /* Send this batch, using one or more write calls. */ | 3318 } |
3315 while (this > 0) | 3319 |
3316 { | 3320 /* Send this batch, using one or more write calls. */ |
3317 old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); | 3321 while (this > 0) |
3318 rv = emacs_write (XINT (XPROCESS (proc)->outfd), buf, this); | 3322 { |
3319 signal (SIGPIPE, old_sigpipe); | 3323 old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); |
3320 | 3324 rv = emacs_write (XINT (XPROCESS (proc)->outfd), |
3321 if (rv < 0) | 3325 (char *) buf, this); |
3322 { | 3326 signal (SIGPIPE, old_sigpipe); |
3323 if (0 | 3327 |
3328 if (rv < 0) | |
3329 { | |
3330 if (0 | |
3324 #ifdef EWOULDBLOCK | 3331 #ifdef EWOULDBLOCK |
3325 || errno == EWOULDBLOCK | 3332 || errno == EWOULDBLOCK |
3326 #endif | 3333 #endif |
3327 #ifdef EAGAIN | 3334 #ifdef EAGAIN |
3328 || errno == EAGAIN | 3335 || errno == EAGAIN |
3329 #endif | 3336 #endif |
3330 ) | 3337 ) |
3331 /* Buffer is full. Wait, accepting input; | 3338 /* Buffer is full. Wait, accepting input; |
3332 that may allow the program | 3339 that may allow the program |
3333 to finish doing output and read more. */ | 3340 to finish doing output and read more. */ |
3334 { | 3341 { |
3335 Lisp_Object zero; | 3342 Lisp_Object zero; |
3336 int offset; | 3343 int offset = 0; |
3337 | 3344 |
3338 #ifdef BROKEN_PTY_READ_AFTER_EAGAIN | 3345 #ifdef BROKEN_PTY_READ_AFTER_EAGAIN |
3339 /* A gross hack to work around a bug in FreeBSD. | 3346 /* A gross hack to work around a bug in FreeBSD. |
3340 In the following sequence, read(2) returns | 3347 In the following sequence, read(2) returns |
3341 bogus data: | 3348 bogus data: |
3342 | 3349 |
3343 write(2) 1022 bytes | 3350 write(2) 1022 bytes |
3344 write(2) 954 bytes, get EAGAIN | 3351 write(2) 954 bytes, get EAGAIN |
3345 read(2) 1024 bytes in process_read_output | 3352 read(2) 1024 bytes in process_read_output |
3346 read(2) 11 bytes in process_read_output | 3353 read(2) 11 bytes in process_read_output |
3347 | 3354 |
3348 That is, read(2) returns more bytes than have | 3355 That is, read(2) returns more bytes than have |
3349 ever been written successfully. The 1033 bytes | 3356 ever been written successfully. The 1033 bytes |
3350 read are the 1022 bytes written successfully | 3357 read are the 1022 bytes written successfully |
3351 after processing (for example with CRs added if | 3358 after processing (for example with CRs added if |
3352 the terminal is set up that way which it is | 3359 the terminal is set up that way which it is |
3353 here). The same bytes will be seen again in a | 3360 here). The same bytes will be seen again in a |
3354 later read(2), without the CRs. */ | 3361 later read(2), without the CRs. */ |
3355 | 3362 |
3356 if (errno == EAGAIN) | 3363 if (errno == EAGAIN) |
3357 { | 3364 { |
3358 int flags = FWRITE; | 3365 int flags = FWRITE; |
3359 ioctl (XINT (XPROCESS (proc)->outfd), TIOCFLUSH, | 3366 ioctl (XINT (XPROCESS (proc)->outfd), TIOCFLUSH, |
3360 &flags); | 3367 &flags); |
3361 } | 3368 } |
3362 #endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ | 3369 #endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ |
3363 | 3370 |
3364 /* Running filters might relocate buffers or strings. | 3371 /* Running filters might relocate buffers or strings. |
3365 Arrange to relocate BUF. */ | 3372 Arrange to relocate BUF. */ |
3366 if (BUFFERP (object)) | 3373 if (BUFFERP (object)) |
3367 offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf); | 3374 offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf); |
3368 else if (STRINGP (object)) | 3375 else if (STRINGP (object)) |
3369 offset = buf - XSTRING (object)->data; | 3376 offset = buf - XSTRING (object)->data; |
3370 | 3377 |
3371 XSETFASTINT (zero, 0); | 3378 XSETFASTINT (zero, 0); |
3372 #ifdef EMACS_HAS_USECS | 3379 #ifdef EMACS_HAS_USECS |
3373 wait_reading_process_input (0, 20000, zero, 0); | 3380 wait_reading_process_input (0, 20000, zero, 0); |
3374 #else | 3381 #else |
3375 wait_reading_process_input (1, 0, zero, 0); | 3382 wait_reading_process_input (1, 0, zero, 0); |
3376 #endif | 3383 #endif |
3377 | 3384 |
3378 if (BUFFERP (object)) | 3385 if (BUFFERP (object)) |
3379 buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); | 3386 buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); |
3380 else if (STRINGP (object)) | 3387 else if (STRINGP (object)) |
3381 buf = offset + XSTRING (object)->data; | 3388 buf = offset + XSTRING (object)->data; |
3382 | 3389 |
3383 rv = 0; | 3390 rv = 0; |
3384 } | 3391 } |
3385 else | 3392 else |
3386 /* This is a real error. */ | 3393 /* This is a real error. */ |
3387 report_file_error ("writing to process", Fcons (proc, Qnil)); | 3394 report_file_error ("writing to process", Fcons (proc, Qnil)); |
3388 } | 3395 } |
3389 buf += rv; | 3396 buf += rv; |
3390 len -= rv; | 3397 len -= rv; |
3391 this -= rv; | 3398 this -= rv; |
3392 } | 3399 } |
3393 | 3400 |
3394 /* If we sent just part of the string, put in an EOF | 3401 /* If we sent just part of the string, put in an EOF |
3395 to force it through, before we send the rest. */ | 3402 to force it through, before we send the rest. */ |
3396 if (len > 0) | 3403 if (len > 0) |
3397 Fprocess_send_eof (proc); | 3404 Fprocess_send_eof (proc); |
3398 } | 3405 } |
3399 #endif | 3406 } |
3407 #endif /* not VMS */ | |
3400 else | 3408 else |
3401 { | 3409 { |
3410 #ifndef VMS | |
3411 proc = process_sent_to; | |
3412 #endif | |
3402 XPROCESS (proc)->raw_status_low = Qnil; | 3413 XPROCESS (proc)->raw_status_low = Qnil; |
3403 XPROCESS (proc)->raw_status_high = Qnil; | 3414 XPROCESS (proc)->raw_status_high = Qnil; |
3404 XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (256), Qnil)); | 3415 XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (256), Qnil)); |
3405 XSETINT (XPROCESS (proc)->tick, ++process_tick); | 3416 XSETINT (XPROCESS (proc)->tick, ++process_tick); |
3406 deactivate_process (proc); | 3417 deactivate_process (proc); |