home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / gnu / emacs / sources / 562 < prev    next >
Encoding:
Text File  |  1992-07-29  |  38.4 KB  |  1,315 lines

  1. Newsgroups: gnu.emacs.sources
  2. Path: sparky!uunet!cis.ohio-state.edu!d0sb10.fnal.gov!SNYDER
  3. From: SNYDER@d0sb10.fnal.gov (scott snyder)
  4. Subject: better subprocess support for vms emacs (1/4)
  5. Message-ID: <920730000040.28a0007c@D0SB10.FNAL.GOV>
  6. Sender: daemon@cis.ohio-state.edu
  7. Organization: Source only  Discussion and requests in gnu.emacs.help.
  8. Distribution: gnu
  9. Date: Wed, 29 Jul 1992 19:00:40 GMT
  10. Lines: 1303
  11.  
  12. This is a set of patches for emacs 18.58 to get the unix subprocess
  13. functions (i.e., start-process and the stuff dealing with the Process
  14. type) working on VMS.  It also includes support for pseudoterminals
  15. and network streams (using the Multinet TCP/IP package).
  16.  
  17. This has been tested with both vax c and gcc.  It should work on both
  18. VMS 5.4 and 5.5 (but see the warning in the readme about using
  19. pseudoterminals under 5.4).  The network support requires Multinet,
  20. but it shouldn't be too hard to get it working with UCX (the call interface
  21. is supposed to be the same).
  22.  
  23. enjoy...
  24. scott snyder
  25. snyder@d0gsc.fnal.gov
  26.  
  27. $! ------------------ CUT HERE -----------------------
  28. $ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
  29. $!
  30. $! This archive created by VMS_SHARE Version 7.2-010  25-Jun-1992
  31. $!   On 29-JUL-1992 22:21:58.40   By user SNYDER 
  32. $!
  33. $! This VMS_SHARE Written by:
  34. $!    Andy Harper, Kings College London UK
  35. $!
  36. $! Acknowledgements to:
  37. $!    James Gray       - Original VMS_SHARE
  38. $!    Michael Bednarek - Original Concept and implementation
  39. $!
  40. $!+ THIS PACKAGE DISTRIBUTED IN 4 PARTS, TO KEEP EACH PART
  41. $!  BELOW 80 BLOCKS
  42. $!
  43. $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
  44. $! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
  45. $!
  46. $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
  47. $!       1. VMS-CHANGES-README.;8
  48. $!       2. SRC.DIFFS;2
  49. $!       3. LISP.DIFFS;8
  50. $!       4. S-VMS5-4.H;1
  51. $!       5. DIRED.EL;10
  52. $!       6. CALC.DIFFS;2
  53. $!       7. GNUS.DIFFS;3
  54. $!
  55. $set="set"
  56. $set symbol/scope=(nolocal,noglobal)
  57. $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
  58. $e="write sys$error  ""%UNPACK"", "
  59. $w="write sys$output ""%UNPACK"", "
  60. $ if f$trnlnm("SHARE_LOG") then $ w = "!"
  61. $ ve=f$getsyi("version")
  62. $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
  63. $ e "-E-OLDVER, Must run at least VMS 4.4"
  64. $ v=f$verify(v)
  65. $ exit 44
  66. $UNPACK: SUBROUTINE ! P1=filename, P2=checksum
  67. $ x = P1 - f$parse(P1,,,"version")
  68. $ y = f$search(x)
  69. $ if y .eqs. "" then $ goto file_absent
  70. $ x = f$integer(f$parse(P1,,,"version")-";")
  71. $ y = f$integer(f$parse(y,,,"version")-";")
  72. $ if x .gt. y then $ goto file_absent
  73. $ if f$mode() .eqs. "INTERACTIVE" then $ goto file_interactive
  74. $ if x .eq. y then e "-W-EXISTS, File ''P1' exists. Skipped."
  75. $ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists. Skipped."
  76. $file_delete:
  77. $ delete 'f'*
  78. $ exit
  79. $file_interactive:
  80. $ if x .eq. y then e "-W-EXISTS, File ''P1' exists."
  81. $ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists."
  82. $ read/error=file_delete/end=file_delete-
  83.   /prompt="Create new version [y/n]: " -
  84.   sys$command x
  85. $ if .not. x then $ e "-W-SKIPPED, File ''P1' skipped."
  86. $ if .not. x then $ goto file_delete
  87. $ P1 = P1 - f$parse(P1,,,"version")
  88. $file_absent:
  89. $ if f$parse(P1) .nes. "" then $ goto dirok
  90. $ dn=f$parse(P1,,,"DIRECTORY")
  91. $ w "-I-CREDIR, Creating directory ''dn'."
  92. $ create/dir 'dn'
  93. $ if $status then $ goto dirok
  94. $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
  95. $ delete 'f'*
  96. $ exit
  97. $dirok:
  98. $ w "-I-PROCESS, Processing file ''P1'."
  99. $ if .not. f$verify() then $ define/user sys$output nl:
  100. $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
  101. PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
  102. SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
  103. CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
  104. LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
  105. BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
  106. IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
  107. MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
  108. ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
  109. 1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
  110. POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
  111. ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
  112. COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
  113. "output_file"));ENDPROCEDURE;Unpacker;QUIT;
  114. $ delete/nolog 'f'*
  115. $ CHECKSUM 'P1'
  116. $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
  117. $ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
  118. $ ENDSUBROUTINE
  119. $START:
  120. $ create 'f'
  121. X
  122. XThis kit contains patched to add unix-style subprocesses,
  123. Xpseudo-terminals, and network streams to VMS emacs.  This file
  124. Xcontains a description of how to install it and a brief description of
  125. Xthe changes.
  126. X
  127. X
  128. X                          Installation.
  129. X
  130. X
  131. XI will assume that you are starting with a virgin 18.58 distribution.
  132. XYou should probably also review the contents of VMSBUILD.
  133. X
  134. X1. Unpack this shar file (if you haven't done so already) in some
  135. Xconvenient directory.  Apply the patches in src.diffs to the src
  136. Xdirectory.  Apply the patches in lisp.diffs to the lisp directory.
  137. XCopy the file s-vms5-4.h into the src directory, and copy the file
  138. Xdired.el into the lisp directory.
  139. X
  140. X2. If you presently have a working version of emacs, you'll probably
  141. Xwant to byte-compile the lisp files changed by the last step.  They
  142. Xare:
  143. X
  144. X  compile, dired, lpr, shell, telnet, vms-patch
  145. X
  146. XIf you don't happen to have a working emacs, you can just delete the
  147. Xexisting .elc files which correspond to these sources.  You can then
  148. Xgo back later, byte-compile the files, and rebuild emacs.
  149. X
  150. X3. Set up emacs.com, config.h, and paths.h as described in VMSBUILD.
  151. XIf you want pseudoterminals, include s-vms5-4.h instead of s-vms4-4.h.
  152. X
  153. XWARNING: VMS 5.4-2 had a bug in the swapper which could cause the
  154. Xsystem to crash if a process with a pseudoterminal got swapped out.
  155. XThis bug appears to be fixed in VMS 5.5.  I don't have any information
  156. Xon other versions.  I have a workaround for the problem in 5.4 which
  157. Xconsists of a patch to the ptd$services image.  Contact me if you're
  158. Xinterested...
  159. X
  160. X4. The network support in this version will only work with Multinet.
  161. XIf you are not running Multinet, disable it by commenting out the line
  162. X
  163. X#define HAVE_SOCKETS
  164. X
  165. Xfrom s-vms.h and by commenting out the line
  166. X
  167. Xmultinet:multinet_socket_library/share
  168. X
  169. Xfrom temacs.opt.
  170. X
  171. X5. Execute compile.com and link.com to build temacs.exe.
  172. X
  173. X6. Build the stuff in `5B-.etc`5D as described in VMSBUILD.  You may also
  174. Xwant to compile wakeup at this point.
  175. X
  176. X7. Execute build.com to build temacs.dump.
  177. X
  178. X
  179. X
  180. X
  181. X                             Usage
  182. X
  183. X
  184. XThe subprocess functions should work much like they do on unix.
  185. XSome notes:
  186. X
  187. X* Both mailboxes and pseudoterminals are supported (provided you
  188. X  included s-vms5-4.h when building).  Which one is used depends on the
  189. X  value of the variable process-connection-type.
  190. X
  191. X* Subprocesses are created with lib$spawn.  The command line which is
  192. X  used is formed in the following manner.  The exec path is searched for
  193. X  a file matching the supplied program name.  If the program name did
  194. X  not include an extension, the extensions `60.com' and `60.exe' are
  195. X  searched for.  The command string is formed from the result of the
  196. X  search as follows:
  197. X
  198. X    Found .com :  `60@<full pathname>'
  199. X    Found .exe :  `60MCR <full pathname>'
  200. X    No match   : `60<program name>'
  201. X
  202. X  Finally, the supplied arguments are concatenated together on the end
  203. X  of the command string, separated by spaces.
  204. X
  205. X* Subprocess I/O is usually massaged to make things work more like
  206. X  unix.  This is controlled by the function
  207. X  set-process-translation-mode:
  208. X
  209. X
  210. Xset-process-translation-mode:
  211. XSet the translation mode for PROCESS to MODE.
  212. XIf MODE is non-nil, the following translations are performed:
  213. X
  214. X  Sending to PTY processes:
  215. X    If the output string consists of the single character `5ED, it is
  216. X      changed to a `5EZ.`20
  217. X    All newlines (`5EJ) are converted to carriage-returns (`5EM).
  218. X
  219. X  Reading from PTY processes:
  220. X    All carriage-returns (`5EM) and nuls (`5E@) are removed.
  221. X
  222. X  Sending to MBX processes:
  223. X    If the output string consists of the single character `5ED, an EOF
  224. X      is written to the mailbox instead.
  225. X    If the output string ends in a newline (`5EJ), the newline is removed.
  226. X
  227. X  Reading from MBX processes:
  228. X    If the string starts with a carriage return (`5EM) it is removed.
  229. X    If the string ends with a CR/LF sequence (`5EM`5EJ), the sequence is
  230. X      removed.
  231. X    A newline (`5EJ) is added to the end of the string.
  232. X
  233. XThis function is unique to VMS.
  234. X
  235. X  There is also the function process-translation-mode to retrieve the
  236. X  current translation setting.
  237. X
  238. X
  239. X* Sending SIGINT to a subprocess is implemented by doing a $forcex on
  240. X  it.  Sending SIGQUIT, SIGKILL, or SIGHUP to a subprocess will kill it
  241. X  with $delprc.
  242. X
  243. X
  244. X* I've rewritten sys_getenv() so that it uses getenv() as little as
  245. X  possble.  This was done both to reduce the dependencies on the current
  246. X  environment (in particular, DCL symbols are no longer translated) and
  247. X  because getenv() would occasionally crash on me for no apparent
  248. X  reason.  This has the side effect of plugging an ugly memory leak.
  249. X
  250. X
  251. X* With the enclosed patches, the emacs packages compile, dired, lpr,
  252. X  shell, telnet, and time all work to some extent.  I am also enclosing
  253. X  patches to GNUS and the gnuplot interface of calc which allow them to
  254. X  run under VMS.
  255. X
  256. Xenjoy!
  257. Xscott snyder
  258. Xsnyder@d0gsc.fnal.gov
  259. $ CALL UNPACK VMS-CHANGES-README.;8 1275471601
  260. $ create 'f'
  261. X*** callproc.c`09Tue Feb 25 11:59:02 1992
  262. X--- sb12:`5Bscratch.snyder.gnu.emacs-18_58.src`5Dcallproc.c`09Mon May 18 22:
  263. V51:23 1992
  264. X***************
  265. X*** 72,77 ****
  266. X--- 72,94 ----
  267. X  /* Exit code of synchronous subprocess if positive,
  268. X     minus the signal number if negative.  */
  269. X  int synch_process_retcode;
  270. X+`20
  271. X+ #ifdef VMS
  272. X+ #include <descrip.h>
  273. X+ #define       CLI$M_NOWAIT    1       /* clidef.h is missing from C librar
  274. Vy */
  275. X+ #define       CLI$M_WAIT      0       /* clidef.h is missing from C librar
  276. Vy */
  277. X+`20
  278. X+ /* macros to extract the low and high portions of a VMS pid */
  279. X+`20
  280. X+ #define LOPID(x)  ((x) & 0x000fffff)
  281. X+ #define HIPID(x) (((x) & 0xfff00000) >> 20)
  282. X+`20
  283. X+ /* join the two parts back together again */
  284. X+`20
  285. X+ #define MKPID(lo, hi) ((lo) `7C ((hi) << 20))
  286. X+`20
  287. X+ static int sync_process_exited;
  288. X+ #endif
  289. X  `0C
  290. X  Lisp_Object
  291. X  call_process_cleanup (fdpid)
  292. X***************
  293. X*** 80,87 ****
  294. X--- 97,109 ----
  295. X    register Lisp_Object fd, pid;
  296. X    fd = Fcar (fdpid);
  297. X    pid = Fcdr (fdpid);
  298. X+ #ifdef VMS
  299. X+   vms_close_fd (XFASTINT (fd));
  300. X+   kill (MKPID (XFASTINT (Fcar (pid)), XFASTINT (Fcdr (pid))), SIGKILL);
  301. X+ #else
  302. X    close (XFASTINT (fd));
  303. X    kill (XFASTINT (pid), SIGKILL);
  304. X+ #endif
  305. X    return Qnil;
  306. X  `7D
  307. X `20
  308. X***************
  309. X*** 92,97 ****
  310. X--- 114,190 ----
  311. X  #else
  312. X  extern noshare char **environ;
  313. X  #endif
  314. X+`20
  315. X+ static void sync_exit_ast(void)
  316. X+ `7B
  317. X+   extern int process_ef, process_tick;
  318. X+`20
  319. X+   sync_process_exited = 1;
  320. X+`20
  321. X+   /* jar select loose */
  322. X+   ++process_tick;
  323. X+   sys$setef(process_ef);
  324. X+ `7D
  325. X+`20
  326. X+ /* Prepare a command string for starting a process on VMS. NEW_ARGV is a
  327. X+    NULL-terminated vector of arguments, with NEW_ARGV`5B0`5D being the pro
  328. Vgram
  329. X+    to run, or the DCL command verb. First, EXEC-PATH is searched for a fil
  330. Ve
  331. X+    matching NEW_ARGV`5B0`5D and ending either `60.com' or `60.exe'. If a m
  332. Vatch is
  333. X+    found ending with `60.com', NEW_ARGV`5B0`5D is changed to an `60@' in f
  334. Vront of
  335. X+    the full path; if a match is found ending in `60.exe', NEW_ARGV`5B0`5D
  336. V is changed
  337. X+    to `60MCR ' in front of the full path. Finally, the elements of NEW_ARG
  338. VV
  339. X+    are concatenated together (separated by spaces) into a single string, w
  340. Vhich
  341. X+    is then returned. This string will have been obtained from malloc(), an
  342. Vd
  343. X+    should be freed when you are done with it.
  344. X+`20
  345. X+    This function may clobber NEW_ARGV`5B0`5D.
  346. X+ */
  347. X+`20
  348. X+ char *vms_hack_process_args(new_argv)
  349. X+ unsigned char **new_argv;
  350. X+ `7B
  351. X+   int i, totlen;
  352. X+   char *cmd;
  353. X+   Lisp_Object path;
  354. X+`20
  355. X+   openp (Vexec_path, build_string (new_argv`5B0`5D), ":.EXE:.COM", &path,
  356. V 1);
  357. X+   if ( ! NULL (path))
  358. X+     `7B
  359. X+       if (XSTRING(path)->size >= 4 &&
  360. X+ `09  strcmp (XSTRING (path)->data + XSTRING (path)->size - 4,".EXE") == 0)
  361. X+ `09`7B
  362. X+ `09  unsigned char *buf = alloca (XSTRING (path)->size + 5);
  363. X+ `09  strcpy (buf, "MCR ");
  364. X+ `09  strcat (buf, XSTRING (path)->data);
  365. X+ `09  new_argv`5B0`5D = buf;
  366. X+ `09`7D
  367. X+       else if (XSTRING (path)->size >= 4 &&
  368. X+ `09       strcmp (XSTRING (path)->data + XSTRING (path)->size - 4,
  369. X+ `09`09       ".COM") == 0)
  370. X+ `09`7B
  371. X+ `09  unsigned char *buf = alloca (XSTRING (path)->size + 2);
  372. X+ `09  strcpy (buf, "@");
  373. X+ `09  strcat (buf, XSTRING (path)->data);
  374. X+ `09  new_argv`5B0`5D = buf;
  375. X+ `09`7D
  376. X+       else
  377. X+ `09new_argv`5B0`5D = XSTRING (path)->data;
  378. X+     `7D
  379. X+`20
  380. X+   totlen = 0;
  381. X+   for (i=0; new_argv`5Bi`5D != 0; i++)
  382. X+     totlen += strlen (new_argv`5Bi`5D) + 1;
  383. X+   cmd = (char *) xmalloc (totlen+1);
  384. X+   cmd`5B0`5D = '\0';
  385. X+   for (i=0; new_argv`5Bi`5D != 0; i++)
  386. X+     `7B
  387. X+       strcat (cmd, new_argv`5Bi`5D);
  388. X+       strcat (cmd, " ");
  389. X+     `7D
  390. X+`20
  391. X+   return cmd;
  392. X+ `7D
  393. X+`20
  394. X  #else
  395. X  extern char **environ;
  396. X  #endif
  397. X***************
  398. X*** 113,124 ****
  399. X    Lisp_Object display, buffer, path;
  400. X    int fd`5B2`5D;
  401. X    int filefd;
  402. X-   register int pid;
  403. X    char buf`5B1024`5D;
  404. X    int count = specpdl_ptr - specpdl;
  405. X    register unsigned char **new_argv
  406. X      = (unsigned char **) alloca ((max (2, nargs - 2)) * sizeof (char *));
  407. X    struct buffer *old = current_buffer;
  408. X `20
  409. X    CHECK_STRING (args`5B0`5D, 0);
  410. X `20
  411. X--- 206,223 ----
  412. X    Lisp_Object display, buffer, path;
  413. X    int fd`5B2`5D;
  414. X    int filefd;
  415. X    char buf`5B1024`5D;
  416. X    int count = specpdl_ptr - specpdl;
  417. X    register unsigned char **new_argv
  418. X      = (unsigned char **) alloca ((max (2, nargs - 2)) * sizeof (char *));
  419. X    struct buffer *old = current_buffer;
  420. X+ #ifdef VMS
  421. X+   int pid;
  422. X+   char out_name_buf`5B33`5D;
  423. X+   $DESCRIPTOR (out_dsc, out_name_buf);
  424. X+ #else
  425. X+   register int pid;
  426. X+ #endif
  427. X `20
  428. X    CHECK_STRING (args`5B0`5D, 0);
  429. X `20
  430. X***************
  431. X*** 131,136 ****
  432. X--- 230,250 ----
  433. X    else
  434. X      args`5B1`5D = Fexpand_file_name (args`5B1`5D, current_buffer->director
  435. Vy);
  436. X `20
  437. X+ #ifdef VMS
  438. X+   /* if the file name doesn't have an extension, add a period. */
  439. X+   `7B
  440. X+     extern unsigned char *strchr (), *strrchr ();
  441. X+     unsigned char *p = strrchr (XSTRING (args`5B1`5D)->data, '`5D');
  442. X+     if (p == 0)
  443. X+       p = strrchr (XSTRING (args`5B1`5D)->data, ':');
  444. X+     if (p == 0)
  445. X+       p = XSTRING (args`5B1`5D)->data;
  446. X+`20
  447. X+     if (strchr (p, '.') == 0)
  448. X+       args`5B1`5D = concat2 (args`5B1`5D, build_string ("."));
  449. X+   `7D
  450. X+ #endif
  451. X+`20
  452. X    CHECK_STRING (args`5B1`5D, 1);
  453. X `20
  454. X    `7B
  455. X***************
  456. X*** 165,170 ****
  457. X--- 279,285 ----
  458. X      `7B
  459. X        report_file_error ("Opening process input file", Fcons (args`5B1`5D,
  460. V Qnil));
  461. X      `7D
  462. X+ #ifndef VMS
  463. X    /* Search for program; barf if not found.  */
  464. X    openp (Vexec_path, args`5B0`5D, "", &path, 1);
  465. X    if (NULL (path))
  466. X***************
  467. X*** 173,185 ****
  468. X        report_file_error ("Searching for program", Fcons (args`5B0`5D, Qnil
  469. V));
  470. X      `7D
  471. X    new_argv`5B0`5D = XSTRING (path)->data;
  472. X `20
  473. X    if (XTYPE (buffer) == Lisp_Int)
  474. X  #ifdef VMS
  475. X!     fd`5B1`5D = open ("NLA0:", 0), fd`5B0`5D = -1;
  476. X! #else
  477. X      fd`5B1`5D = open ("/dev/null", O_WRONLY), fd`5B0`5D = -1;
  478. X- #endif /* not VMS */
  479. X    else
  480. X      `7B
  481. X        pipe (fd);
  482. X--- 288,314 ----
  483. X        report_file_error ("Searching for program", Fcons (args`5B0`5D, Qnil
  484. V));
  485. X      `7D
  486. X    new_argv`5B0`5D = XSTRING (path)->data;
  487. X+ #endif
  488. X `20
  489. X    if (XTYPE (buffer) == Lisp_Int)
  490. X  #ifdef VMS
  491. X!     `7B
  492. X!       out_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
  493. X!       out_dsc.dsc$b_class = DSC$K_CLASS_S;
  494. X!       out_dsc.dsc$a_pointer = "NLA0:";
  495. X!       out_dsc.dsc$w_length = strlen (out_dsc.dsc$a_pointer);
  496. X!       fd`5B0`5D = -1;
  497. X!     `7D
  498. X!   else
  499. X!     `7B
  500. X!       extern struct dsc$descriptor_s *vms_mbx_dsc ();
  501. X!       if (vms_pipe (fd) < 0)
  502. X!       error ("can't create mailboxes");
  503. X!       vms_close_fd (fd`5B1`5D);
  504. X!       vms_get_device_name (fd`5B0`5D, &out_dsc);
  505. X!     `7D
  506. X! #else  /* not VMS */
  507. X      fd`5B1`5D = open ("/dev/null", O_WRONLY), fd`5B0`5D = -1;
  508. X    else
  509. X      `7B
  510. X        pipe (fd);
  511. X***************
  512. X*** 188,197 ****
  513. X--- 317,328 ----
  514. X        set_exclusive_use (fd`5B0`5D);
  515. X  #endif
  516. X      `7D
  517. X+ #endif  /* not VMS */
  518. X `20
  519. X    synch_process_death = 0;
  520. X    synch_process_retcode = 0;
  521. X `20
  522. X+ #ifndef VMS
  523. X    `7B
  524. X      /* child_setup must clobber environ in systems with true vfork.
  525. X         Protect it from permanent change.  */
  526. X***************
  527. X*** 235,241 ****
  528. X--- 366,406 ----
  529. X        close (fd`5B0`5D);
  530. X        report_file_error ("Doing vfork", Qnil);
  531. X      `7D
  532. X+ #else /* VMS */
  533. X+   `7B
  534. X+     struct dsc$descriptor_s in_dsc, cmd_dsc;
  535. X+     int status;
  536. X+     int dum_CLI$M_NOWAIT = CLI$M_NOWAIT;
  537. X+     char *cmd;
  538. X+`20
  539. X+     close (filefd);
  540. X+     in_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
  541. X+     in_dsc.dsc$b_class = DSC$K_CLASS_S;
  542. X+     in_dsc.dsc$a_pointer = (char *) XSTRING (args`5B1`5D)->data;
  543. X+     in_dsc.dsc$w_length = strlen (XSTRING (args`5B1`5D)->data);
  544. X+`20
  545. X+     cmd = vms_hack_process_args (new_argv);
  546. X+`20
  547. X+     cmd_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
  548. X+     cmd_dsc.dsc$b_class = DSC$K_CLASS_S;
  549. X+     cmd_dsc.dsc$a_pointer = cmd;
  550. X+     cmd_dsc.dsc$w_length = strlen (cmd);
  551. X+`20
  552. X+     sync_process_exited = 0;
  553. X+     status = lib$spawn (&cmd_dsc, &in_dsc, &out_dsc, &dum_CLI$M_NOWAIT, 0,
  554. X+ `09`09`09&pid, &synch_process_retcode, 0, sync_exit_ast, 0);
  555. X+`20
  556. X+     free (cmd);
  557. X `20
  558. X+     if (! (status & 1))
  559. X+       `7B
  560. X+ `09vms_close_fd (fd`5B0`5D);
  561. X+ `09error  ("Unable to spawn subprocess");
  562. X+       `7D
  563. X+   `7D
  564. X+ #endif /* VMS */
  565. X+`20
  566. X+`20
  567. X    if (XTYPE (buffer) == Lisp_Int)
  568. X      `7B
  569. X  #ifndef subprocesses
  570. X***************
  571. X*** 244,251 ****
  572. X--- 409,423 ----
  573. X        return Qnil;
  574. X      `7D
  575. X `20
  576. X+ #ifdef VMS
  577. X+   record_unwind_protect (call_process_cleanup,
  578. X+ `09`09`09 Fcons (make_number (fd`5B0`5D),
  579. X+ `09`09`09`09Fcons (make_number (LOPID (pid)),
  580. X+ `09`09`09`09       make_number (HIPID (pid)))));
  581. X+ #else
  582. X    record_unwind_protect (call_process_cleanup,
  583. X  `09`09`09 Fcons (make_number (fd`5B0`5D), make_number (pid)));
  584. X+ #endif
  585. X `20
  586. X `20
  587. X    if (XTYPE (buffer) == Lisp_Buffer)
  588. X***************
  589. X*** 257,264 ****
  590. X--- 429,446 ----
  591. X    `7B
  592. X      register int nread;
  593. X `20
  594. X+ #ifdef VMS
  595. X+     int rfds = 1<<fd`5B0`5D;
  596. X+`20
  597. X+     while ( ! sync_process_exited )
  598. X+       `7B
  599. X+       select(32, &rfds, 0, 0, 0);
  600. X+       if ((nread = vms_read_fd (fd`5B0`5D, buf, sizeof buf)) > 0)
  601. X+ `09`7B
  602. X+ #else /* not VMS */
  603. X      while ((nread = read (fd`5B0`5D, buf, sizeof buf)) > 0)
  604. X        `7B
  605. X+ #endif /* not VMS */
  606. X  `09immediate_quit = 0;
  607. X  `09if (!NULL (buffer))
  608. X  `09  insert (buf, nread);
  609. X***************
  610. X*** 266,276 ****
  611. X--- 448,464 ----
  612. X  `09  redisplay_preserve_echo_area ();
  613. X  `09immediate_quit = 1;
  614. X  `09QUIT;
  615. X+ #ifdef VMS
  616. X+         `7D
  617. X        `7D
  618. X    `7D
  619. X+ #else /* not VMS */
  620. X+       `7D
  621. X+   `7D
  622. X `20
  623. X    /* Wait for it to terminate, unless it already has.  */
  624. X    wait_for_termination (pid);
  625. X+ #endif /* not VMS */
  626. X `20
  627. X    immediate_quit = 0;
  628. X `20
  629. X***************
  630. X*** 317,322 ****
  631. X--- 505,511 ----
  632. X    return Qnil;
  633. X  `7D
  634. X  `0C
  635. X+ #ifndef VMS
  636. X  /* This is the last thing run in a newly forked inferior
  637. X     either synchronous or asynchronous.
  638. X     Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2.
  639. X***************
  640. X*** 423,428 ****
  641. X--- 612,618 ----
  642. X    write (1, new_argv`5B0`5D, strlen (new_argv`5B0`5D));
  643. X    _exit (1);
  644. X  `7D
  645. X+ #endif /* not VMS */
  646. X  `0C
  647. X  init_callproc ()
  648. X  `7B
  649. X*** emacs.c`09Tue Feb 25 11:59:05 1992
  650. X--- sb12:`5Bscratch.snyder.gnu.emacs-18_58.src`5Demacs.c`09Mon May 18 22:51:
  651. V29 1992
  652. X***************
  653. X*** 169,176 ****
  654. X  #endif /* CLASH_DETECTION */
  655. X `20
  656. X  #ifdef VMS
  657. X!   kill_vms_processes ();
  658. X!   LIB$STOP (SS$_ABORT);
  659. X  #else
  660. X    /* Signal the same code; this time it will really be fatal.  */
  661. X    kill (getpid (), fatal_error_code);
  662. X--- 169,175 ----
  663. X  #endif /* CLASH_DETECTION */
  664. X `20
  665. X  #ifdef VMS
  666. X!   lib$signal (SS$_DEBUG);
  667. X  #else
  668. X    /* Signal the same code; this time it will really be fatal.  */
  669. X    kill (getpid (), fatal_error_code);
  670. X***************
  671. X*** 565,574 ****
  672. X  #ifdef subprocesses
  673. X    kill_buffer_processes (Qnil);
  674. X  #endif /* subprocesses */
  675. X-`20
  676. X- #ifdef VMS
  677. X-   kill_vms_processes ();
  678. X- #endif /* VMS */
  679. X `20
  680. X    Fdo_auto_save (Qt);
  681. X `20
  682. X--- 564,569 ----
  683. X*** keyboard.c`09Tue Feb 25 11:59:07 1992
  684. X--- sb12:`5Bscratch.snyder.gnu.emacs-18_58.src`5Dkeyboard.c`09Mon May 18 22:
  685. V51:34 1992
  686. X***************
  687. X*** 1123,1131 ****
  688. X        /* One way or another, wait until input is available; then, if
  689. X  `09 interrupt handlers have not read it, read it now.  */
  690. X `20
  691. X- #ifdef VMS
  692. X-       wait_for_kbd_input ();
  693. X- #else
  694. X  /* Note SIGIO has been undef'd if FIONREAD is missing.  */
  695. X  #ifdef SIGIO
  696. X        gobble_input ();
  697. X--- 1123,1128 ----
  698. X***************
  699. X*** 1156,1162 ****
  700. X  `09      read_avail_input (0);
  701. X  `09    `7D
  702. X  `09`7D
  703. X- #endif /* not VMS */
  704. X      `7D
  705. X `20
  706. X    input_pending = --kbd_count > 0;
  707. X--- 1153,1158 ----
  708. X*** process.c`09Tue Feb 25 11:59:19 1992
  709. X--- `5Bscratch.snyder.gnu.emacs-18_58.src`5Dprocess.c`09Thu Jul  2 07:52:52
  710. V 1992
  711. X***************
  712. X*** 22,32 ****
  713. X `20
  714. X  #include "config.h"
  715. X `20
  716. X- #ifdef VMS
  717. X- /* Prevent the file from being totally empty.  */
  718. X- static dummy () `7B`7D
  719. X- #endif
  720. X-`20
  721. X  #ifdef subprocesses
  722. X  /* The entire file is within this conditional */
  723. X `20
  724. X--- 22,27 ----
  725. X***************
  726. X*** 38,46 ****
  727. X--- 33,54 ----
  728. X  #include <sys/stat.h>
  729. X `20
  730. X  #ifdef HAVE_SOCKETS`09/* TCP connection support, if kernel can do it */
  731. X+ #ifdef VMS
  732. X+ #ifndef __GNUC__
  733. X+ #include "multinet_root:`5Bmultinet.include.sys`5Dtypes.h"
  734. X+ #undef FD_SET    /* we need types for the rest of the multinet includes */
  735. X+ #undef FD_CLR    /* to work with vaxc.  but types makes bogus defns */
  736. X+ #undef FD_ISSET  /* of the FD_* macros... */
  737. X+ #undef FD_ZERO
  738. X+ #endif
  739. X+ #include "multinet_root:`5Bmultinet.include.sys`5Dsocket.h"
  740. X+ #include "multinet_root:`5Bmultinet.include`5Dnetdb.h"
  741. X+ #include "multinet_root:`5Bmultinet.include.netinet`5Din.h"
  742. X+ #else
  743. X  #include <sys/socket.h>
  744. X  #include <netdb.h>
  745. X  #include <netinet/in.h>
  746. X+ #endif
  747. X  #endif /* HAVE_SOCKETS */
  748. X `20
  749. X  #if defined(BSD) `7C`7C defined(STRIDE)
  750. X***************
  751. X*** 101,106 ****
  752. X--- 109,122 ----
  753. X  #undef O_NONBLOCK
  754. X  #endif
  755. X `20
  756. X+ #ifdef VMS
  757. X+ #include <descrip.h>
  758. X+ #include <iodef.h>
  759. X+ #include <dvidef.h>
  760. X+ #define       CLI$M_NOWAIT    1       /* clidef.h is missing from C librar
  761. Vy */
  762. X+ #define       CLI$M_WAIT      0       /* clidef.h is missing from C librar
  763. Vy */
  764. X+ #endif
  765. X+`20
  766. X  #undef NULL
  767. X  #include "lisp.h"
  768. X  #include "window.h"
  769. X***************
  770. X*** 135,141 ****
  771. X `20
  772. X  /* Define the structure that the wait system call stores.
  773. X     On many systems, there is a structure defined for this.
  774. X!    But on vanilla-ish USG systems there is not.  */
  775. X `20
  776. X  #ifndef WAITTYPE
  777. X  #if !defined (BSD) && !defined (UNIPLUS) && !defined (STRIDE) && !(defined
  778. V (HPUX) && !defined (NOMULTIPLEJOBS)) && !defined (HAVE_WAIT_HEADER)
  779. X--- 151,169 ----
  780. X `20
  781. X  /* Define the structure that the wait system call stores.
  782. X     On many systems, there is a structure defined for this.
  783. X!    But on vanilla-ish USG systems there is not.
  784. X!    Neither is there on VMS (surprise, surprise!). */
  785. X!`20
  786. X! #ifdef VMS
  787. X! # define WAITTYPE int
  788. X! # define WIFSTOPPED(w) 0
  789. X! # define WIFSIGNALED(w) 0
  790. X! # define WIFEXITED(w) ((w) != -1)
  791. X! # define WRETCODE(w) (w)
  792. X! # define WSTOPSIG(w) (w)
  793. X! # define WCOREDUMP(w) 0
  794. X! # define WTERMSIG(w) (w)
  795. X! #endif
  796. X `20
  797. X  #ifndef WAITTYPE
  798. X  #if !defined (BSD) && !defined (UNIPLUS) && !defined (STRIDE) && !(defined
  799. V (HPUX) && !defined (NOMULTIPLEJOBS)) && !defined (HAVE_WAIT_HEADER)
  800. X***************
  801. X*** 289,294 ****
  802. X--- 317,384 ----
  803. X     output from the process is to read at least one char.
  804. X     Always -1 on systems that support FIONREAD.  */
  805. X `20
  806. X+ #ifdef VMS
  807. X+`20
  808. X+ /* A few notes on the VMS subprocess implementation:
  809. X+`20
  810. X+    All input and output is done through `60pseudo-fds', which are
  811. X+    managed in sysdep.c.  They can refer to mailboxes, ptys, or
  812. X+    network streams.  They are created by the functions vms_pipe,
  813. X+    vms_make_pty, and vms_net_chan and operated on with vms_read_fd,
  814. X+    vms_write_fd, and vms_close_fd.  They also can be used with the
  815. X+    vms select emulator in sysdep.c.
  816. X+`20
  817. X+    Pseudo-fd 0 always refers to the keyboard.  The select emulator
  818. X+    knows about this.
  819. X+`20
  820. X+    Retrieving the exit status from a child process works somewhat differen
  821. Vtly
  822. X+    on vms than on unix.  One can request a subprocess termination AST,
  823. X+    and one can supply a memory location into which the system will
  824. X+    write the completion status when the subprocess completes.  Naturally,
  825. X+    one must ensure that this memory location remains valid until the
  826. X+    process actually exits.  If I were to use a member of the Lisp_Process
  827. X+    struct for this, I don't think that that can be guaranteed: it seems
  828. X+    possible for the Lisp_Process struct to be freed before the process
  829. X+    actually terminates.
  830. X+`20
  831. X+    To solve this problem, we keep the exit status in a separate structure,
  832. X+    struct vms_process_handle.  These are kept in a table: vms_handle_tab.
  833. X+    Besides the exit status longword, each handle contains a pointer
  834. X+    back to the Lisp_Process struct.  The procedure works like this:
  835. X+`20
  836. X+    - Initially, all the handles have a NULL pointer.
  837. X+    - When creating a process, we find a free handle (one with a NULL point
  838. Ver)
  839. X+      and set it to point to the Lisp_Process struct for this process.
  840. X+    - When deleting a process, we search the table for a handle pointing
  841. X+      to the process's Lisp_Process struct.  If there's one there, we
  842. X+      invalidate it by changing the pointer to -1.
  843. X+    - When we receive an exit_ast, we look at the value of the pointer in
  844. X+      the handle.  If it's still valid (not -1), we copy the status return
  845. X+      into the Lisp_Process struct.  In any event, we reset the pointer to
  846. X+      NULL to free the handle.
  847. X+`20
  848. X+    - sss  (snyder@d0gsc.fnal.gov)  */
  849. X+`20
  850. X+ struct vms_process_handle `7B
  851. X+   struct Lisp_Process *proc;
  852. X+   int exit_status;
  853. X+ `7D;
  854. X+`20
  855. X+ struct vms_process_handle vms_handle_tab`5BMAXDESC`5D;
  856. X+`20
  857. X+ /* macros to extract the low and high portions of a VMS pid */
  858. X+`20
  859. X+ #define LOPID(x)  ((x) & 0x000fffff)
  860. X+ #define HIPID(x) (((x) & 0xfff00000) >> 20)
  861. X+`20
  862. X+ /* join the two parts back together again */
  863. X+`20
  864. X+ #define MKPID(lo, hi) ((lo) `7C ((hi) << 20))
  865. X+`20
  866. X+ static void exit_ast();
  867. X+`20
  868. X+ #endif  /* VMS */
  869. X+`20
  870. X  int proc_buffered_char`5BMAXDESC`5D;
  871. X `20
  872. X  /* These variables hold the filter about to be run, and its args,
  873. X***************
  874. X*** 510,515 ****
  875. X--- 600,609 ----
  876. X    XFASTINT (p->infd) = 0;
  877. X    XFASTINT (p->outfd) = 0;
  878. X    XFASTINT (p->pid) = 0;
  879. X+ #ifdef VMS
  880. X+   XFASTINT (p->hipid) = 0;
  881. X+   p->translate_p = Qt;
  882. X+ #endif
  883. X    XFASTINT (p->tick) = 0;
  884. X    XFASTINT (p->update_tick) = 0;
  885. X    p->raw_status_low = Qnil;
  886. X***************
  887. X*** 538,543 ****
  888. X--- 632,651 ----
  889. X  `7B
  890. X    register Lisp_Object pair;
  891. X `20
  892. X+ #ifdef VMS
  893. X+   int i;
  894. X+`20
  895. X+   /* invalidate the handle */
  896. X+   sys$setast (0);
  897. X+   for (i=0; i<MAXDESC; i++)
  898. X+     if (vms_handle_tab`5Bi`5D.proc == XPROCESS (proc))
  899. X+       `7B
  900. X+ `09vms_handle_tab`5Bi`5D.proc = (struct Lisp_Process *) (-1);
  901. X+ `09break;
  902. X+       `7D
  903. X+   sys$setast (1);
  904. X+ #endif
  905. X+`20
  906. X    pair = Frassq (proc, Vprocess_alist);
  907. X    Vprocess_alist = Fdelq (pair, Vprocess_alist);
  908. X    Fset_marker (XPROCESS (proc)->mark, Qnil, Qnil);
  909. X***************
  910. X*** 822,827 ****
  911. X--- 930,985 ----
  912. X    XPROCESS (proc)->kill_without_query = Fnull (value);
  913. X    return Fnull (tem);
  914. X  `7D
  915. X+`20
  916. X+ #ifdef VMS
  917. X+`20
  918. X+ DEFUN ("set-process-translation-mode", Fset_process_translation_mode,
  919. X+   Sset_process_translation_mode,  2, 2, 0,
  920. X+   "Set the translation mode for PROCESS to MODE.\n\
  921. X+ If MODE is non-nil, the following translations are performed:\n\
  922. X+ \n\
  923. X+   Sending to PTY processes:\n\
  924. X+     If the output string consists of the single character `5ED, it is\n\
  925. X+       changed to a `5EZ. \n\
  926. X+     All newlines (`5EJ) are converted to carriage-returns (`5EM).\n\
  927. X+ \n\
  928. X+   Reading from PTY processes:\n\
  929. X+     All carriage-returns (`5EM) and nuls (`5E@) are removed.\n\
  930. X+ \n\
  931. X+   Sending to MBX processes:\n\
  932. X+     If the output string consists of the single character `5ED, an EOF\n\
  933. X+       is written to the mailbox instead.\n\
  934. X+     If the output string ends in a newline (`5EJ), the newline is removed.
  935. V\n\
  936. X+ \n\
  937. X+   Reading from MBX processes:\n\
  938. X+     If the string starts with a carriage return (`5EM) it is removed.\n\
  939. X+     If the string ends with a CR/LF sequence (`5EM`5EJ), the sequence is\n
  940. V\
  941. X+       removed.\n\
  942. X+     A newline (`5EJ) is added to the end of the string.\n\
  943. X+ \n\
  944. X+ This function is unique to VMS.")
  945. X+   (proc, mode)
  946. X+      register Lisp_Object proc, mode;
  947. X+ `7B
  948. X+   CHECK_PROCESS (proc, 0);
  949. X+   XPROCESS (proc)->translate_p = mode;
  950. X+   return mode;
  951. X+ `7D
  952. X+`20
  953. X+ DEFUN ("process-translation-mode", Fprocess_translation_mode,
  954. X+   Sprocess_translation_mode, 1, 1, 0,
  955. X+   "Returns the translation mode of PROCESS.\n\
  956. X+ See set-process-translation-mode for more info on process I/O translations
  957. V.\n\
  958. X+ \n\
  959. X+ This function is unique to VMS.")
  960. X+   (proc)
  961. X+      register Lisp_Object proc;
  962. X+ `7B
  963. X+   CHECK_PROCESS (proc, 0);
  964. X+   return XPROCESS (proc)->translate_p;
  965. X+ `7D
  966. X+`20
  967. X+ #endif  /* VMS */
  968. X  `0C
  969. X  Lisp_Object
  970. X  list_processes_1 ()
  971. X***************
  972. X*** 991,996 ****
  973. X--- 1149,1155 ----
  974. X    new_argv`5Bi - 2`5D = 0;
  975. X    new_argv`5B0`5D = XSTRING (program)->data;
  976. X `20
  977. X+ #ifndef VMS
  978. X    /* If program file name is not absolute, search our path for it */
  979. X    if (new_argv`5B0`5D`5B0`5D != '/')
  980. X      `7B
  981. X***************
  982. X*** 1000,1005 ****
  983. X--- 1159,1165 ----
  984. X  `09report_file_error ("Searching for program", Fcons (program, Qnil));
  985. X        new_argv`5B0`5D = XSTRING (tem)->data;
  986. X      `7D
  987. X+ #endif  /* not VMS */
  988. X `20
  989. X    proc = make_process (name);
  990. X `20
  991. X***************
  992. X*** 1015,1020 ****
  993. X--- 1175,1266 ----
  994. X    return proc;
  995. X  `7D
  996. X `20
  997. X+ #ifdef VMS
  998. X+`20
  999. X+ create_process (process, new_argv)
  1000. X+      Lisp_Object process;
  1001. X+      char **new_argv;
  1002. X+ `7B
  1003. X+   int fds`5B2`5D, pid, status, handle_ndx;
  1004. X+   int dum_CLI$M_NOWAIT = CLI$M_NOWAIT;
  1005. X+   char *cmd;
  1006. X+   int pty_flag = 0;
  1007. X+   char indevbuf`5B21`5D, outdevbuf`5B21`5D;
  1008. X+   $DESCRIPTOR (indsc, indevbuf);
  1009. X+   $DESCRIPTOR (outdsc, outdevbuf);
  1010. X+`20
  1011. X+   struct dsc$descriptor_s cmd_dsc;
  1012. X+   extern char *vms_hack_process_args ();
  1013. X+`20
  1014. X+   /* create the I/O channels, either ptys or mailboxes */
  1015. X+   status = -1;
  1016. X+ #ifdef HAVE_VMS_PTYS
  1017. X+   if (EQ (Vprocess_connection_type, Qt))
  1018. X+     `7B
  1019. X+       status = vms_make_pty (fds);
  1020. X+       if (status >= 0)
  1021. X+ `09pty_flag = 1;
  1022. X+     `7D
  1023. X+ #endif
  1024. X+`20
  1025. X+   if (status < 0)
  1026. X+     `7B
  1027. X+       if (vms_pipe (fds) < 0)
  1028. X+ `09error ("Can't create mailboxes");
  1029. X+     `7D
  1030. X+`20
  1031. X+   /* find a free process handle */
  1032. X+   for (handle_ndx = 0; handle_ndx < MAXDESC; handle_ndx++)
  1033. X+     if (vms_handle_tab`5Bhandle_ndx`5D.proc == 0)
  1034. X+       `7B
  1035. X+ `09vms_handle_tab`5Bhandle_ndx`5D.proc = XPROCESS (process);
  1036. X+ `09vms_handle_tab`5Bhandle_ndx`5D.exit_status = -1;
  1037. X+ `09break;
  1038. X+       `7D
  1039. X+   if (handle_ndx >= MAXDESC)
  1040. X+     error ("Can't allocate process handle");
  1041. X+`20
  1042. X+   /* fill in the fields of the process struct */
  1043. X+   chan_process`5Bfds`5B0`5D`5D = process;
  1044. X+   XFASTINT (XPROCESS (process)->infd) = fds`5B0`5D;
  1045. X+   XFASTINT (XPROCESS (process)->outfd) = fds`5B1`5D;
  1046. X+   XPROCESS (process)->pty_flag = (pty_flag ? Qt : Qnil);
  1047. X+   XPROCESS (process)->status = Qrun;
  1048. X+   XPROCESS (process)->subtty = Qnil;
  1049. X+`20
  1050. X+   /* prepare the dcl command line */
  1051. X+   cmd = vms_hack_process_args (new_argv);
  1052. X+   cmd_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
  1053. X+   cmd_dsc.dsc$b_class = DSC$K_CLASS_S;
  1054. X+   cmd_dsc.dsc$a_pointer = cmd;
  1055. X+   cmd_dsc.dsc$w_length = strlen (cmd);
  1056. X+`20
  1057. X+   /* spawn the subprocess... */
  1058. X+   vms_get_device_name (fds`5B0`5D, &indsc);
  1059. X+   vms_get_device_name (fds`5B1`5D, &outdsc);
  1060. X+`20
  1061. X+   message ("Creating subprocess...");
  1062. X+   status = lib$spawn (&cmd_dsc, &outdsc, &indsc, &dum_CLI$M_NOWAIT, 0,
  1063. X+                       &pid, &vms_handle_tab`5Bhandle_ndx`5D.exit_status, 0
  1064. V,
  1065. X+ `09`09      exit_ast, &vms_handle_tab`5Bhandle_ndx`5D);
  1066. X+   if (! (status & 1))
  1067. X+     `7B
  1068. X+       remove_process (process);`20
  1069. X+       error ("Unable to spawn subprocess");
  1070. X+     `7D
  1071. X+`20
  1072. X+   /* record the pid */
  1073. X+   XFASTINT (XPROCESS (process)->pid) = LOPID (pid);
  1074. X+   XFASTINT (XPROCESS (process)->hipid) = HIPID (pid);
  1075. X+`20
  1076. X+   /* receive input from this process */
  1077. X+   FD_SET (fds`5B0`5D, &input_wait_mask);
  1078. X+`20
  1079. X+   message ("Creating subprocess...done");
  1080. X+ `7D
  1081. X+`20
  1082. X+ #else /* not VMS */
  1083. X+`20
  1084. X  create_process_1 (signo)
  1085. X       int signo;
  1086. X  `7B
  1087. X***************
  1088. X*** 1333,1338 ****
  1089. X--- 1579,1586 ----
  1090. X    `7D
  1091. X  `7D
  1092. X `20
  1093. X+ #endif /* not VMS */
  1094. X+`20
  1095. X  #ifdef HAVE_SOCKETS
  1096. X `20
  1097. X  /* open a TCP network connection to a given HOST/SERVICE.  Treated
  1098. X***************
  1099. X*** 1396,1406 ****
  1100. X--- 1644,1656 ----
  1101. X    if (s < 0)`20
  1102. X      report_file_error ("error creating socket", Fcons (name, Qnil));
  1103. X `20
  1104. X+ #ifndef VMS
  1105. X    /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
  1106. X       when connect is interrupted.  So let's not let it get interrupted.  *
  1107. V/
  1108. X    if (interrupt_input)
  1109. X      unrequest_sigio ();
  1110. X    stop_polling ();
  1111. X+ #endif
  1112. X `20
  1113. X    while (1)
  1114. X      `7B
  1115. X***************
  1116. X*** 1411,1422 ****
  1117. X--- 1661,1685 ----
  1118. X        /* Report a "real" error.  */
  1119. X        if (errno != EINTR)
  1120. X  `09`7B
  1121. X+ #ifdef VMS
  1122. X+ `09  socket_close (s);
  1123. X+ #else
  1124. X  `09  close (s);
  1125. X+ #endif
  1126. X  `09  error ("Host \"%s\" not responding", XSTRING (host)->data);
  1127. X  `09`7D
  1128. X        /* Loop around after temporary error.  */
  1129. X      `7D
  1130. X `20
  1131. X+ #ifdef VMS
  1132. X+   `7B
  1133. X+     int fds`5B2`5D;
  1134. X+     if (vms_net_chan (s, fds) < 0)
  1135. X+       report_file_error ("error starting I/O on socket", Fcons (name, Qnil
  1136. V));
  1137. X+     inch = fds`5B0`5D;
  1138. X+     outch = fds`5B1`5D;
  1139. X+   `7D
  1140. X+ #else  /* not VMS */
  1141. X    if (interrupt_input)
  1142. X      request_sigio ();
  1143. X    start_polling ();
  1144. X***************
  1145. X*** 1425,1430 ****
  1146. X--- 1688,1694 ----
  1147. X    outch = dup (s);
  1148. X    if (outch < 0)`20
  1149. X      report_file_error ("error duplicating socket", Fcons (name, Qnil));
  1150. X+ #endif  /* not VMS */
  1151. X `20
  1152. X    if (!NULL (buffer))
  1153. X      buffer = Fget_buffer_create (buffer);
  1154. X***************
  1155. X*** 1432,1437 ****
  1156. X--- 1696,1702 ----
  1157. X `20
  1158. X    chan_process`5Binch`5D = proc;
  1159. X `20
  1160. X+ #ifndef VMS
  1161. X  #ifdef O_NONBLOCK
  1162. X    fcntl (inch, F_SETFL, O_NONBLOCK);
  1163. X  #else
  1164. X***************
  1165. X*** 1439,1444 ****
  1166. X--- 1704,1710 ----
  1167. X    fcntl (inch, F_SETFL, O_NDELAY);
  1168. X  #endif
  1169. X  #endif
  1170. X+ #endif  /* not VMS */
  1171. X `20
  1172. X    XPROCESS (proc)->childp = host;
  1173. X    XPROCESS (proc)->command_channel_p = Qnil;
  1174. X***************
  1175. X*** 1448,1454 ****
  1176. X    XPROCESS (proc)->command = Qnil;
  1177. X    XPROCESS (proc)->pid = Qnil;
  1178. X    XPROCESS (proc)->kill_without_query = Qt;
  1179. X!   XFASTINT (XPROCESS (proc)->infd) = s;
  1180. X    XFASTINT (XPROCESS (proc)->outfd) = outch;
  1181. X    XPROCESS (proc)->status = Qrun;
  1182. X    FD_SET (inch, &input_wait_mask);
  1183. X--- 1714,1720 ----
  1184. X    XPROCESS (proc)->command = Qnil;
  1185. X    XPROCESS (proc)->pid = Qnil;
  1186. X    XPROCESS (proc)->kill_without_query = Qt;
  1187. X!   XFASTINT (XPROCESS (proc)->infd) = inch;
  1188. X    XFASTINT (XPROCESS (proc)->outfd) = outch;
  1189. X    XPROCESS (proc)->status = Qrun;
  1190. X    FD_SET (inch, &input_wait_mask);
  1191. X***************
  1192. X*** 1469,1479 ****
  1193. X--- 1735,1751 ----
  1194. X `20
  1195. X    if (inchannel)
  1196. X      `7B
  1197. X+ #ifdef VMS
  1198. X+       vms_close_fd (inchannel);
  1199. X+       if (outchannel != inchannel)
  1200. X+ `09vms_close_fd (outchannel);
  1201. X+ #else
  1202. X        /* Beware SIGCHLD hereabouts. */
  1203. X        flush_pending_output (inchannel);
  1204. X        close (inchannel);
  1205. X        if (outchannel  &&  outchannel != inchannel)
  1206. X   `09close (outchannel);
  1207. X+ #endif  /* not VMS */
  1208. X `20
  1209. X        XFASTINT (p->infd) = 0;
  1210. X        XFASTINT (p->outfd) = 0;
  1211. X***************
  1212. X*** 1488,1493 ****
  1213. X--- 1760,1766 ----
  1214. X `20
  1215. X  close_process_descs ()
  1216. X  `7B
  1217. X+ #ifndef VMS
  1218. X    int i;
  1219. X    for (i = 0; i < MAXDESC; i++)
  1220. X      `7B
  1221. X***************
  1222. X*** 1506,1511 ****
  1223. X--- 1779,1785 ----
  1224. X  `09    close (XFASTINT (XPROCESS (process)->subtty));
  1225. X  `09`7D
  1226. X      `7D
  1227. X+ #endif
  1228. X  `7D
  1229. X  `0C
  1230. X  DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_ou
  1231. Vtput,
  1232. X***************
  1233. X*** 1920,1925 ****
  1234. X--- 2194,2203 ----
  1235. X    register struct Lisp_Process *p = XPROCESS (proc);
  1236. X    register int opoint;
  1237. X `20
  1238. X+ #ifdef VMS
  1239. X+   nchars = vms_read_fd (channel, chars, sizeof chars,
  1240. X+ `09`09`09! NULL (XPROCESS (proc)->translate_p));
  1241. X+ #else
  1242. X    if (proc_buffered_char`5Bchannel`5D < 0)
  1243. X      nchars = read (channel, chars, sizeof chars);
  1244. X    else
  1245. X***************
  1246. X*** 1932,1937 ****
  1247. X--- 2210,2216 ----
  1248. X        else
  1249. X  `09nchars = nchars + 1;
  1250. X      `7D
  1251. X+ #endif  /* not VMS */
  1252. X `20
  1253. X    if (nchars <= 0) return nchars;
  1254. X `20
  1255. X***************
  1256. X*** 1993,1998 ****
  1257. X--- 2272,2278 ----
  1258. X `20
  1259. X  jmp_buf send_process_frame;
  1260. X `20
  1261. X+ #ifndef VMS
  1262. X  send_process_trap ()
  1263. X  `7B
  1264. X  #ifdef BSD4_1
  1265. X***************
  1266. X*** 2001,2006 ****
  1267. X--- 2281,2287 ----
  1268. X  #endif /* BSD4_1 */
  1269. X    longjmp (send_process_frame, 1);
  1270. X  `7D
  1271. X+ #endif  /* not VMS */
  1272. X `20
  1273. X  send_process (proc, buf, len)
  1274. X       Lisp_Object proc;
  1275. X***************
  1276. X*** 2019,2027 ****
  1277. X--- 2300,2313 ----
  1278. X    if (!setjmp (send_process_frame))
  1279. X      while (len > 0)
  1280. X        `7B
  1281. X+ #ifdef VMS
  1282. X+       rv = vms_write_fd (XFASTINT (XPROCESS (proc)->outfd), buf, len,
  1283. X+                          ! NULL (XPROCESS (proc)->translate_p) );
  1284. X+ #else
  1285. X  `09signal (SIGPIPE, send_process_trap);
  1286. X  `09rv = write (XFASTINT (XPROCESS (proc)->outfd), buf, len);
  1287. X  `09signal (SIGPIPE, SIG_DFL);
  1288. X+ #endif
  1289. X  `09if (rv < 0)
  1290. X  `09  `7B
  1291. X  `09    if (0
  1292. X***************
  1293. X*** 2123,2128 ****
  1294. X--- 2409,2417 ----
  1295. X      error ("Process %s is not active",
  1296. X  `09   XSTRING (p->name)->data);
  1297. X `20
  1298. X+ #ifdef VMS
  1299. X+   gid = MKPID(XFASTINT (p->pid), XFASTINT (p->hipid));
  1300. X+ #else
  1301. X    if (NULL (p->pty_flag))
  1302. X      current_group = Qnil;
  1303. X `20
  1304. X***************
  1305. X*** 2220,2225 ****
  1306. X--- 2509,2515 ----
  1307. X        kill (XFASTINT (p->pid), signo);
  1308. X        return;
  1309. X      `7D
  1310. X+ #endif  /* not VMS */
  1311. X `20
  1312. X    /* gid may be a pid, or minus a pgrp's number */
  1313. X  #ifdef TIOCSIGSEND
  1314. +-+-+-+-+-+-+-+-  END  OF PART 1 +-+-+-+-+-+-+-+-
  1315.