You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include <signal.h>
int fd[2];
int filefd;
register int pid;
- char buf[1024];
+ char buf[16384];
+ char *bufptr = buf;
+ int bufsize = 16384;
int count = specpdl_ptr - specpdl;
register unsigned char **new_argv
= (unsigned char **) alloca ((max (2, nargs - 2)) * sizeof (char *));
if (CONSP (buffer))
{
if (CONSP (XCONS (buffer)->cdr))
- error_file = XCONS (XCONS (buffer)->cdr)->car;
+ error_file = Fexpand_file_name (XCONS (XCONS (buffer)->cdr)->car,
+ Qnil);
buffer = XCONS (buffer)->car;
}
}
#ifdef MSDOS /* MW, July 1993 */
- /* These vars record information from process termination.
- Clear them now before process can possibly terminate,
- to avoid timing error if process terminates soon. */
- synch_process_death = 0;
- synch_process_retcode = 0;
-
if ((outf = egetenv ("TMP")) || (outf = egetenv ("TEMP")))
strcpy (tempfile = alloca (strlen (outf) + 20), outf);
else
close (filefd);
report_file_error ("Opening process output file", Fcons (tempfile, Qnil));
}
+ fd[1] = outfilefd;
#endif
if (INTEGERP (buffer))
synch_process_death = 0;
synch_process_retcode = 0;
-#ifdef MSDOS /* MW, July 1993 */
- /* ??? Someone who knows MSDOG needs to check whether this properly
- closes all descriptors that it opens. */
- pid = run_msdos_command (new_argv, current_dir, filefd, outfilefd);
- close (outfilefd);
- fd1 = -1; /* No harm in closing that one! */
- fd[0] = open (tempfile, NILP (Vbinary_process_output) ? O_TEXT : O_BINARY);
- if (fd[0] < 0)
- {
- unlink (tempfile);
- close (filefd);
- report_file_error ("Cannot re-open temporary file", Qnil);
- }
-#else /* not MSDOS */
-
if (NILP (error_file))
fd_error = open (NULL_DEVICE, O_WRONLY);
else if (STRINGP (error_file))
close (fd1);
report_file_error ("Cannot open", error_file);
}
+#ifdef MSDOS /* MW, July 1993 */
+ /* ??? Someone who knows MSDOG needs to check whether this properly
+ closes all descriptors that it opens.
+
+ Note that run_msdos_command() actually returns the child process
+ exit status, not its PID, so we assign it to `synch_process_retcode'
+ below. */
+ pid = run_msdos_command (new_argv, current_dir,
+ filefd, outfilefd, fd_error);
+ /* Record that the synchronous process exited and note its
+ termination status. */
+ synch_process_alive = 0;
+ synch_process_retcode = pid;
+ if (synch_process_retcode < 0) /* means it couldn't be exec'ed */
+ synch_process_death = strerror(errno);
+
+ close (outfilefd);
+ if (fd_error != outfilefd)
+ close (fd_error);
+ fd1 = -1; /* No harm in closing that one! */
+ fd[0] = open (tempfile, NILP (Vbinary_process_output) ? O_TEXT : O_BINARY);
+ if (fd[0] < 0)
+ {
+ unlink (tempfile);
+ close (filefd);
+ report_file_error ("Cannot re-open temporary file", Qnil);
+ }
+#else /* not MSDOS */
#ifdef WINDOWSNT
pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir);
#else /* not WINDOWSNT */
#endif /* USG */
child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir);
}
-#endif /* not MSDOS */
#endif /* not WINDOWSNT */
+#endif /* not MSDOS */
environ = save_environ;
{
register int nread;
int first = 1;
+ int total_read = 0;
- while ((nread = read (fd[0], buf, sizeof buf)) != 0)
+ while (1)
{
- if (nread < 0)
+ /* Repeatedly read until we've filled as much as possible
+ of the buffer size we have. But don't read
+ less than 1024--save that for the next bufferful. */
+
+ nread = 0;
+ while (nread < bufsize - 1024)
{
-#if defined (__osf__) && defined (__alpha)
- continue; /* Work around bug in DEC OSF/1 V3.0. */
-#else
- break;
-#endif
+ int this_read
+ = read (fd[0], bufptr + nread, bufsize - nread);
+
+ if (this_read < 0)
+ goto give_up;
+
+ if (this_read == 0)
+ goto give_up_1;
+
+ nread += this_read;
}
+
+ give_up_1:
+
+ /* Now NREAD is the total amount of data in the buffer. */
+ if (nread == 0)
+ break;
+
immediate_quit = 0;
+ total_read += nread;
+
if (!NILP (buffer))
- insert (buf, nread);
+ insert (bufptr, nread);
+
+ /* Make the buffer bigger as we continue to read more data,
+ but not past 64k. */
+ if (bufsize < 64 * 1024 && total_read > 32 * bufsize)
+ {
+ bufsize *= 2;
+ bufptr = (char *) alloca (bufsize);
+ }
+
if (!NILP (display) && INTERACTIVE)
{
if (first)
immediate_quit = 1;
QUIT;
}
+ give_up: ;
}
/* Wait for it to terminate, unless it already has. */
*tempfile = '\0';
}
dostounix_filename (tempfile);
- if (tempfile[strlen (tempfile) - 1] != '/')
+ if (!IS_DIRECTORY_SEP (tempfile[strlen (tempfile) - 1]))
strcat (tempfile, "/");
+#ifdef WINDOWSNT
+ strcat (tempfile, "emXXXXXX");
+#else
strcat (tempfile, "detmp.XXX");
+#endif
#else /* not DOS_NT */
#ifdef VMS
end = args[1];
#ifdef DOS_NT
specbind (Qbuffer_file_type, Vbinary_process_input);
- Fwrite_region (start, end, filename_string, Qnil, Qlambda);
+ Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil);
unbind_to (count, Qnil);
#else /* not DOS_NT */
- Fwrite_region (start, end, filename_string, Qnil, Qlambda);
+ Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil);
#endif /* not DOS_NT */
record_unwind_protect (delete_temp_file, filename_string);
descriptors zero, one, or two; this could happen if Emacs is
started with its standard in, out, or error closed, as might
happen under X. */
- in = relocate_fd (in, 3);
- if (out == err)
- err = out = relocate_fd (out, 3);
- else
- {
+ {
+ int oin = in, oout = out;
+
+ /* We have to avoid relocating the same descriptor twice! */
+
+ in = relocate_fd (in, 3);
+
+ if (out == oin)
+ out = in;
+ else
out = relocate_fd (out, 3);
+
+ if (err == oin)
+ err = in;
+ else if (err == oout)
+ err = out;
+ else
err = relocate_fd (err, 3);
- }
+ }
close (0);
close (1);
environ = env;
execvp (new_argv[0], new_argv);
- write (1, "Couldn't exec the program ", 26);
+ write (1, "Can't exec program: ", 26);
write (1, new_argv[0], strlen (new_argv[0]));
+ write (1, "\n", 1);
_exit (1);
#endif /* not WINDOWSNT */
#endif /* not MSDOS */
Vexec_path = nconc2 (decode_env_path ("PATH", ""), Vexec_path);
}
-/* This is run after init_cmdargs, so that Vinvocation_directory is valid. */
+/* This is run after init_cmdargs, when Vinstallation_directory is valid. */
init_callproc ()
{
Vexec_path = nconc2 (Vexec_path, Fcons (tem, Qnil));
Vexec_directory = Ffile_name_as_directory (tem);
#endif /* not DOS_NT */
+ }
- /* If we use ../lib-src, maybe use ../etc as well.
- Do so if ../etc exists and has our DOC-... file in it. */
- if (data_dir == 0)
- {
- tem = Fexpand_file_name (build_string ("etc"),
- Vinstallation_directory);
- Vdoc_directory = Ffile_name_as_directory (tem);
- }
+ /* Maybe use ../etc as well as ../lib-src. */
+ if (data_dir == 0)
+ {
+ tem = Fexpand_file_name (build_string ("etc"),
+ Vinstallation_directory);
+ Vdoc_directory = Ffile_name_as_directory (tem);
}
}
/* Look for the files that should be in etc. We don't use
Vinstallation_directory, because these files are never installed
- in /bin near the executable, and they are never in the build
+ near the executable, and they are never in the build
directory when that's different from the source directory.
Instead, if these files are not in the nominal place, we try the