Commit a4a37e65 authored by Kenichi Handa's avatar Kenichi Handa
Browse files

(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.
parent eba90784
...@@ -1082,63 +1082,6 @@ Remaining arguments are strings to give program as arguments.") ...@@ -1082,63 +1082,6 @@ Remaining arguments are strings to give program as arguments.")
CHECK_STRING (program, 2); 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); proc = make_process (name);
/* If an error occurs and we can't start the process, we want to /* 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 remove it from the process list. This means that each error
...@@ -1167,7 +1110,7 @@ Remaining arguments are strings to give program as arguments.") ...@@ -1167,7 +1110,7 @@ Remaining arguments are strings to give program as arguments.")
/* Qt denotes we have not yet called Ffind_operation_coding_system. */ /* Qt denotes we have not yet called Ffind_operation_coding_system. */
Lisp_Object coding_systems = Qt; Lisp_Object coding_systems = Qt;
Lisp_Object val, *args2; Lisp_Object val, *args2;
struct gcpro gcpro1; struct gcpro gcpro1, gcpro2;
val = Vcoding_system_for_read; val = Vcoding_system_for_read;
if (NILP (val)) if (NILP (val))
...@@ -1175,7 +1118,7 @@ Remaining arguments are strings to give program as arguments.") ...@@ -1175,7 +1118,7 @@ Remaining arguments are strings to give program as arguments.")
args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2);
args2[0] = Qstart_process; args2[0] = Qstart_process;
for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 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); coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
UNGCPRO; UNGCPRO;
if (CONSP (coding_systems)) if (CONSP (coding_systems))
...@@ -1193,7 +1136,7 @@ Remaining arguments are strings to give program as arguments.") ...@@ -1193,7 +1136,7 @@ Remaining arguments are strings to give program as arguments.")
args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof args2); args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof args2);
args2[0] = Qstart_process; args2[0] = Qstart_process;
for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 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); coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
UNGCPRO; UNGCPRO;
} }
...@@ -1205,6 +1148,73 @@ Remaining arguments are strings to give program as arguments.") ...@@ -1205,6 +1148,73 @@ Remaining arguments are strings to give program as arguments.")
XPROCESS (proc)->encode_coding_system = val; 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_buf = make_uninit_string (0);
XPROCESS (proc)->decoding_carryover = make_number (0); XPROCESS (proc)->decoding_carryover = make_number (0);
XPROCESS (proc)->encoding_buf = make_uninit_string (0); XPROCESS (proc)->encoding_buf = make_uninit_string (0);
...@@ -1408,34 +1418,6 @@ create_process (process, new_argv, current_dir) ...@@ -1408,34 +1418,6 @@ create_process (process, new_argv, current_dir)
setup_raw_text_coding_system (proc_encode_coding_system[outchannel]); 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 /* Delay interrupts until we have a chance to store
the new fork's pid in its process structure */ the new fork's pid in its process structure */
#ifdef POSIX_SIGNALS #ifdef POSIX_SIGNALS
...@@ -2114,11 +2096,15 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ ...@@ -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)); = (struct coding_system *) xmalloc (sizeof (struct coding_system));
setup_coding_system (XPROCESS (proc)->decode_coding_system, setup_coding_system (XPROCESS (proc)->decode_coding_system,
proc_decode_coding_system[inch]); 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]) if (!proc_encode_coding_system[outch])
proc_encode_coding_system[outch] proc_encode_coding_system[outch]
= (struct coding_system *) xmalloc (sizeof (struct coding_system)); = (struct coding_system *) xmalloc (sizeof (struct coding_system));
setup_coding_system (XPROCESS (proc)->encode_coding_system, setup_coding_system (XPROCESS (proc)->encode_coding_system,
proc_encode_coding_system[outch]); 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_buf = make_uninit_string (0);
XPROCESS (proc)->decoding_carryover = make_number (0); XPROCESS (proc)->decoding_carryover = make_number (0);
...@@ -2858,6 +2844,7 @@ read_process_output (proc, channel) ...@@ -2858,6 +2844,7 @@ read_process_output (proc, channel)
int chars_in_decoding_buf = 0; /* If 1, `chars' points int chars_in_decoding_buf = 0; /* If 1, `chars' points
XSTRING (p->decoding_buf)->data. */ XSTRING (p->decoding_buf)->data. */
int carryover = XINT (p->decoding_carryover); int carryover = XINT (p->decoding_carryover);
int require_decoding;
#ifdef VMS #ifdef VMS
VMS_PROC_STUFF *vs, *get_vms_process_pointer(); VMS_PROC_STUFF *vs, *get_vms_process_pointer();
...@@ -2930,17 +2917,36 @@ read_process_output (proc, channel) ...@@ -2930,17 +2917,36 @@ read_process_output (proc, channel)
/* Now set NBYTES how many bytes we must decode. */ /* Now set NBYTES how many bytes we must decode. */
nbytes += carryover; 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 require = decoding_buffer_size (coding, nbytes);
int dst_bytes = STRING_BYTES (XSTRING (p->decoding_buf));
int result; int result;
if (STRING_BYTES (XSTRING (p->decoding_buf)) < require) if (dst_bytes < require)
p->decoding_buf = make_uninit_string (require); p->decoding_buf = make_uninit_string (require), dst_bytes = require;
result = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data, result = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data,
nbytes, STRING_BYTES (XSTRING (p->decoding_buf))); nbytes, dst_bytes);
carryover = nbytes - coding->consumed; carryover = nbytes - coding->consumed;
if (carryover > 0) if (carryover > 0)
{ {
...@@ -2951,12 +2957,10 @@ read_process_output (proc, channel) ...@@ -2951,12 +2957,10 @@ read_process_output (proc, channel)
space for the carryover (which is by definition a sequence space for the carryover (which is by definition a sequence
of bytes that was not long enough to be decoded, and thus of bytes that was not long enough to be decoded, and thus
has a bounded length). */ has a bounded length). */
if (STRING_BYTES (XSTRING (p->decoding_buf)) if (dst_bytes < coding->produced + carryover)
< coding->produced + carryover)
abort (); abort ();
bcopy (chars + coding->consumed, bcopy (chars + coding->consumed,
XSTRING (p->decoding_buf)->data XSTRING (p->decoding_buf)->data + dst_bytes - carryover,
+ STRING_BYTES (XSTRING (p->decoding_buf)) - carryover,
carryover); carryover);
XSETINT (p->decoding_carryover, carryover); XSETINT (p->decoding_carryover, carryover);
} }
...@@ -2989,15 +2993,13 @@ read_process_output (proc, channel) ...@@ -2989,15 +2993,13 @@ read_process_output (proc, channel)
#ifdef VMS #ifdef VMS
/* Now we don't need the contents of `chars'. */ /* Now we don't need the contents of `chars'. */
if (chars_allocated) if (chars_allocated)
free (chars); xfree (chars);
#endif #endif
if (coding->produced == 0) if (coding->produced == 0)
return 0; return 0;
chars = (char *) XSTRING (p->decoding_buf)->data; chars = (char *) XSTRING (p->decoding_buf)->data;
nbytes = coding->produced; nbytes = coding->produced;
nchars = (coding->fake_multibyte nchars = coding->produced_char;
? multibyte_chars_in_text (chars, nbytes)
: coding->produced_char);
chars_in_decoding_buf = 1; chars_in_decoding_buf = 1;
} }
else else
...@@ -3012,11 +3014,10 @@ read_process_output (proc, channel) ...@@ -3012,11 +3014,10 @@ read_process_output (proc, channel)
p->decoding_buf = make_uninit_string (nbytes); p->decoding_buf = make_uninit_string (nbytes);
bcopy (chars, XSTRING (p->decoding_buf)->data, nbytes); bcopy (chars, XSTRING (p->decoding_buf)->data, nbytes);
free (chars); free (chars);
chars = XSTRING (p->decoding_buf)->data;
chars_in_decoding_buf = 1; chars_in_decoding_buf = 1;
} }
#endif #endif
nchars = multibyte_chars_in_text (chars, nbytes); nchars = nbytes;
} }
Vlast_coding_system_used = coding->symbol; Vlast_coding_system_used = coding->symbol;
...@@ -3076,11 +3077,10 @@ read_process_output (proc, channel) ...@@ -3076,11 +3077,10 @@ read_process_output (proc, channel)
/* The multibyteness of a string given to the filter is decided /* The multibyteness of a string given to the filter is decided
by which coding system we used for decoding. */ by which coding system we used for decoding. */
if (coding->type == coding_type_no_conversion if (coding->dst_multibyte)
|| coding->type == coding_type_raw_text)
text = make_unibyte_string (chars, nbytes);
else
text = make_multibyte_string (chars, nchars, nbytes); text = make_multibyte_string (chars, nchars, nbytes);
else
text = make_unibyte_string (chars, nbytes);
internal_condition_case_1 (read_process_output_call, internal_condition_case_1 (read_process_output_call,
Fcons (outstream, Fcons (outstream,
...@@ -3158,27 +3158,20 @@ read_process_output (proc, channel) ...@@ -3158,27 +3158,20 @@ read_process_output (proc, channel)
if (! (BEGV <= PT && PT <= ZV)) if (! (BEGV <= PT && PT <= ZV))
Fwiden (); Fwiden ();
if (NILP (current_buffer->enable_multibyte_characters)) /* If the text to insert is in decoding buffer (Lisp String), we
nchars = nbytes; 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 /* Insert before markers in case we are inserting where
the buffer's mark is, and the user's next command is Meta-y. */ the buffer's mark is, and the user's next command is Meta-y. */
if (chars_in_decoding_buf) insert_1_both (chars, nchars, nbytes, 0, 1, 1);
{ signal_after_change (before, 0, PT - before);
/* Since multibyteness of p->docoding_buf is corrupted, we update_compositions (before, PT, CHECK_BORDER);
can't use insert_from_string_before_markers. */
char *temp_buf;
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); set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
update_mode_lines++; update_mode_lines++;
...@@ -3265,6 +3258,7 @@ send_process (proc, buf, len, object) ...@@ -3265,6 +3258,7 @@ send_process (proc, buf, len, object)
struct coding_system *coding; struct coding_system *coding;
struct gcpro gcpro1; struct gcpro gcpro1;
int carryover = XINT (XPROCESS (proc)->encoding_carryover); int carryover = XINT (XPROCESS (proc)->encoding_carryover);
int require_encoding;
GCPRO1 (object); GCPRO1 (object);
...@@ -3285,7 +3279,18 @@ send_process (proc, buf, len, object) ...@@ -3285,7 +3279,18 @@ send_process (proc, buf, len, object)
coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)]; coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
Vlast_coding_system_used = coding->symbol; 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 require = encoding_buffer_size (coding, len);
int offset; int offset;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment