aboutsummaryrefslogtreecommitdiffstats
path: root/src/callproc.c
diff options
context:
space:
mode:
authorJim Blandy1992-02-06 01:02:59 +0000
committerJim Blandy1992-02-06 01:02:59 +0000
commit77d78be1714a34f0225850fadb997ca5fa80fe99 (patch)
treed6b4883d6bccb4ec2bfff3d1218b4d6b3e655c14 /src/callproc.c
parent6da5831969214acd256e624c5ad45c7400eac8a0 (diff)
downloademacs-77d78be1714a34f0225850fadb997ca5fa80fe99.tar.gz
emacs-77d78be1714a34f0225850fadb997ca5fa80fe99.zip
*** empty log message ***
Diffstat (limited to 'src/callproc.c')
-rw-r--r--src/callproc.c90
1 files changed, 56 insertions, 34 deletions
diff --git a/src/callproc.c b/src/callproc.c
index e033a8bf018..e9374aabe13 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -19,6 +19,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19 19
20 20
21#include <signal.h> 21#include <signal.h>
22#include <errno.h>
22 23
23#include "config.h" 24#include "config.h"
24 25
@@ -104,7 +105,7 @@ If you quit, the process is killed with SIGKILL.")
104 int nargs; 105 int nargs;
105 register Lisp_Object *args; 106 register Lisp_Object *args;
106{ 107{
107 Lisp_Object display, buffer, path; 108 Lisp_Object display, infile, buffer, path, current_dir;
108 int fd[2]; 109 int fd[2];
109 int filefd; 110 int filefd;
110 register int pid; 111 register int pid;
@@ -118,23 +119,27 @@ If you quit, the process is killed with SIGKILL.")
118#endif 119#endif
119 CHECK_STRING (args[0], 0); 120 CHECK_STRING (args[0], 0);
120 121
121 if (nargs <= 1 || NILP (args[1])) 122 if (nargs >= 2 && ! NILP (args[1]))
122 args[1] = build_string ("/dev/null"); 123 {
124 infile = Fexpand_file_name (args[1], current_buffer->directory);
125 CHECK_STRING (infile, 1);
126 }
123 else 127 else
124 args[1] = Fexpand_file_name (args[1], current_buffer->directory); 128 infile = build_string ("/dev/null");
125
126 CHECK_STRING (args[1], 1);
127 129
128 { 130 {
129 register Lisp_Object tem; 131 register Lisp_Object tem;
130 buffer = tem = args[2]; 132 if (nargs < 3)
131 if (nargs <= 2)
132 buffer = Qnil; 133 buffer = Qnil;
133 else if (!(EQ (tem, Qnil) || EQ (tem, Qt) 134 else
134 || XFASTINT (tem) == 0))
135 { 135 {
136 buffer = Fget_buffer (tem); 136 buffer = tem = args[2];
137 CHECK_BUFFER (buffer, 2); 137 if (!(EQ (tem, Qnil) || EQ (tem, Qt)
138 || XFASTINT (tem) == 0))
139 {
140 buffer = Fget_buffer (tem);
141 CHECK_BUFFER (buffer, 2);
142 }
138 } 143 }
139 } 144 }
140 145
@@ -152,10 +157,10 @@ If you quit, the process is killed with SIGKILL.")
152 new_argv[i - 3] = 0; 157 new_argv[i - 3] = 0;
153 } 158 }
154 159
155 filefd = open (XSTRING (args[1])->data, O_RDONLY, 0); 160 filefd = open (XSTRING (infile)->data, O_RDONLY, 0);
156 if (filefd < 0) 161 if (filefd < 0)
157 { 162 {
158 report_file_error ("Opening process input file", Fcons (args[1], Qnil)); 163 report_file_error ("Opening process input file", Fcons (infile, Qnil));
159 } 164 }
160 /* Search for program; barf if not found. */ 165 /* Search for program; barf if not found. */
161 openp (Vexec_path, args[0], "", &path, 1); 166 openp (Vexec_path, args[0], "", &path, 1);
@@ -177,6 +182,14 @@ If you quit, the process is killed with SIGKILL.")
177#endif 182#endif
178 } 183 }
179 184
185 /* Make sure that the child will be able to chdir to the current
186 buffer's current directory. We can't just have the child check
187 for an error when it does the chdir, since it's in a vfork. */
188 current_dir = expand_and_dir_to_file (current_buffer->directory, Qnil);
189 if (NILP (Ffile_accessible_directory_p (current_dir)))
190 report_file_error ("Setting current directory",
191 Fcons (current_buffer->directory, Qnil));
192
180 { 193 {
181 /* child_setup must clobber environ in systems with true vfork. 194 /* child_setup must clobber environ in systems with true vfork.
182 Protect it from permanent change. */ 195 Protect it from permanent change. */
@@ -204,7 +217,7 @@ If you quit, the process is killed with SIGKILL.")
204#else 217#else
205 setpgrp (pid, pid); 218 setpgrp (pid, pid);
206#endif /* USG */ 219#endif /* USG */
207 child_setup (filefd, fd1, fd1, new_argv, env, 0); 220 child_setup (filefd, fd1, fd1, new_argv, env, 0, current_dir);
208 } 221 }
209 222
210#if 0 223#if 0
@@ -338,13 +351,19 @@ If you quit, the process is killed with SIGKILL.")
338 ENV is the environment for the subprocess. 351 ENV is the environment for the subprocess.
339 352
340 SET_PGRP is nonzero if we should put the subprocess into a separate 353 SET_PGRP is nonzero if we should put the subprocess into a separate
341 process group. */ 354 process group.
355
356 CURRENT_DIR is an elisp string giving the path of the current
357 directory the subprocess should have. Since we can't really signal
358 a decent error from within the child, this should be verified as an
359 executable directory by the parent. */
342 360
343child_setup (in, out, err, new_argv, env, set_pgrp) 361child_setup (in, out, err, new_argv, env, set_pgrp, current_dir)
344 int in, out, err; 362 int in, out, err;
345 register char **new_argv; 363 register char **new_argv;
346 char **env; 364 char **env;
347 int set_pgrp; 365 int set_pgrp;
366 Lisp_Object current_dir;
348{ 367{
349 register int pid = getpid(); 368 register int pid = getpid();
350 369
@@ -361,21 +380,24 @@ child_setup (in, out, err, new_argv, env, set_pgrp)
361 the superior's static variables as if the superior had done alloca 380 the superior's static variables as if the superior had done alloca
362 and will be cleaned up in the usual way. */ 381 and will be cleaned up in the usual way. */
363 382
364 if (XTYPE (current_buffer->directory) == Lisp_String) 383 {
365 { 384 register unsigned char *temp;
366 register unsigned char *temp; 385 register int i;
367 register int i; 386
368 387 i = XSTRING (current_dir)->size;
369 i = XSTRING (current_buffer->directory)->size; 388 temp = (unsigned char *) alloca (i + 2);
370 temp = (unsigned char *) alloca (i + 2); 389 bcopy (XSTRING (current_dir)->data, temp, i);
371 bcopy (XSTRING (current_buffer->directory)->data, temp, i); 390 if (temp[i - 1] != '/') temp[i++] = '/';
372 if (temp[i - 1] != '/') temp[i++] = '/'; 391 temp[i] = 0;
373 temp[i] = 0; 392
374 /* Switch to that directory, and report any error. */ 393 /* We can't signal an Elisp error here; we're in a vfork. Since
375 if (chdir (temp) < 0) 394 the callers check the current directory before forking, this
376 report_file_error ("In chdir", 395 should only return an error if the directory's permissions
377 Fcons (current_buffer->directory, Qnil)); 396 are changed between the check and this chdir, but we should
378 } 397 at least check. */
398 if (chdir (temp) < 0)
399 exit (errno);
400 }
379 401
380 /* Set `env' to a vector of the strings in Vprocess_environment. */ 402 /* Set `env' to a vector of the strings in Vprocess_environment. */
381 { 403 {
@@ -435,7 +457,7 @@ getenv_internal (var, varlen, value, valuelen)
435 char *var; 457 char *var;
436 int varlen; 458 int varlen;
437 char **value; 459 char **value;
438 int **valuelen; 460 int *valuelen;
439{ 461{
440 Lisp_Object scan; 462 Lisp_Object scan;
441 463
@@ -448,7 +470,7 @@ getenv_internal (var, varlen, value, valuelen)
448 && XSTRING (entry)->data[varlen] == '=' 470 && XSTRING (entry)->data[varlen] == '='
449 && ! bcmp (XSTRING (entry)->data, var, varlen)) 471 && ! bcmp (XSTRING (entry)->data, var, varlen))
450 { 472 {
451 *value = XSTRING (entry)->data + (varlen + 1); 473 *value = (char *) XSTRING (entry)->data + (varlen + 1);
452 *valuelen = XSTRING (entry)->size - (varlen + 1); 474 *valuelen = XSTRING (entry)->size - (varlen + 1);
453 return 1; 475 return 1;
454 } 476 }