diff options
| author | Gerd Moellmann | 2000-09-21 11:48:48 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-09-21 11:48:48 +0000 |
| commit | 0daad115c4fa2dd80610c46f6c33471e81afb239 (patch) | |
| tree | 11a0144d3b77cab330d94d86858977e110803ff7 /src/process.c | |
| parent | 550a625e340938c17c00526b0706ccce19aaeaf8 (diff) | |
| download | emacs-0daad115c4fa2dd80610c46f6c33471e81afb239.tar.gz emacs-0daad115c4fa2dd80610c46f6c33471e81afb239.zip | |
(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.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 225 |
1 files changed, 118 insertions, 107 deletions
diff --git a/src/process.c b/src/process.c index 49dcaea467c..8ce822fdb1b 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -3138,6 +3138,7 @@ This is intended for use by asynchronous process output filters and sentinels.") | |||
| 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 () |
| @@ -3164,9 +3165,9 @@ send_process_trap () | |||
| 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; |
| @@ -3219,7 +3220,7 @@ send_process (proc, buf, len, object) | |||
| 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)) |
| @@ -3247,7 +3248,7 @@ send_process (proc, buf, len, object) | |||
| 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; |
| @@ -3261,7 +3262,7 @@ send_process (proc, buf, len, object) | |||
| 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 | { |
| @@ -3277,128 +3278,138 @@ send_process (proc, buf, len, object) | |||
| 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 | { |
| 3289 | int this = len; | ||
| 3290 | SIGTYPE (*old_sigpipe)(); | ||
| 3285 | 3291 | ||
| 3286 | /* Decide how much data we can send in one batch. | 3292 | /* Decide how much data we can send in one batch. |
| 3287 | Long lines need to be split into multiple batches. */ | 3293 | Long lines need to be split into multiple batches. */ |
| 3288 | if (!NILP (XPROCESS (proc)->pty_flag)) | 3294 | if (!NILP (XPROCESS (proc)->pty_flag)) |
| 3289 | { | 3295 | { |
| 3290 | /* Starting this at zero is always correct when not the first iteration | 3296 | /* Starting this at zero is always correct when not the first iteration |
| 3291 | because the previous iteration ended by sending C-d. | 3297 | because the previous iteration ended by sending C-d. |
| 3292 | It may not be correct for the first iteration | 3298 | It may not be correct for the first iteration |
| 3293 | if a partial line was sent in a separate send_process call. | 3299 | if a partial line was sent in a separate send_process call. |
| 3294 | If that proves worth handling, we need to save linepos | 3300 | If that proves worth handling, we need to save linepos |
| 3295 | in the process object. */ | 3301 | in the process object. */ |
| 3296 | int linepos = 0; | 3302 | int linepos = 0; |
| 3297 | unsigned char *ptr = buf; | 3303 | unsigned char *ptr = (unsigned char *) buf; |
| 3298 | unsigned char *end = buf + len; | 3304 | unsigned char *end = (unsigned char *) buf + len; |
| 3299 | 3305 | ||
| 3300 | /* Scan through this text for a line that is too long. */ | 3306 | /* Scan through this text for a line that is too long. */ |
| 3301 | while (ptr != end && linepos < pty_max_bytes) | 3307 | while (ptr != end && linepos < pty_max_bytes) |
| 3302 | { | 3308 | { |
| 3303 | if (*ptr == '\n') | 3309 | if (*ptr == '\n') |
| 3304 | linepos = 0; | 3310 | linepos = 0; |
| 3305 | else | 3311 | else |
| 3306 | linepos++; | 3312 | linepos++; |
| 3307 | ptr++; | 3313 | ptr++; |
| 3308 | } | 3314 | } |
| 3309 | /* If we found one, break the line there | 3315 | /* If we found one, break the line there |
| 3310 | and put in a C-d to force the buffer through. */ | 3316 | and put in a C-d to force the buffer through. */ |
| 3311 | this = ptr - buf; | 3317 | this = ptr - buf; |
| 3312 | } | 3318 | } |
| 3313 | 3319 | ||
| 3314 | /* Send this batch, using one or more write calls. */ | 3320 | /* Send this batch, using one or more write calls. */ |
| 3315 | while (this > 0) | 3321 | while (this > 0) |
| 3316 | { | 3322 | { |
| 3317 | old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); | 3323 | old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); |
| 3318 | rv = emacs_write (XINT (XPROCESS (proc)->outfd), buf, this); | 3324 | rv = emacs_write (XINT (XPROCESS (proc)->outfd), |
| 3319 | signal (SIGPIPE, old_sigpipe); | 3325 | (char *) buf, this); |
| 3326 | signal (SIGPIPE, old_sigpipe); | ||
| 3320 | 3327 | ||
| 3321 | if (rv < 0) | 3328 | if (rv < 0) |
| 3322 | { | 3329 | { |
| 3323 | if (0 | 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)); |