/* Synchronous subprocess invocation for GNU Emacs.
- Copyright (C) 1985, 86,87,88,93,94,95, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1985,86,87,88,93,94,95,99, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <errno.h>
#include <stdio.h>
+#ifndef USE_CRT_DLL
extern int errno;
+#endif
/* Define SIGCHLD as an alias for SIGCLD. */
#include "charset.h"
#include "ccl.h"
#include "coding.h"
+#include "composite.h"
#include <epaths.h>
#include "process.h"
#include "syssignal.h"
#ifdef VMS
extern noshare char **environ;
#else
+#ifndef USE_CRT_DLL
extern char **environ;
#endif
+#endif
#ifdef HAVE_SETPGID
+#if !defined (USG) || defined (BSD_PGRPS)
+#undef setpgrp
#define setpgrp setpgid
#endif
+#endif
#define max(a, b) ((a) > (b) ? (a) : (b))
int carryover = 0;
int display_on_the_fly = !NILP (display) && INTERACTIVE;
struct coding_system saved_coding;
+ int pt_orig = PT, pt_byte_orig = PT_BYTE;
+ int inserted;
saved_coding = process_coding;
-
+ if (process_coding.composing != COMPOSITION_DISABLED)
+ coding_allocate_composition_data (&process_coding, PT);
while (1)
{
/* Repeatedly read until we've filled as much as possible
insert_1_both (bufptr, nread, nread, 0, 1, 0);
else
{ /* We have to decode the input. */
- int size = decoding_buffer_size (&process_coding, nread);
- char *decoding_buf = (char *) xmalloc (size);
-
+ int size;
+ char *decoding_buf;
+
+ repeat_decoding:
+ size = decoding_buffer_size (&process_coding, nread);
+ decoding_buf = (char *) xmalloc (size);
+
+ if (process_coding.cmp_data)
+ process_coding.cmp_data->char_offset = PT;
+
decode_coding (&process_coding, bufptr, decoding_buf,
nread, size);
+
if (display_on_the_fly
&& saved_coding.type == coding_type_undecided
&& process_coding.type != coding_type_undecided)
carryover = nread;
continue;
}
+
if (process_coding.produced > 0)
insert_1_both (decoding_buf, process_coding.produced_char,
process_coding.produced, 0, 1, 0);
xfree (decoding_buf);
- carryover = nread - process_coding.consumed;
+
+ if (process_coding.result == CODING_FINISH_INCONSISTENT_EOL)
+ {
+ Lisp_Object eol_type, coding;
+
+ if (process_coding.eol_type == CODING_EOL_CR)
+ {
+ /* CRs have been replaced with LFs. Undo
+ that in the text inserted above. */
+ unsigned char *p;
+
+ move_gap_both (PT, PT_BYTE);
+
+ p = BYTE_POS_ADDR (pt_byte_orig);
+ for (; p < GPT_ADDR; ++p)
+ if (*p == '\n')
+ *p = '\r';
+ }
+ else if (process_coding.eol_type == CODING_EOL_CRLF)
+ {
+ /* CR LFs have been replaced with LFs. Undo
+ that by inserting CRs in front of LFs in
+ the text inserted above. */
+ EMACS_INT bytepos, old_pt, old_pt_byte, nCR;
+
+ old_pt = PT;
+ old_pt_byte = PT_BYTE;
+ nCR = 0;
+
+ for (bytepos = PT_BYTE - 1;
+ bytepos >= pt_byte_orig;
+ --bytepos)
+ if (FETCH_BYTE (bytepos) == '\n')
+ {
+ EMACS_INT charpos = BYTE_TO_CHAR (bytepos);
+ TEMP_SET_PT_BOTH (charpos, bytepos);
+ insert_1_both ("\r", 1, 1, 0, 1, 0);
+ ++nCR;
+ }
+
+ TEMP_SET_PT_BOTH (old_pt + nCR, old_pt_byte + nCR);
+ }
+
+ /* Set the coding system symbol to that for
+ Unix-like EOL. */
+ eol_type = Fget (saved_coding.symbol, Qeol_type);
+ if (VECTORP (eol_type)
+ && ASIZE (eol_type) == 3
+ && SYMBOLP (AREF (eol_type, CODING_EOL_LF)))
+ coding = AREF (eol_type, CODING_EOL_LF);
+ else
+ coding = saved_coding.symbol;
+
+ process_coding.symbol = coding;
+ process_coding.eol_type = CODING_EOL_LF;
+ process_coding.mode
+ &= ~CODING_MODE_INHIBIT_INCONSISTENT_EOL;
+ }
+
+ nread -= process_coding.consumed;
+ carryover = nread;
if (carryover > 0)
/* As CARRYOVER should not be that large, we had
better avoid overhead of bcopy. */
BCOPY_SHORT (bufptr + process_coding.consumed, bufptr,
carryover);
+ if (process_coding.result == CODING_FINISH_INSUFFICIENT_CMP)
+ {
+ /* The decoding ended because of insufficient data
+ area to record information about composition.
+ We must try decoding with additional data area
+ before reading more output for the process. */
+ coding_allocate_composition_data (&process_coding, PT);
+ goto repeat_decoding;
+ }
}
}
if (first)
prepare_menu_bars ();
first = 0;
- redisplay_preserve_echo_area ();
+ redisplay_preserve_echo_area (1);
}
immediate_quit = 1;
QUIT;
}
give_up: ;
- Vlast_coding_system_used = process_coding.symbol;
+ if (!NILP (buffer)
+ && process_coding.cmp_data)
+ {
+ coding_restore_composition (&process_coding, Fcurrent_buffer ());
+ coding_free_composition_data (&process_coding);
+ }
+
+ {
+ int post_read_count = specpdl_ptr - specpdl;
+
+ record_unwind_protect (save_excursion_restore, save_excursion_save ());
+ inserted = PT - pt_orig;
+ TEMP_SET_PT_BOTH (pt_orig, pt_byte_orig);
+ if (SYMBOLP (process_coding.post_read_conversion)
+ && !NILP (Ffboundp (process_coding.post_read_conversion)))
+ call1 (process_coding.post_read_conversion, make_number (inserted));
- /* If the caller required, let the buffer inherit the
- coding-system used to decode the process output. */
- if (inherit_process_coding_system)
- call1 (intern ("after-insert-file-set-buffer-file-coding-system"),
- make_number (total_read));
+ Vlast_coding_system_used = process_coding.symbol;
+
+ /* If the caller required, let the buffer inherit the
+ coding-system used to decode the process output. */
+ if (inherit_process_coding_system)
+ call1 (intern ("after-insert-file-set-buffer-file-coding-system"),
+ make_number (total_read));
+
+ unbind_to (post_read_count, Qnil);
+ }
}
/* Wait for it to terminate, unless it already has. */
/* Use Fdelete_file (indirectly) because that runs a file name handler.
We did that when writing the file, so we should do so when deleting. */
internal_delete_file (name);
+ return Qnil;
}
DEFUN ("call-process-region", Fcall_process_region, Scall_process_region,
coding_systems = Qt;
+#ifdef HAVE_MKSTEMP
+ {
+ int fd = mkstemp (tempfile);
+ if (fd == -1)
+ report_file_error ("Failed to open temporary file",
+ Fcons (Vtemp_file_name_pattern, Qnil));
+ else
+ close (fd);
+ }
+#else
mktemp (tempfile);
+#endif
filename_string = build_string (tempfile);
GCPRO1 (filename_string);
register int i;
i = STRING_BYTES (XSTRING (current_dir));
+#ifdef MSDOS
+ /* MSDOS must have all environment variables malloc'ed, because
+ low-level libc functions that launch subsidiary processes rely
+ on that. */
+ pwd_var = (char *) xmalloc (i + 6);
+#else
pwd_var = (char *) alloca (i + 6);
+#endif
temp = pwd_var + 4;
bcopy ("PWD=", pwd_var, 4);
bcopy (XSTRING (current_dir)->data, temp, i);
#ifdef MSDOS
pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
+ xfree (pwd_var);
if (pid == -1)
/* An error occurred while trying to run the subprocess. */
report_file_error ("Spawning child process", Qnil);