diff options
| author | Richard M. Stallman | 1992-08-04 21:22:43 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1992-08-04 21:22:43 +0000 |
| commit | 044512ed541a3dead8fcc29f4d5e56a00926895e (patch) | |
| tree | 6bddfd1e1b367735818054fe4c31dc4e9d9ae2b4 /src/callproc.c | |
| parent | cefabdab1ccc77ed0ee43474f947d3e5177404b6 (diff) | |
| download | emacs-044512ed541a3dead8fcc29f4d5e56a00926895e.tar.gz emacs-044512ed541a3dead8fcc29f4d5e56a00926895e.zip | |
entered into RCS
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 277 |
1 files changed, 96 insertions, 181 deletions
diff --git a/src/callproc.c b/src/callproc.c index 253d6877851..7d8185c5a4b 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Synchronous subprocess invocation for GNU Emacs. | 1 | /* Synchronous subprocess invocation for GNU Emacs. |
| 2 | Copyright (C) 1985, 1986, 1987, 1988, 1992 Free Software Foundation, Inc. | 2 | Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -19,7 +19,6 @@ 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> | ||
| 23 | 22 | ||
| 24 | #include "config.h" | 23 | #include "config.h" |
| 25 | 24 | ||
| @@ -58,11 +57,16 @@ extern char **environ; | |||
| 58 | 57 | ||
| 59 | #define max(a, b) ((a) > (b) ? (a) : (b)) | 58 | #define max(a, b) ((a) > (b) ? (a) : (b)) |
| 60 | 59 | ||
| 61 | Lisp_Object Vexec_path, Vexec_directory, Vdata_directory; | 60 | Lisp_Object Vexec_path, Vexec_directory; |
| 62 | 61 | ||
| 63 | Lisp_Object Vshell_file_name; | 62 | Lisp_Object Vshell_file_name; |
| 64 | 63 | ||
| 64 | #ifndef MAINTAIN_ENVIRONMENT | ||
| 65 | /* List of strings to append to front of environment of | ||
| 66 | all subprocesses when they are started. */ | ||
| 67 | |||
| 65 | Lisp_Object Vprocess_environment; | 68 | Lisp_Object Vprocess_environment; |
| 69 | #endif | ||
| 66 | 70 | ||
| 67 | /* True iff we are about to fork off a synchronous process or if we | 71 | /* True iff we are about to fork off a synchronous process or if we |
| 68 | are waiting for it. */ | 72 | are waiting for it. */ |
| @@ -99,13 +103,13 @@ Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\ | |||
| 99 | Remaining arguments are strings passed as command arguments to PROGRAM.\n\ | 103 | Remaining arguments are strings passed as command arguments to PROGRAM.\n\ |
| 100 | If BUFFER is nil or 0, returns immediately with value nil.\n\ | 104 | If BUFFER is nil or 0, returns immediately with value nil.\n\ |
| 101 | Otherwise waits for PROGRAM to terminate\n\ | 105 | Otherwise waits for PROGRAM to terminate\n\ |
| 102 | and returns a numeric exit status or a signal description string.\n\ | 106 | and returns a numeric exit status or a signal name as a string.\n\ |
| 103 | If you quit, the process is killed with SIGKILL.") | 107 | If you quit, the process is killed with SIGKILL.") |
| 104 | (nargs, args) | 108 | (nargs, args) |
| 105 | int nargs; | 109 | int nargs; |
| 106 | register Lisp_Object *args; | 110 | register Lisp_Object *args; |
| 107 | { | 111 | { |
| 108 | Lisp_Object display, infile, buffer, path, current_dir; | 112 | Lisp_Object display, buffer, path; |
| 109 | int fd[2]; | 113 | int fd[2]; |
| 110 | int filefd; | 114 | int filefd; |
| 111 | register int pid; | 115 | register int pid; |
| @@ -117,37 +121,34 @@ If you quit, the process is killed with SIGKILL.") | |||
| 117 | #if 0 | 121 | #if 0 |
| 118 | int mask; | 122 | int mask; |
| 119 | #endif | 123 | #endif |
| 124 | struct gcpro gcpro1; | ||
| 125 | |||
| 126 | GCPRO1 (*args); | ||
| 127 | gcpro1.nvars = nargs; | ||
| 128 | |||
| 120 | CHECK_STRING (args[0], 0); | 129 | CHECK_STRING (args[0], 0); |
| 121 | 130 | ||
| 122 | if (nargs >= 2 && ! NILP (args[1])) | 131 | if (nargs <= 1 || NULL (args[1])) |
| 123 | { | 132 | args[1] = build_string ("/dev/null"); |
| 124 | infile = Fexpand_file_name (args[1], current_buffer->directory); | ||
| 125 | CHECK_STRING (infile, 1); | ||
| 126 | } | ||
| 127 | else | 133 | else |
| 128 | #ifdef VMS | 134 | args[1] = Fexpand_file_name (args[1], current_buffer->directory); |
| 129 | infile = build_string ("NLA0:"); | ||
| 130 | #else | ||
| 131 | infile = build_string ("/dev/null"); | ||
| 132 | #endif /* not VMS */ | ||
| 133 | 135 | ||
| 134 | if (nargs >= 3) | 136 | CHECK_STRING (args[1], 1); |
| 135 | { | 137 | |
| 136 | register Lisp_Object tem; | 138 | { |
| 137 | 139 | register Lisp_Object tem; | |
| 138 | buffer = tem = args[2]; | 140 | buffer = tem = args[2]; |
| 139 | if (!(EQ (tem, Qnil) | 141 | if (nargs <= 2) |
| 140 | || EQ (tem, Qt) | 142 | buffer = Qnil; |
| 141 | || XFASTINT (tem) == 0)) | 143 | else if (!(EQ (tem, Qnil) || EQ (tem, Qt) |
| 142 | { | 144 | || XFASTINT (tem) == 0)) |
| 143 | buffer = Fget_buffer (tem); | 145 | { |
| 144 | CHECK_BUFFER (buffer, 2); | 146 | buffer = Fget_buffer (tem); |
| 145 | } | 147 | CHECK_BUFFER (buffer, 2); |
| 146 | } | 148 | } |
| 147 | else | 149 | } |
| 148 | buffer = Qnil; | ||
| 149 | 150 | ||
| 150 | display = nargs >= 4 ? args[3] : Qnil; | 151 | display = nargs >= 3 ? args[3] : Qnil; |
| 151 | 152 | ||
| 152 | { | 153 | { |
| 153 | register int i; | 154 | register int i; |
| @@ -161,14 +162,14 @@ If you quit, the process is killed with SIGKILL.") | |||
| 161 | new_argv[i - 3] = 0; | 162 | new_argv[i - 3] = 0; |
| 162 | } | 163 | } |
| 163 | 164 | ||
| 164 | filefd = open (XSTRING (infile)->data, O_RDONLY, 0); | 165 | filefd = open (XSTRING (args[1])->data, O_RDONLY, 0); |
| 165 | if (filefd < 0) | 166 | if (filefd < 0) |
| 166 | { | 167 | { |
| 167 | report_file_error ("Opening process input file", Fcons (infile, Qnil)); | 168 | report_file_error ("Opening process input file", Fcons (args[1], Qnil)); |
| 168 | } | 169 | } |
| 169 | /* Search for program; barf if not found. */ | 170 | /* Search for program; barf if not found. */ |
| 170 | openp (Vexec_path, args[0], "", &path, 1); | 171 | openp (Vexec_path, args[0], "", &path, 1); |
| 171 | if (NILP (path)) | 172 | if (NULL (path)) |
| 172 | { | 173 | { |
| 173 | close (filefd); | 174 | close (filefd); |
| 174 | report_file_error ("Searching for program", Fcons (args[0], Qnil)); | 175 | report_file_error ("Searching for program", Fcons (args[0], Qnil)); |
| @@ -186,19 +187,19 @@ If you quit, the process is killed with SIGKILL.") | |||
| 186 | #endif | 187 | #endif |
| 187 | } | 188 | } |
| 188 | 189 | ||
| 189 | /* Make sure that the child will be able to chdir to the current | ||
| 190 | buffer's current directory. We can't just have the child check | ||
| 191 | for an error when it does the chdir, since it's in a vfork. */ | ||
| 192 | current_dir = expand_and_dir_to_file (current_buffer->directory, Qnil); | ||
| 193 | if (NILP (Ffile_accessible_directory_p (current_dir))) | ||
| 194 | report_file_error ("Setting current directory", | ||
| 195 | Fcons (current_buffer->directory, Qnil)); | ||
| 196 | |||
| 197 | { | 190 | { |
| 198 | /* child_setup must clobber environ in systems with true vfork. | 191 | /* child_setup must clobber environ in systems with true vfork. |
| 199 | Protect it from permanent change. */ | 192 | Protect it from permanent change. */ |
| 200 | register char **save_environ = environ; | 193 | register char **save_environ = environ; |
| 201 | register int fd1 = fd[1]; | 194 | register int fd1 = fd[1]; |
| 195 | char **env; | ||
| 196 | |||
| 197 | #ifdef MAINTAIN_ENVIRONMENT | ||
| 198 | env = (char **) alloca (size_of_current_environ ()); | ||
| 199 | get_current_environ (env); | ||
| 200 | #else | ||
| 201 | env = environ; | ||
| 202 | #endif /* MAINTAIN_ENVIRONMENT */ | ||
| 202 | 203 | ||
| 203 | #if 0 /* Some systems don't have sigblock. */ | 204 | #if 0 /* Some systems don't have sigblock. */ |
| 204 | mask = sigblock (sigmask (SIGCHLD)); | 205 | mask = sigblock (sigmask (SIGCHLD)); |
| @@ -218,7 +219,7 @@ If you quit, the process is killed with SIGKILL.") | |||
| 218 | #else | 219 | #else |
| 219 | setpgrp (pid, pid); | 220 | setpgrp (pid, pid); |
| 220 | #endif /* USG */ | 221 | #endif /* USG */ |
| 221 | child_setup (filefd, fd1, fd1, new_argv, 0, current_dir); | 222 | child_setup (filefd, fd1, fd1, new_argv, env, 0); |
| 222 | } | 223 | } |
| 223 | 224 | ||
| 224 | #if 0 | 225 | #if 0 |
| @@ -243,17 +244,13 @@ If you quit, the process is killed with SIGKILL.") | |||
| 243 | if (XTYPE (buffer) == Lisp_Int) | 244 | if (XTYPE (buffer) == Lisp_Int) |
| 244 | { | 245 | { |
| 245 | #ifndef subprocesses | 246 | #ifndef subprocesses |
| 246 | /* If Emacs has been built with asynchronous subprocess support, | ||
| 247 | we don't need to do this, I think because it will then have | ||
| 248 | the facilities for handling SIGCHLD. */ | ||
| 249 | wait_without_blocking (); | 247 | wait_without_blocking (); |
| 250 | #endif /* subprocesses */ | 248 | #endif /* subprocesses */ |
| 249 | |||
| 250 | UNGCPRO; | ||
| 251 | return Qnil; | 251 | return Qnil; |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | synch_process_death = 0; | ||
| 255 | synch_process_retcode = 0; | ||
| 256 | |||
| 257 | record_unwind_protect (call_process_cleanup, | 254 | record_unwind_protect (call_process_cleanup, |
| 258 | Fcons (make_number (fd[0]), make_number (pid))); | 255 | Fcons (make_number (fd[0]), make_number (pid))); |
| 259 | 256 | ||
| @@ -270,9 +267,9 @@ If you quit, the process is killed with SIGKILL.") | |||
| 270 | while ((nread = read (fd[0], buf, sizeof buf)) > 0) | 267 | while ((nread = read (fd[0], buf, sizeof buf)) > 0) |
| 271 | { | 268 | { |
| 272 | immediate_quit = 0; | 269 | immediate_quit = 0; |
| 273 | if (!NILP (buffer)) | 270 | if (!NULL (buffer)) |
| 274 | insert (buf, nread); | 271 | insert (buf, nread); |
| 275 | if (!NILP (display) && INTERACTIVE) | 272 | if (!NULL (display) && INTERACTIVE) |
| 276 | redisplay_preserve_echo_area (); | 273 | redisplay_preserve_echo_area (); |
| 277 | immediate_quit = 1; | 274 | immediate_quit = 1; |
| 278 | QUIT; | 275 | QUIT; |
| @@ -288,6 +285,8 @@ If you quit, the process is killed with SIGKILL.") | |||
| 288 | 285 | ||
| 289 | unbind_to (count, Qnil); | 286 | unbind_to (count, Qnil); |
| 290 | 287 | ||
| 288 | UNGCPRO; | ||
| 289 | |||
| 291 | if (synch_process_death) | 290 | if (synch_process_death) |
| 292 | return build_string (synch_process_death); | 291 | return build_string (synch_process_death); |
| 293 | return make_number (synch_process_retcode); | 292 | return make_number (synch_process_retcode); |
| @@ -311,7 +310,7 @@ Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\ | |||
| 311 | Remaining args are passed to PROGRAM at startup as command args.\n\ | 310 | Remaining args are passed to PROGRAM at startup as command args.\n\ |
| 312 | If BUFFER is nil, returns immediately with value nil.\n\ | 311 | If BUFFER is nil, returns immediately with value nil.\n\ |
| 313 | Otherwise waits for PROGRAM to terminate\n\ | 312 | Otherwise waits for PROGRAM to terminate\n\ |
| 314 | and returns a numeric exit status or a signal description string.\n\ | 313 | and returns a numeric exit status or a signal name as a string.\n\ |
| 315 | If you quit, the process is killed with SIGKILL.") | 314 | If you quit, the process is killed with SIGKILL.") |
| 316 | (nargs, args) | 315 | (nargs, args) |
| 317 | int nargs; | 316 | int nargs; |
| @@ -320,6 +319,10 @@ If you quit, the process is killed with SIGKILL.") | |||
| 320 | register Lisp_Object filename_string, start, end; | 319 | register Lisp_Object filename_string, start, end; |
| 321 | char tempfile[20]; | 320 | char tempfile[20]; |
| 322 | int count = specpdl_ptr - specpdl; | 321 | int count = specpdl_ptr - specpdl; |
| 322 | struct gcpro gcpro1; | ||
| 323 | |||
| 324 | GCPRO1 (*args); | ||
| 325 | gcpro1.nvars = 2; | ||
| 323 | 326 | ||
| 324 | #ifdef VMS | 327 | #ifdef VMS |
| 325 | strcpy (tempfile, "tmp:emacsXXXXXX."); | 328 | strcpy (tempfile, "tmp:emacsXXXXXX."); |
| @@ -334,12 +337,13 @@ If you quit, the process is killed with SIGKILL.") | |||
| 334 | Fwrite_region (start, end, filename_string, Qnil, Qlambda); | 337 | Fwrite_region (start, end, filename_string, Qnil, Qlambda); |
| 335 | record_unwind_protect (delete_temp_file, filename_string); | 338 | record_unwind_protect (delete_temp_file, filename_string); |
| 336 | 339 | ||
| 337 | if (!NILP (args[3])) | 340 | if (!NULL (args[3])) |
| 338 | Fdelete_region (start, end); | 341 | Fdelete_region (start, end); |
| 339 | 342 | ||
| 340 | args[3] = filename_string; | 343 | args[3] = filename_string; |
| 341 | Fcall_process (nargs - 2, args + 2); | 344 | Fcall_process (nargs - 2, args + 2); |
| 342 | 345 | ||
| 346 | UNGCPRO; | ||
| 343 | return unbind_to (count, Qnil); | 347 | return unbind_to (count, Qnil); |
| 344 | } | 348 | } |
| 345 | 349 | ||
| @@ -358,21 +362,14 @@ If you quit, the process is killed with SIGKILL.") | |||
| 358 | ENV is the environment for the subprocess. | 362 | ENV is the environment for the subprocess. |
| 359 | 363 | ||
| 360 | SET_PGRP is nonzero if we should put the subprocess into a separate | 364 | SET_PGRP is nonzero if we should put the subprocess into a separate |
| 361 | process group. | 365 | process group. */ |
| 362 | |||
| 363 | CURRENT_DIR is an elisp string giving the path of the current | ||
| 364 | directory the subprocess should have. Since we can't really signal | ||
| 365 | a decent error from within the child, this should be verified as an | ||
| 366 | executable directory by the parent. */ | ||
| 367 | 366 | ||
| 368 | child_setup (in, out, err, new_argv, set_pgrp, current_dir) | 367 | child_setup (in, out, err, new_argv, env, set_pgrp) |
| 369 | int in, out, err; | 368 | int in, out, err; |
| 370 | register char **new_argv; | 369 | register char **new_argv; |
| 370 | char **env; | ||
| 371 | int set_pgrp; | 371 | int set_pgrp; |
| 372 | Lisp_Object current_dir; | ||
| 373 | { | 372 | { |
| 374 | char **env; | ||
| 375 | |||
| 376 | register int pid = getpid(); | 373 | register int pid = getpid(); |
| 377 | 374 | ||
| 378 | setpriority (PRIO_PROCESS, pid, 0); | 375 | setpriority (PRIO_PROCESS, pid, 0); |
| @@ -387,25 +384,24 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 387 | If using vfork and C_ALLOCA it is safe because that changes | 384 | If using vfork and C_ALLOCA it is safe because that changes |
| 388 | the superior's static variables as if the superior had done alloca | 385 | the superior's static variables as if the superior had done alloca |
| 389 | and will be cleaned up in the usual way. */ | 386 | and will be cleaned up in the usual way. */ |
| 390 | { | ||
| 391 | register unsigned char *temp; | ||
| 392 | register int i; | ||
| 393 | 387 | ||
| 394 | i = XSTRING (current_dir)->size; | 388 | if (XTYPE (current_buffer->directory) == Lisp_String) |
| 395 | temp = (unsigned char *) alloca (i + 2); | 389 | { |
| 396 | bcopy (XSTRING (current_dir)->data, temp, i); | 390 | register unsigned char *temp; |
| 397 | if (temp[i - 1] != '/') temp[i++] = '/'; | 391 | register int i; |
| 398 | temp[i] = 0; | 392 | |
| 399 | 393 | i = XSTRING (current_buffer->directory)->size; | |
| 400 | /* We can't signal an Elisp error here; we're in a vfork. Since | 394 | temp = (unsigned char *) alloca (i + 2); |
| 401 | the callers check the current directory before forking, this | 395 | bcopy (XSTRING (current_buffer->directory)->data, temp, i); |
| 402 | should only return an error if the directory's permissions | 396 | if (temp[i - 1] != '/') temp[i++] = '/'; |
| 403 | are changed between the check and this chdir, but we should | 397 | temp[i] = 0; |
| 404 | at least check. */ | 398 | /* Switch to that directory, and report any error. */ |
| 405 | if (chdir (temp) < 0) | 399 | if (chdir (temp) < 0) |
| 406 | exit (errno); | 400 | report_file_error ("In chdir", |
| 407 | } | 401 | Fcons (current_buffer->directory, Qnil)); |
| 402 | } | ||
| 408 | 403 | ||
| 404 | #ifndef MAINTAIN_ENVIRONMENT | ||
| 409 | /* Set `env' to a vector of the strings in Vprocess_environment. */ | 405 | /* Set `env' to a vector of the strings in Vprocess_environment. */ |
| 410 | { | 406 | { |
| 411 | register Lisp_Object tem; | 407 | register Lisp_Object tem; |
| @@ -422,7 +418,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 422 | /* new_length + 1 to include terminating 0 */ | 418 | /* new_length + 1 to include terminating 0 */ |
| 423 | env = new_env = (char **) alloca ((new_length + 1) * sizeof (char *)); | 419 | env = new_env = (char **) alloca ((new_length + 1) * sizeof (char *)); |
| 424 | 420 | ||
| 425 | /* Copy the Vprocess_alist strings into new_env. */ | 421 | /* Copy the env strings into new_env. */ |
| 426 | for (tem = Vprocess_environment; | 422 | for (tem = Vprocess_environment; |
| 427 | (XTYPE (tem) == Lisp_Cons | 423 | (XTYPE (tem) == Lisp_Cons |
| 428 | && XTYPE (XCONS (tem)->car) == Lisp_String); | 424 | && XTYPE (XCONS (tem)->car) == Lisp_String); |
| @@ -430,6 +426,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 430 | *new_env++ = (char *) XSTRING (XCONS (tem)->car)->data; | 426 | *new_env++ = (char *) XSTRING (XCONS (tem)->car)->data; |
| 431 | *new_env = 0; | 427 | *new_env = 0; |
| 432 | } | 428 | } |
| 429 | #endif /* Not MAINTAIN_ENVIRONMENT */ | ||
| 433 | 430 | ||
| 434 | close (0); | 431 | close (0); |
| 435 | close (1); | 432 | close (1); |
| @@ -442,11 +439,6 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 442 | close (out); | 439 | close (out); |
| 443 | close (err); | 440 | close (err); |
| 444 | 441 | ||
| 445 | #ifdef USG | ||
| 446 | setpgrp (); /* No arguments but equivalent in this case */ | ||
| 447 | #else | ||
| 448 | setpgrp (pid, pid); | ||
| 449 | #endif /* USG */ | ||
| 450 | setpgrp_of_tty (pid); | 442 | setpgrp_of_tty (pid); |
| 451 | 443 | ||
| 452 | #ifdef vipc | 444 | #ifdef vipc |
| @@ -464,111 +456,38 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 464 | _exit (1); | 456 | _exit (1); |
| 465 | } | 457 | } |
| 466 | 458 | ||
| 467 | static int | ||
| 468 | getenv_internal (var, varlen, value, valuelen) | ||
| 469 | char *var; | ||
| 470 | int varlen; | ||
| 471 | char **value; | ||
| 472 | int *valuelen; | ||
| 473 | { | ||
| 474 | Lisp_Object scan; | ||
| 475 | |||
| 476 | for (scan = Vprocess_environment; CONSP (scan); scan = XCONS (scan)->cdr) | ||
| 477 | { | ||
| 478 | Lisp_Object entry = XCONS (scan)->car; | ||
| 479 | |||
| 480 | if (XTYPE (entry) == Lisp_String | ||
| 481 | && XSTRING (entry)->size > varlen | ||
| 482 | && XSTRING (entry)->data[varlen] == '=' | ||
| 483 | && ! bcmp (XSTRING (entry)->data, var, varlen)) | ||
| 484 | { | ||
| 485 | *value = (char *) XSTRING (entry)->data + (varlen + 1); | ||
| 486 | *valuelen = XSTRING (entry)->size - (varlen + 1); | ||
| 487 | return 1; | ||
| 488 | } | ||
| 489 | } | ||
| 490 | |||
| 491 | return 0; | ||
| 492 | } | ||
| 493 | |||
| 494 | DEFUN ("getenv", Fgetenv, Sgetenv, 1, 2, 0, | ||
| 495 | "Return the value of environment variable VAR, as a string.\n\ | ||
| 496 | VAR should be a string. Value is nil if VAR is undefined in the environment.\n\ | ||
| 497 | This function consults the variable ``process-environment'' for its value.") | ||
| 498 | (var) | ||
| 499 | Lisp_Object var; | ||
| 500 | { | ||
| 501 | char *value; | ||
| 502 | int valuelen; | ||
| 503 | |||
| 504 | CHECK_STRING (var, 0); | ||
| 505 | if (getenv_internal (XSTRING (var)->data, XSTRING (var)->size, | ||
| 506 | &value, &valuelen)) | ||
| 507 | return make_string (value, valuelen); | ||
| 508 | else | ||
| 509 | return Qnil; | ||
| 510 | } | ||
| 511 | |||
| 512 | /* A version of getenv that consults process_environment, easily | ||
| 513 | callable from C. */ | ||
| 514 | char * | ||
| 515 | egetenv (var) | ||
| 516 | char *var; | ||
| 517 | { | ||
| 518 | char *value; | ||
| 519 | int valuelen; | ||
| 520 | |||
| 521 | if (getenv_internal (var, strlen (var), &value, &valuelen)) | ||
| 522 | return value; | ||
| 523 | else | ||
| 524 | return 0; | ||
| 525 | } | ||
| 526 | |||
| 527 | #endif /* not VMS */ | 459 | #endif /* not VMS */ |
| 528 | 460 | ||
| 529 | init_callproc () | 461 | init_callproc () |
| 530 | { | 462 | { |
| 531 | register char * sh; | 463 | register char * sh; |
| 532 | register char **envp; | 464 | register char **envp; |
| 533 | Lisp_Object tempdir; | 465 | Lisp_Object execdir; |
| 534 | 466 | ||
| 535 | { | 467 | /* Turn PATH_EXEC into a path. `==' is just a string which we know |
| 536 | char *data_dir = egetenv ("EMACSDATA"); | 468 | will not be the name of an environment variable. */ |
| 537 | 469 | Vexec_path = decode_env_path ("==", PATH_EXEC); | |
| 538 | Vdata_directory = | ||
| 539 | Ffile_name_as_directory | ||
| 540 | (build_string (data_dir ? data_dir : PATH_DATA)); | ||
| 541 | } | ||
| 542 | |||
| 543 | /* Check the EMACSPATH environment variable, defaulting to the | ||
| 544 | PATH_EXEC path from paths.h. */ | ||
| 545 | Vexec_path = decode_env_path ("EMACSPATH", PATH_EXEC); | ||
| 546 | Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path)); | 470 | Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path)); |
| 547 | Vexec_path = nconc2 (decode_env_path ("PATH", ""), Vexec_path); | 471 | Vexec_path = nconc2 (decode_env_path ("PATH", ""), Vexec_path); |
| 548 | 472 | ||
| 549 | tempdir = Fdirectory_file_name (Vexec_directory); | 473 | execdir = Fdirectory_file_name (Vexec_directory); |
| 550 | if (access (XSTRING (tempdir)->data, 0) < 0) | 474 | if (access (XSTRING (execdir)->data, 0) < 0) |
| 551 | { | 475 | { |
| 552 | printf ("Warning: arch-dependent data dir (%s) does not exist.\n", | 476 | printf ("Warning: executable/documentation dir (%s) does not exist.\n", |
| 553 | XSTRING (Vexec_directory)->data); | 477 | XSTRING (Vexec_directory)->data); |
| 554 | sleep (2); | 478 | sleep (2); |
| 555 | } | 479 | } |
| 556 | 480 | ||
| 557 | tempdir = Fdirectory_file_name (Vdata_directory); | ||
| 558 | if (access (XSTRING (tempdir)->data, 0) < 0) | ||
| 559 | { | ||
| 560 | printf ("Warning: arch-independent data dir (%s) does not exist.\n", | ||
| 561 | XSTRING (Vdata_directory)->data); | ||
| 562 | sleep (2); | ||
| 563 | } | ||
| 564 | |||
| 565 | #ifdef VMS | 481 | #ifdef VMS |
| 566 | Vshell_file_name = build_string ("*dcl*"); | 482 | Vshell_file_name = build_string ("*dcl*"); |
| 567 | #else | 483 | #else |
| 568 | sh = (char *) getenv ("SHELL"); | 484 | sh = (char *) egetenv ("SHELL"); |
| 569 | Vshell_file_name = build_string (sh ? sh : "/bin/sh"); | 485 | Vshell_file_name = build_string (sh ? sh : "/bin/sh"); |
| 570 | #endif | 486 | #endif |
| 571 | 487 | ||
| 488 | #ifndef MAINTAIN_ENVIRONMENT | ||
| 489 | /* The equivalent of this operation was done | ||
| 490 | in init_environ in environ.c if MAINTAIN_ENVIRONMENT */ | ||
| 572 | Vprocess_environment = Qnil; | 491 | Vprocess_environment = Qnil; |
| 573 | #ifndef CANNOT_DUMP | 492 | #ifndef CANNOT_DUMP |
| 574 | if (initialized) | 493 | if (initialized) |
| @@ -576,6 +495,7 @@ init_callproc () | |||
| 576 | for (envp = environ; *envp; envp++) | 495 | for (envp = environ; *envp; envp++) |
| 577 | Vprocess_environment = Fcons (build_string (*envp), | 496 | Vprocess_environment = Fcons (build_string (*envp), |
| 578 | Vprocess_environment); | 497 | Vprocess_environment); |
| 498 | #endif /* MAINTAIN_ENVIRONMENT */ | ||
| 579 | } | 499 | } |
| 580 | 500 | ||
| 581 | syms_of_callproc () | 501 | syms_of_callproc () |
| @@ -589,22 +509,17 @@ Initialized from the SHELL environment variable."); | |||
| 589 | Each element is a string (directory name) or nil (try default directory)."); | 509 | Each element is a string (directory name) or nil (try default directory)."); |
| 590 | 510 | ||
| 591 | DEFVAR_LISP ("exec-directory", &Vexec_directory, | 511 | DEFVAR_LISP ("exec-directory", &Vexec_directory, |
| 592 | "Directory of architecture-dependent files that come with GNU Emacs,\n\ | 512 | "Directory that holds programs that come with GNU Emacs,\n\ |
| 593 | especially executable programs intended for Emacs to invoke."); | 513 | intended for Emacs to invoke."); |
| 594 | |||
| 595 | DEFVAR_LISP ("data-directory", &Vdata_directory, | ||
| 596 | "Directory of architecture-independent files that come with GNU Emacs,\n\ | ||
| 597 | intended for Emacs to use."); | ||
| 598 | 514 | ||
| 515 | #ifndef MAINTAIN_ENVIRONMENT | ||
| 599 | DEFVAR_LISP ("process-environment", &Vprocess_environment, | 516 | DEFVAR_LISP ("process-environment", &Vprocess_environment, |
| 600 | "List of environment variables for subprocesses to inherit.\n\ | 517 | "List of strings to append to environment of subprocesses that are started.\n\ |
| 601 | Each element should be a string of the form ENVVARNAME=VALUE.\n\ | 518 | Each string should have the format ENVVARNAME=VALUE."); |
| 602 | The environment which Emacs inherits is placed in this variable\n\ | 519 | #endif |
| 603 | when Emacs starts."); | ||
| 604 | 520 | ||
| 605 | #ifndef VMS | 521 | #ifndef VMS |
| 606 | defsubr (&Scall_process); | 522 | defsubr (&Scall_process); |
| 607 | #endif | 523 | #endif |
| 608 | defsubr (&Sgetenv); | ||
| 609 | defsubr (&Scall_process_region); | 524 | defsubr (&Scall_process_region); |
| 610 | } | 525 | } |