aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorKenichi Handa <[email protected]>2000-05-20 00:04:37 +0000
committerKenichi Handa <[email protected]>2000-05-20 00:04:37 +0000
commita4a37e652d5717aa8f13e83101f43ef381696532 (patch)
treec20dbef25a45647a104f906c28f0aa8fc7efda67 /src/process.c
parenteba90784ce2bca76105770b44da0a60063e59f94 (diff)
(Fstart_process): GCPRO current_dir before calling
Ffind_operation_coding_system. Encode arguments here. (create_process): Don't encode arguments here. Setup src_multibyte and dst_multibyte members of struct coding. (read_process_output): Setup src_multibyte and dst_multibyte members of struct coding. If the output is to multibyte buffer, always decode the output of the process. Adjust the representation of 8-bit characters to the multibyteness of the output. (send_process): Setup coding->src_multibyte according to the multibyteness of the source.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c255
1 files changed, 130 insertions, 125 deletions
diff --git a/src/process.c b/src/process.c
index 8b23d2f91f..0c8211e6c4 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1082,63 +1082,6 @@ Remaining arguments are strings to give program as arguments.")
CHECK_STRING (program, 2);
-#ifdef VMS
- /* Make a one member argv with all args concatenated
- together separated by a blank. */
- len = STRING_BYTES (XSTRING (program)) + 2;
- for (i = 3; i < nargs; i++)
- {
- tem = args[i];
- CHECK_STRING (tem, i);
- len += STRING_BYTES (XSTRING (tem)) + 1; /* count the blank */
- }
- new_argv = (unsigned char *) alloca (len);
- strcpy (new_argv, XSTRING (program)->data);
- for (i = 3; i < nargs; i++)
- {
- tem = args[i];
- CHECK_STRING (tem, i);
- strcat (new_argv, " ");
- strcat (new_argv, XSTRING (tem)->data);
- }
- /* Need to add code here to check for program existence on VMS */
-
-#else /* not VMS */
- new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
-
- /* If program file name is not absolute, search our path for it */
- if (!IS_DIRECTORY_SEP (XSTRING (program)->data[0])
- && !(XSTRING (program)->size > 1
- && IS_DEVICE_SEP (XSTRING (program)->data[1])))
- {
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
-
- tem = Qnil;
- GCPRO4 (name, program, buffer, current_dir);
- openp (Vexec_path, program, EXEC_SUFFIXES, &tem, 1);
- UNGCPRO;
- if (NILP (tem))
- report_file_error ("Searching for program", Fcons (program, Qnil));
- tem = Fexpand_file_name (tem, Qnil);
- new_argv[0] = XSTRING (tem)->data;
- }
- else
- {
- if (!NILP (Ffile_directory_p (program)))
- error ("Specified program for new process is a directory");
-
- new_argv[0] = XSTRING (program)->data;
- }
-
- for (i = 3; i < nargs; i++)
- {
- tem = args[i];
- CHECK_STRING (tem, i);
- new_argv[i - 2] = XSTRING (tem)->data;
- }
- new_argv[i - 2] = 0;
-#endif /* not VMS */
-
proc = make_process (name);
/* If an error occurs and we can't start the process, we want to
remove it from the process list. This means that each error
@@ -1167,7 +1110,7 @@ Remaining arguments are strings to give program as arguments.")
/* Qt denotes we have not yet called Ffind_operation_coding_system. */
Lisp_Object coding_systems = Qt;
Lisp_Object val, *args2;
- struct gcpro gcpro1;
+ struct gcpro gcpro1, gcpro2;
val = Vcoding_system_for_read;
if (NILP (val))
@@ -1175,7 +1118,7 @@ Remaining arguments are strings to give program as arguments.")
args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2);
args2[0] = Qstart_process;
for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
- GCPRO1 (proc);
+ GCPRO2 (proc, current_dir);
coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
UNGCPRO;
if (CONSP (coding_systems))
@@ -1193,7 +1136,7 @@ Remaining arguments are strings to give program as arguments.")
args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof args2);
args2[0] = Qstart_process;
for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
- GCPRO1 (proc);
+ GCPRO2 (proc, current_dir);
coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
UNGCPRO;
}
@@ -1205,6 +1148,73 @@ Remaining arguments are strings to give program as arguments.")
XPROCESS (proc)->encode_coding_system = val;
}
+#ifdef VMS
+ /* Make a one member argv with all args concatenated
+ together separated by a blank. */
+ len = STRING_BYTES (XSTRING (program)) + 2;
+ for (i = 3; i < nargs; i++)
+ {
+ tem = args[i];
+ CHECK_STRING (tem, i);
+ len += STRING_BYTES (XSTRING (tem)) + 1; /* count the blank */
+ }
+ new_argv = (unsigned char *) alloca (len);
+ strcpy (new_argv, XSTRING (program)->data);
+ for (i = 3; i < nargs; i++)
+ {
+ tem = args[i];
+ CHECK_STRING (tem, i);
+ strcat (new_argv, " ");
+ strcat (new_argv, XSTRING (tem)->data);
+ }
+ /* Need to add code here to check for program existence on VMS */
+
+#else /* not VMS */
+ new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
+
+ /* If program file name is not absolute, search our path for it */
+ if (!IS_DIRECTORY_SEP (XSTRING (program)->data[0])
+ && !(XSTRING (program)->size > 1
+ && IS_DEVICE_SEP (XSTRING (program)->data[1])))
+ {
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+
+ tem = Qnil;
+ GCPRO4 (name, program, buffer, current_dir);
+ openp (Vexec_path, program, EXEC_SUFFIXES, &tem, 1);
+ UNGCPRO;
+ if (NILP (tem))
+ report_file_error ("Searching for program", Fcons (program, Qnil));
+ tem = Fexpand_file_name (tem, Qnil);
+ tem = ENCODE_FILE (tem);
+ new_argv[0] = XSTRING (tem)->data;
+ }
+ else
+ {
+ if (!NILP (Ffile_directory_p (program)))
+ error ("Specified program for new process is a directory");
+
+ tem = ENCODE_FILE (program);
+ new_argv[0] = XSTRING (tem)->data;
+ }
+
+ /* Here we encode arguments by the coding system used for sending
+ data to the process. We don't support using different coding
+ systems for encoding arguments and for encoding data sent to the
+ process. */
+
+ for (i = 3; i < nargs; i++)
+ {
+ tem = args[i];
+ CHECK_STRING (tem, i);
+ if (STRING_MULTIBYTE (tem))
+ tem = (code_convert_string_norecord
+ (tem, XPROCESS (proc)->encode_coding_system, 1));
+ new_argv[i - 2] = XSTRING (tem)->data;
+ }
+ new_argv[i - 2] = 0;
+#endif /* not VMS */
+
XPROCESS (proc)->decoding_buf = make_uninit_string (0);
XPROCESS (proc)->decoding_carryover = make_number (0);
XPROCESS (proc)->encoding_buf = make_uninit_string (0);
@@ -1408,34 +1418,6 @@ create_process (process, new_argv, current_dir)
setup_raw_text_coding_system (proc_encode_coding_system[outchannel]);
}
- if (CODING_REQUIRE_ENCODING (proc_encode_coding_system[outchannel]))
- {
- /* Here we encode arguments by the coding system used for
- sending data to the process. We don't support using
- different coding systems for encoding arguments and for
- encoding data sent to the process. */
- struct gcpro gcpro1;
- int i = 1;
- struct coding_system *coding = proc_encode_coding_system[outchannel];
-
- coding->mode |= CODING_MODE_LAST_BLOCK;
- GCPRO1 (process);
- while (new_argv[i] != 0)
- {
- int len = strlen (new_argv[i]);
- int size = encoding_buffer_size (coding, len);
- unsigned char *buf = (unsigned char *) alloca (size);
-
- encode_coding (coding, (unsigned char *)new_argv[i], buf, len, size);
- buf[coding->produced] = 0;
- /* We don't have to free new_argv[i] because it points to a
- Lisp string given as an argument to `start-process'. */
- new_argv[i++] = (char *) buf;
- }
- UNGCPRO;
- coding->mode &= ~CODING_MODE_LAST_BLOCK;
- }
-
/* Delay interrupts until we have a chance to store
the new fork's pid in its process structure */
#ifdef POSIX_SIGNALS
@@ -2114,11 +2096,15 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
= (struct coding_system *) xmalloc (sizeof (struct coding_system));
setup_coding_system (XPROCESS (proc)->decode_coding_system,
proc_decode_coding_system[inch]);
+ proc_decode_coding_system[inch]->src_multibyte = 1;
+ proc_decode_coding_system[inch]->dst_multibyte = 0;
if (!proc_encode_coding_system[outch])
proc_encode_coding_system[outch]
= (struct coding_system *) xmalloc (sizeof (struct coding_system));
setup_coding_system (XPROCESS (proc)->encode_coding_system,
proc_encode_coding_system[outch]);
+ proc_encode_coding_system[inch]->src_multibyte = 0;
+ proc_encode_coding_system[inch]->dst_multibyte = 1;
XPROCESS (proc)->decoding_buf = make_uninit_string (0);
XPROCESS (proc)->decoding_carryover = make_number (0);
@@ -2858,6 +2844,7 @@ read_process_output (proc, channel)
int chars_in_decoding_buf = 0; /* If 1, `chars' points
XSTRING (p->decoding_buf)->data. */
int carryover = XINT (p->decoding_carryover);
+ int require_decoding;
#ifdef VMS
VMS_PROC_STUFF *vs, *get_vms_process_pointer();
@@ -2930,17 +2917,36 @@ read_process_output (proc, channel)
/* Now set NBYTES how many bytes we must decode. */
nbytes += carryover;
- nchars = nbytes;
- if (CODING_MAY_REQUIRE_DECODING (coding))
+ require_decoding = 1;
+ coding->src_multibyte = 0;
+ /* Decide the multibyteness of the decoded text. */
+ if (!NILP (p->filter))
+ /* We make a string given to the process filter. The
+ multibyteness is decided by which coding system we use for
+ decoding. */
+ coding->dst_multibyte = (coding->type != coding_type_no_conversion
+ && coding->type != coding_type_raw_text);
+ else if (!NILP (p->buffer) && !NILP (XBUFFER (p->buffer)->name))
+ /* The decoded text is inserted in a buffer. The multibyteness is
+ decided by that of the buffer. */
+ coding->dst_multibyte
+ = !NILP (XBUFFER (p->buffer)->enable_multibyte_characters);
+ else
+ /* We can discard the source, thus no need of decoding. */
+ require_decoding = 0;
+
+ if (require_decoding
+ || CODING_MAY_REQUIRE_DECODING (coding))
{
int require = decoding_buffer_size (coding, nbytes);
+ int dst_bytes = STRING_BYTES (XSTRING (p->decoding_buf));
int result;
- if (STRING_BYTES (XSTRING (p->decoding_buf)) < require)
- p->decoding_buf = make_uninit_string (require);
+ if (dst_bytes < require)
+ p->decoding_buf = make_uninit_string (require), dst_bytes = require;
result = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data,
- nbytes, STRING_BYTES (XSTRING (p->decoding_buf)));
+ nbytes, dst_bytes);
carryover = nbytes - coding->consumed;
if (carryover > 0)
{
@@ -2951,12 +2957,10 @@ read_process_output (proc, channel)
space for the carryover (which is by definition a sequence
of bytes that was not long enough to be decoded, and thus
has a bounded length). */
- if (STRING_BYTES (XSTRING (p->decoding_buf))
- < coding->produced + carryover)
+ if (dst_bytes < coding->produced + carryover)
abort ();
bcopy (chars + coding->consumed,
- XSTRING (p->decoding_buf)->data
- + STRING_BYTES (XSTRING (p->decoding_buf)) - carryover,
+ XSTRING (p->decoding_buf)->data + dst_bytes - carryover,
carryover);
XSETINT (p->decoding_carryover, carryover);
}
@@ -2989,15 +2993,13 @@ read_process_output (proc, channel)
#ifdef VMS
/* Now we don't need the contents of `chars'. */
if (chars_allocated)
- free (chars);
+ xfree (chars);
#endif
if (coding->produced == 0)
return 0;
chars = (char *) XSTRING (p->decoding_buf)->data;
nbytes = coding->produced;
- nchars = (coding->fake_multibyte
- ? multibyte_chars_in_text (chars, nbytes)
- : coding->produced_char);
+ nchars = coding->produced_char;
chars_in_decoding_buf = 1;
}
else
@@ -3012,11 +3014,10 @@ read_process_output (proc, channel)
p->decoding_buf = make_uninit_string (nbytes);
bcopy (chars, XSTRING (p->decoding_buf)->data, nbytes);
free (chars);
- chars = XSTRING (p->decoding_buf)->data;
chars_in_decoding_buf = 1;
}
#endif
- nchars = multibyte_chars_in_text (chars, nbytes);
+ nchars = nbytes;
}
Vlast_coding_system_used = coding->symbol;
@@ -3076,11 +3077,10 @@ read_process_output (proc, channel)
/* The multibyteness of a string given to the filter is decided
by which coding system we used for decoding. */
- if (coding->type == coding_type_no_conversion
- || coding->type == coding_type_raw_text)
- text = make_unibyte_string (chars, nbytes);
- else
+ if (coding->dst_multibyte)
text = make_multibyte_string (chars, nchars, nbytes);
+ else
+ text = make_unibyte_string (chars, nbytes);
internal_condition_case_1 (read_process_output_call,
Fcons (outstream,
@@ -3158,27 +3158,20 @@ read_process_output (proc, channel)
if (! (BEGV <= PT && PT <= ZV))
Fwiden ();
- if (NILP (current_buffer->enable_multibyte_characters))
- nchars = nbytes;
+ /* If the text to insert is in decoding buffer (Lisp String), we
+ must move it to a relocation-free memory space. */
+ if (chars_in_decoding_buf)
+ {
+ chars = (char *) alloca (nbytes);
+ bcopy (XSTRING (p->decoding_buf)->data, chars, nbytes);
+ }
/* Insert before markers in case we are inserting where
the buffer's mark is, and the user's next command is Meta-y. */
- if (chars_in_decoding_buf)
- {
- /* Since multibyteness of p->docoding_buf is corrupted, we
- can't use insert_from_string_before_markers. */
- char *temp_buf;
+ insert_1_both (chars, nchars, nbytes, 0, 1, 1);
+ signal_after_change (before, 0, PT - before);
+ update_compositions (before, PT, CHECK_BORDER);
- temp_buf = (char *) alloca (nbytes);
- bcopy (XSTRING (p->decoding_buf)->data, temp_buf, nbytes);
- insert_before_markers (temp_buf, nbytes);
- }
- else
- {
- insert_1_both (chars, nchars, nbytes, 0, 1, 1);
- signal_after_change (before, 0, PT - before);
- update_compositions (before, PT, CHECK_BORDER);
- }
set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
update_mode_lines++;
@@ -3265,6 +3258,7 @@ send_process (proc, buf, len, object)
struct coding_system *coding;
struct gcpro gcpro1;
int carryover = XINT (XPROCESS (proc)->encoding_carryover);
+ int require_encoding;
GCPRO1 (object);
@@ -3285,7 +3279,18 @@ send_process (proc, buf, len, object)
coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
Vlast_coding_system_used = coding->symbol;
- if (CODING_REQUIRE_ENCODING (coding))
+ require_encoding = 0;
+ if (STRINGP (object) && STRING_MULTIBYTE (object))
+ coding->src_multibyte = require_encoding = 1;
+ else if (BUFFERP (object)
+ && !NILP (XBUFFER (object)->enable_multibyte_characters))
+ coding->src_multibyte = require_encoding = 1;
+ else
+ require_encoding = 0;
+ coding->dst_multibyte = 0;
+
+ if (require_encoding
+ || CODING_REQUIRE_ENCODING (coding))
{
int require = encoding_buffer_size (coding, len);
int offset;