home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / gnu / emacs / sources / 563 < prev    next >
Encoding:
Text File  |  1992-07-29  |  37.6 KB  |  1,399 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 (2/4)
  5. Message-ID: <920730000059.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:59 GMT
  10. Lines: 1387
  11.  
  12. -+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
  13. X***************
  14. X*** 2322,2327 ****
  15. X--- 2612,2620 ----
  16. X      write (XFASTINT (XPROCESS (proc)->outfd), buf, 0);
  17. X    `7D
  18. X  #else /* did not do TOICREMOTE */
  19. X+ #ifdef VMS
  20. X+   send_process (proc, "\004", 1);
  21. X+ #else
  22. X    if (!NULL (XPROCESS (proc)->pty_flag))
  23. X      send_process (proc, "\004", 1);
  24. X    else
  25. X***************
  26. X*** 2329,2334 ****
  27. X--- 2622,2628 ----
  28. X        close (XPROCESS (proc)->outfd);
  29. X        XFASTINT (XPROCESS (proc)->outfd) = open ("/dev/null", O_WRONLY);
  30. X      `7D
  31. X+ #endif /* not VMS */
  32. X `20
  33. X  #endif /* did not do TOICREMOTE */
  34. X    return process;
  35. X***************
  36. X*** 2357,2362 ****
  37. X--- 2651,2657 ----
  38. X      `7D
  39. X  `7D
  40. X  `0C
  41. X+ #ifndef VMS
  42. X  /* On receipt of a signal that a child status has changed,
  43. X   loop asking about children with changed statuses until
  44. X   the system says there are no more.
  45. X***************
  46. X*** 2498,2503 ****
  47. X--- 2793,2819 ----
  48. X  #endif /* USG, but not HPUX with WNOHANG */
  49. X      `7D
  50. X  `7D
  51. X+`20
  52. X+ #else /* VMS */
  53. X+`20
  54. X+ static void exit_ast (handle)
  55. X+ struct vms_process_handle *handle;
  56. X+ `7B
  57. X+   register struct Lisp_Process *p = handle->proc;
  58. X+   extern int process_ef;
  59. X+`20
  60. X+   if (p != (struct Lisp_Process *) (-1))
  61. X+     `7B
  62. X+       XFASTINT (p->raw_status_low) = handle->exit_status & 0xfff;
  63. X+       XFASTINT (p->raw_status_high) = handle->exit_status >> 16;
  64. X+       XSETINT (p->tick, ++process_tick);
  65. X+       FD_CLR (p->infd, &input_wait_mask);
  66. X+     `7D
  67. X+   handle->proc = 0;
  68. X+   sys$setef (process_ef);
  69. X+ `7D
  70. X+`20
  71. X+ #endif /* VMS */
  72. X  `0C
  73. X  /* Report all recent events of a change in process status
  74. X     (either run the sentinel or output a message).
  75. X***************
  76. X*** 2715,2720 ****
  77. X--- 3031,3040 ----
  78. X    defsubr (&Scontinue_process);
  79. X    defsubr (&Sprocess_send_eof);
  80. X    defsubr (&Swaiting_for_user_input_p);
  81. X+ #ifdef VMS
  82. X+   defsubr (&Sset_process_translation_mode);
  83. X+   defsubr (&Sprocess_translation_mode);
  84. X+ #endif
  85. X  `7D
  86. X `20
  87. X  #endif /* subprocesses */
  88. X*** process.h`09Tue Feb 25 11:59:19 1992
  89. X--- sb12:`5Bscratch.snyder.gnu.emacs-18_58.src`5Dprocess.h`09Mon May 18 22:5
  90. V1:52 1992
  91. X***************
  92. X*** 71,76 ****
  93. X--- 71,83 ----
  94. X      Lisp_Object tick;
  95. X      /* Event-count of last such event reported.  */
  96. X      Lisp_Object update_tick;
  97. X+ #ifdef VMS
  98. X+     /* VMS pids are 32 bits wide. store the upper 12 here. */
  99. X+     Lisp_Object hipid;
  100. X+     /* should we massage `5EM's, `5EJ's, etc. going to and from processes
  101. X+        so as to make things look more like unix? */
  102. X+     Lisp_Object translate_p;
  103. X+ #endif
  104. X  `7D;
  105. X `20
  106. X  #define ChannelMask(n) (1<<(n))
  107. X*** s-vms.h`09Tue Feb 25 11:59:23 1992
  108. X--- sb12:`5Bscratch.snyder.gnu.emacs-18_58.src`5Ds-vms.h`09Mon May 18 22:51:
  109. V58 1992
  110. X***************
  111. X*** 70,76 ****
  112. X `20
  113. X  /* Define HAVE_SOCKETS if system supports 4.2-compatible sockets.  */
  114. X `20
  115. X! /* #define HAVE_SOCKETS */
  116. X `20
  117. X  /*
  118. X   *`09Define NONSYSTEM_DIR_LIBRARY to make Emacs emulate
  119. X--- 70,76 ----
  120. X `20
  121. X  /* Define HAVE_SOCKETS if system supports 4.2-compatible sockets.  */
  122. X `20
  123. X! #define HAVE_SOCKETS
  124. X `20
  125. X  /*
  126. X   *`09Define NONSYSTEM_DIR_LIBRARY to make Emacs emulate
  127. X***************
  128. X*** 81,87 ****
  129. X `20
  130. X  /* Define this symbol if your system has the functions bcopy, etc. */
  131. X `20
  132. X! /* #define BSTRING */
  133. X `20
  134. X  /* subprocesses should be defined if you want to
  135. X     have code for asynchronous subprocesses
  136. X--- 81,89 ----
  137. X `20
  138. X  /* Define this symbol if your system has the functions bcopy, etc. */
  139. X `20
  140. X! #ifdef HAVE_SOCKETS
  141. X! # define BSTRING
  142. X! #endif
  143. X `20
  144. X  /* subprocesses should be defined if you want to
  145. X     have code for asynchronous subprocesses
  146. X***************
  147. X*** 89,95 ****
  148. X     This is generally OS dependent, and not supported
  149. X     under most USG systems. */
  150. X `20
  151. X! /* #define subprocesses */
  152. X `20
  153. X  /* If your system uses COFF (Common Object File Format) then define the
  154. X     preprocessor symbol "COFF". */
  155. X--- 91,97 ----
  156. X     This is generally OS dependent, and not supported
  157. X     under most USG systems. */
  158. X `20
  159. X! #define subprocesses
  160. X `20
  161. X  /* If your system uses COFF (Common Object File Format) then define the
  162. X     preprocessor symbol "COFF". */
  163. X***************
  164. X*** 159,164 ****
  165. X--- 161,169 ----
  166. X  #define rename sys_rename
  167. X  #define execvp sys_execvp
  168. X  #define system sys_system
  169. X+`20
  170. X+ /* select() is in the multinet socket library */
  171. X+ #define select sys_select
  172. X `20
  173. X  /* Hide these names so that we don't get linker errors */
  174. X  #define malloc sys_malloc
  175. X*** sysdep.c`09Tue Feb 25 11:59:25 1992
  176. X--- `5Bscratch.snyder.gnu.emacs-18_58.src`5Dsysdep.c`09Wed Jun 24 06:42:38 1
  177. V992
  178. X***************
  179. X*** 62,67 ****
  180. X--- 62,68 ----
  181. X  #endif
  182. X `20
  183. X  #ifdef VMS
  184. X+ #include <dcdef.h>
  185. X  #include <rms.h>
  186. X  #include <ttdef.h>
  187. X  #include <tt2def.h>
  188. X***************
  189. X*** 526,531 ****
  190. X--- 527,533 ----
  191. X  `7D
  192. X `20
  193. X  #ifdef subprocesses
  194. X+ #ifndef VMS
  195. X `20
  196. X  /*
  197. X   *`09flush any pending output
  198. X***************
  199. X*** 635,640 ****
  200. X--- 637,643 ----
  201. X  #endif /* RTU */
  202. X  `7D
  203. X `20
  204. X+ #endif /* not VMS */
  205. X  #endif /* subprocesses */
  206. X `20
  207. X  /*ARGSUSED*/
  208. X***************
  209. X*** 711,716 ****
  210. X--- 714,720 ----
  211. X    if (pid == 0)
  212. X      `7B
  213. X        char *sh;
  214. X+       extern char *egetenv();
  215. X `20
  216. X        sh = (char *) egetenv ("SHELL");
  217. X        if (sh == 0)
  218. X***************
  219. X*** 921,927 ****
  220. X    input_eflist = ((unsigned) 1 << (input_ef % 32)) `7C
  221. X      ((unsigned) 1 << (process_ef % 32));
  222. X    timer_eflist = ((unsigned) 1 << (input_ef % 32)) `7C
  223. X!     ((unsigned) 1 << (timer_ef % 32));
  224. X    SYS$QIOW (0, input_chan, IO$_SENSEMODE, &old_gtty, 0, 0,
  225. X  `09    &old_gtty.class, 12, 0, 0, 0, 0);
  226. X  #ifndef VMS4_4
  227. X--- 925,932 ----
  228. X    input_eflist = ((unsigned) 1 << (input_ef % 32)) `7C
  229. X      ((unsigned) 1 << (process_ef % 32));
  230. X    timer_eflist = ((unsigned) 1 << (input_ef % 32)) `7C
  231. X!     ((unsigned) 1 << (timer_ef % 32)) `7C
  232. X!     ((unsigned) 1 << (process_ef % 32));
  233. X    SYS$QIOW (0, input_chan, IO$_SENSEMODE, &old_gtty, 0, 0,
  234. X  `09    &old_gtty.class, 12, 0, 0, 0, 0);
  235. X  #ifndef VMS4_4
  236. X***************
  237. X*** 1399,1445 ****
  238. X    errno = old_errno;
  239. X  `7D
  240. X `20
  241. X- /* Wait until there is something in kbd_buffer.  */
  242. X-`20
  243. X- wait_for_kbd_input ()
  244. X- `7B
  245. X-   extern int have_process_input, process_exited;
  246. X-`20
  247. X-   /* If already something, avoid doing system calls.  */
  248. X-   if (detect_input_pending ())
  249. X-     `7B
  250. X-       return;
  251. X-     `7D
  252. X-   /* Clear a flag, and tell ast routine above to set it.  */
  253. X-   SYS$CLREF (input_ef);
  254. X-   waiting_for_ast = 1;
  255. X-   /* Check for timing error: ast happened while we were doing that.  */
  256. X-   if (!detect_input_pending ())
  257. X-     `7B
  258. X-       /* No timing error: wait for flag to be set.  */
  259. X-       set_waiting_for_input (0);
  260. X-       SYS$WFLOR (input_ef, input_eflist);
  261. X-       clear_waiting_for_input (0);
  262. X-       if (!detect_input_pending ())
  263. X- `09/* Check for subprocess input availability */
  264. X- `09`7B
  265. X- `09  int dsp = have_process_input `7C`7C process_exited;
  266. X-`20
  267. X- `09  sys$clref (process_ef);
  268. X- `09  if (have_process_input)
  269. X- `09    process_command_input ();
  270. X- `09  if (process_exited)
  271. X- `09    process_exit ();
  272. X- `09  if (dsp)
  273. X- `09    `7B
  274. X- `09      update_mode_lines++;
  275. X- `09      redisplay_preserve_echo_area ();
  276. X- `09    `7D
  277. X- `09`7D
  278. X-     `7D
  279. X-   waiting_for_ast = 0;
  280. X- `7D
  281. X-`20
  282. X  /* Get rid of any pending QIO, when we are about to suspend
  283. X     or when we want to throw away pending input.
  284. X     We wait for a positive sign that the AST routine has run
  285. X--- 1404,1409 ----
  286. X***************
  287. X*** 1686,1701 ****
  288. X    static char system_name_saved`5B32`5D;
  289. X  #ifdef VMS
  290. X    char *sp;
  291. X    if ((sp = egetenv ("SYS$NODE")) == 0)
  292. X      sp = "vax-vms";
  293. X-   else
  294. X-     `7B
  295. X-       char *end;
  296. X `20
  297. X!       if ((end = index (sp, ':')) != 0)
  298. X! `09*end = '\0';
  299. X!     `7D
  300. X!   strcpy (system_name_saved, sp);
  301. X  #else /* not VMS */
  302. X    gethostname (system_name_saved, sizeof (system_name_saved));
  303. X  #endif /* not VMS */
  304. X--- 1650,1672 ----
  305. X    static char system_name_saved`5B32`5D;
  306. X  #ifdef VMS
  307. X    char *sp;
  308. X+   extern char *egetenv ();
  309. X    if ((sp = egetenv ("SYS$NODE")) == 0)
  310. X      sp = "vax-vms";
  311. X `20
  312. X!   /* vms likes to stick a leading underscore in front of the node
  313. X!      name for some reason... */
  314. X!   if (*sp == '_') ++sp;
  315. X!   system_name_saved `5Bsizeof (system_name_saved) - 1`5D = '\0';
  316. X!   strncpy (system_name_saved, sp, sizeof (system_name_saved) - 1);
  317. X!`20
  318. X!   /* now hack off any trailing `60::' */
  319. X!   `7B
  320. X!     char *end;
  321. X!    `20
  322. X!     if ((end = index (system_name_saved, ':')) != 0)
  323. X!       *end = '\0';
  324. X!   `7D
  325. X  #else /* not VMS */
  326. X    gethostname (system_name_saved, sizeof (system_name_saved));
  327. X  #endif /* not VMS */
  328. X***************
  329. X*** 1705,1710 ****
  330. X--- 1676,1682 ----
  331. X  `7D
  332. X  `0C
  333. X  #ifndef HAVE_SELECT
  334. X+ #ifndef VMS   /* vms has its own select emulator */
  335. X `20
  336. X  /* Emulate as much as select as is possible under 4.1 and needed by Gnu Em
  337. Vacs
  338. X   * Only checks read descriptors.
  339. X***************
  340. X*** 1893,1898 ****
  341. X--- 1865,1871 ----
  342. X      `7D
  343. X  `7D
  344. X `20
  345. X+ #endif /* not VMS */
  346. X  #endif /* not HAVE_SELECT */
  347. X  `0C
  348. X  #ifdef BSD4_1
  349. X***************
  350. X*** 2187,2224 ****
  351. X     before attempting to translate the logical name TERM.  As a last
  352. X     resort, ask for VAX C's special idea of the TERM variable.  */
  353. X  #undef getenv
  354. X! char *
  355. X! sys_getenv (name)
  356. X!      char *name;
  357. X! `7B
  358. X!   register char *val;
  359. X!   static char buf`5B256`5D;
  360. X!   static struct dsc$descriptor_s equiv
  361. X!     = `7Bsizeof (buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf`7D;
  362. X!   static struct dsc$descriptor_s d_name
  363. X!     = `7B0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0`7D;
  364. X!   short eqlen;
  365. X `20
  366. X    if (!strcmp (name, "TERM"))
  367. X      `7B
  368. X!       val = (char *) getenv ("EMACS_TERM");
  369. X!       if (val)
  370. X! `09return val;
  371. X!     `7D
  372. X!`20
  373. X!   d_name.dsc$w_length = strlen (name);
  374. X!   d_name.dsc$a_pointer = name;
  375. X!   if (lib$sys_trnlog (&d_name, &eqlen, &equiv) == 1)
  376. X!     `7B
  377. X!       char *str = (char *) xmalloc (eqlen + 1);
  378. X!       bcopy (buf, str, eqlen);
  379. X!       str`5Beqlen`5D = '\0';
  380. X!       /* This is a storage leak, but a pain to fix.  With luck,
  381. X! `09 no one will ever notice.  */
  382. X!       return str;
  383. X      `7D
  384. X!   return (char *) getenv (name);
  385. X  `7D
  386. X  #endif /* getenv */
  387. X `20
  388. X  #ifdef abort
  389. X--- 2160,2271 ----
  390. X     before attempting to translate the logical name TERM.  As a last
  391. X     resort, ask for VAX C's special idea of the TERM variable.  */
  392. X  #undef getenv
  393. X!`20
  394. X! /* This variable is also reset in vmsmap.c.
  395. X!    This is because it gets saved in the dump file.  If we didn't do anythi
  396. Vng,
  397. X!    genenv() would then return the environment in effect when emacs was dum
  398. Vped
  399. X!    instead of the current environment.  So we reset it to NULL after mappi
  400. Vng
  401. X!    in a dump. */
  402. X! char **my_environ = NULL;
  403. X!`20
  404. X! /* The vax c getenv() can be a real pain to deal with.
  405. X!    It is hard to avoid leaking memory when using it.
  406. X!    In addition, it would occasionally accvio on me for no discernable reas
  407. Von.
  408. X!    The main motivation behind this sys_getenv is to call vax c's getenv()
  409. X!    as little as possible. */
  410. X!`20
  411. X! char *sys_getenv(char *name)
  412. X! `7B
  413. X!   extern char **environ;
  414. X!   extern char *getenv ();
  415. X!   static int n_slots_allocated, n_slots_used;
  416. X!   int namelen;
  417. X!   char **s, *reslt;
  418. X!   char resltbuf`5B257`5D;
  419. X!`20
  420. X!   if (my_environ == NULL)
  421. X!     `7B
  422. X!       my_environ = (char **) xmalloc (20 * sizeof (char *));
  423. X!       *my_environ = NULL;
  424. X!       n_slots_allocated = 20;
  425. X!       n_slots_used = 0;
  426. X!     `7D
  427. X!`20
  428. X!   /* try to find the name in our private database */
  429. X!   namelen = strlen (name);
  430. X!   for (s = my_environ; *s != NULL; ++s)
  431. X!     if (! strncmp (name, *s, namelen) && (*s)`5Bnamelen`5D == '=')
  432. X!       `7B
  433. X! `09if ((*s)`5Bnamelen+1`5D != '\0')
  434. X! `09  return *s + namelen + 1;
  435. X! `09else
  436. X! `09  return NULL;
  437. X!       `7D
  438. X `20
  439. X+   /* didn't find it - first try some standard synonyms... */
  440. X+   reslt = NULL;
  441. X    if (!strcmp (name, "TERM"))
  442. X      `7B
  443. X!       reslt = sys_getenv ("EMACS_TERM");
  444. X!     `7D
  445. X!   else if (!strcmp (name, "HOME"))
  446. X!     `7B
  447. X!       reslt = sys_getenv ("SYS$LOGIN");
  448. X!     `7D
  449. X!   else if (!strcmp (name, "TMP"))
  450. X!     `7B
  451. X!       reslt = sys_getenv ("SYS$SCRATCH");
  452. X!     `7D
  453. X!`20
  454. X!   /* no luck - try a logical name translation */
  455. X!   if (reslt == NULL)
  456. X!     `7B
  457. X!       struct dsc$descriptor_s name_dsc
  458. X! `09= `7Bnamelen, DSC$K_DTYPE_T, DSC$K_CLASS_S, name`7D;
  459. X!       $DESCRIPTOR (reslt_dsc, resltbuf);
  460. X!       short resltlen;
  461. X!`20
  462. X!       if (lib$sys_trnlog (&name_dsc, &resltlen, &reslt_dsc) == 1)
  463. X! `09`7B
  464. X! `09  reslt = resltbuf;
  465. X! `09  reslt`5Bresltlen`5D = '\0';
  466. X! `09`7D
  467. X!     `7D
  468. X!`20
  469. X!   /* look up special values of `60USER' and `60TERM' */
  470. X!   if (reslt == NULL &&
  471. X!       (!strcmp (name, "USER") `7C`7C !strcmp (name, "TERM")) &&
  472. X!       (int) environ >= 512)
  473. X!     reslt = getenv (name);
  474. X!`20
  475. X!   /* store what we've found in our private database... */
  476. X!   `7B
  477. X!     char *reslt1 = reslt;
  478. X!     char *entry;
  479. X!`20
  480. X!     if (reslt1 == NULL) reslt1 = "";
  481. X!     entry = (char *) xmalloc (namelen + 1 + strlen (reslt1) + 1);
  482. X!     strcpy (entry, name);
  483. X!     entry`5Bnamelen`5D = '=';
  484. X!     strcpy (entry+namelen+1, reslt1);
  485. X!`20
  486. X!     my_environ`5Bn_slots_used`5D = entry;
  487. X!     ++n_slots_used;
  488. X!`20
  489. X!     if (reslt != NULL) reslt = entry + namelen + 1;
  490. X!   `7D
  491. X!`20
  492. X!   if (n_slots_used == n_slots_allocated)
  493. X!     `7B
  494. X!       n_slots_allocated *= 2;
  495. X!       my_environ = (char **) xrealloc (my_environ,
  496. X! `09`09`09`09       n_slots_allocated * sizeof (char *));
  497. X      `7D
  498. X!   my_environ`5Bn_slots_used`5D = NULL;
  499. X!`20
  500. X!   return reslt;
  501. X  `7D
  502. X+`20
  503. X  #endif /* getenv */
  504. X `20
  505. X  #ifdef abort
  506. X***************
  507. X*** 2854,2859 ****
  508. X--- 2901,2907 ----
  509. X  #include <acldef.h>
  510. X  #include <chpdef.h>
  511. X  #include <jpidef.h>
  512. X+ #include <dvidef.h>
  513. X `20
  514. X  /* Return as a string the VMS error string pertaining to STATUS.
  515. X     Reuses the same static buffer each time it is called.  */
  516. X***************
  517. X*** 2914,2919 ****
  518. X--- 2962,2968 ----
  519. X  `7B
  520. X    static char *user = NULL;
  521. X    char dir_fn`5B512`5D;
  522. X+   extern char *getenv();
  523. X `20
  524. X    /* translate possible directory spec into .DIR file name, so brain-dead
  525. X     * access() can treat the directory like a file.  */
  526. X***************
  527. X*** 3250,3257 ****
  528. X       char *pathname;
  529. X  `7B
  530. X    char *ptr;
  531. X-   strcpy (pathname, egetenv ("PATH"));
  532. X `20
  533. X    ptr = pathname;
  534. X    while (*ptr)
  535. X      `7B
  536. X--- 3299,3306 ----
  537. X       char *pathname;
  538. X  `7B
  539. X    char *ptr;
  540. X `20
  541. X+   getcwd(pathname, 1025, 1);
  542. X    ptr = pathname;
  543. X    while (*ptr)
  544. X      `7B
  545. X***************
  546. X*** 3815,3820 ****
  547. X--- 3864,3870 ----
  548. X    unsigned char * full;
  549. X  #endif /* READ_SYSUAF */
  550. X    char *ptr = name;
  551. X+   extern char *egetenv();
  552. X `20
  553. X    while (*ptr)
  554. X      `7B
  555. X***************
  556. X*** 4146,4151 ****
  557. X--- 4196,5022 ----
  558. X  `7B
  559. X    srand (seed);
  560. X  `7D
  561. X+`20
  562. X+ /* support for unix-style asynchronous processes under VMS */
  563. X+`20
  564. X+ /* Subprocess I/O is done through `60pseudo-fd's, which can refer to
  565. X+    mailboxes, ptys, and network streams.  They are created by vms_pipe,
  566. X+    vms_make_pty, and vms_net_chan.  They are operated on by vms_read_fd,
  567. X+    vms_write_fd, and vms_close_fd.  They also can be passed to our select
  568. X+    emulator.  Pseudo-fd 0 always refers to the keyboard.
  569. X+`20
  570. X+    When a pseudo-fd is created, a read qio is queued to the channel.
  571. X+    When it completes, a flag is set in the structure for that fd, along
  572. X+    with a local event flag.  The select emulator watches that event flag
  573. X+    to know when to wake up.
  574. X+`20
  575. X+    Some of this code was borrowed from the old vmsfns.c...
  576. X+`20
  577. X+    - sss  (snyder@d0gsc.fnal.gov)  */
  578. X+`20
  579. X+`20
  580. X+ #define MAXDESC 32
  581. X+`20
  582. X+ #define       MSGSIZE 160             /* Maximum size for mailbox operatio
  583. Vns */
  584. X+`20
  585. X+ #ifdef HAVE_SOCKETS
  586. X+ #include "multinet_root:`5Bmultinet.include.vms`5Dinetiodef.h"
  587. X+ #include "multinet_root:`5Bmultinet.include.sys`5Dioctl.h"
  588. X+ #define NETBUFSIZ 1024
  589. X+ #endif
  590. X+`20
  591. X+ /* IO status block for mailbox operations.  */
  592. X+ struct mbx_iosb
  593. X+   `7B
  594. X+     short status;
  595. X+     short size;
  596. X+     int   pid;
  597. X+   `7D;
  598. X+`20
  599. X+`20
  600. X+ /* define the structure of the buffers used for communicating with the pty
  601. X+    driver.  each buffer is exactly one page long. */
  602. X+`20
  603. X+ #define PAGESIZE 512
  604. X+ #define PTYBUF_SIZE (PAGESIZE - 2*sizeof(short))
  605. X+ #define PTY_BUFFERS 2
  606. X+ #define PTY_READBUF 0
  607. X+`20
  608. X+ struct ptybuf
  609. X+   `7B
  610. X+     short stat;
  611. X+     short len;
  612. X+     char buf`5BPTYBUF_SIZE`5D;
  613. X+   `7D;
  614. X+`20
  615. X+`20
  616. X+ /* describe the state of one pseudo-fd */
  617. X+`20
  618. X+ struct vms_pseudo_fd
  619. X+   `7B
  620. X+     /* true if this pfd has been allocated */
  621. X+     int inuse : 1;
  622. X+`20
  623. X+     /* true if there is input in the buffer */
  624. X+     int input_avail : 1;
  625. X+`20
  626. X+     /* true for pty and network pfds, respectively */
  627. X+     int is_pty : 1;
  628. X+     int is_net : 1;
  629. X+`20
  630. X+     /* the vms i/o channel */
  631. X+     int chan;
  632. X+`20
  633. X+     /* i/o buffers and iosb's */
  634. X+     union
  635. X+       `7B
  636. X+ `09struct
  637. X+ `09  `7B
  638. X+ `09    int pty_lastlen`5BPTY_BUFFERS`5D;
  639. X+ `09    struct ptybuf *pty_buffers;
  640. X+ `09  `7D pty;
  641. X+`20
  642. X+ `09struct
  643. X+ `09  `7B
  644. X+ `09    char *mbx_buffer;
  645. X+ `09    struct mbx_iosb iosb;
  646. X+ `09  `7D mbx;
  647. X+`20
  648. X+ `09struct
  649. X+ `09  `7B
  650. X+ `09    char *net_buffer;
  651. X+ `09    struct mbx_iosb iosb;
  652. X+ `09  `7D net;
  653. X+       `7D a;
  654. X+   `7D;
  655. X+`20
  656. X+ /* accessor macros */
  657. X+`20
  658. X+ #define PTY_STRUCT(fdp, i) (&((fdp)->a.pty.pty_buffers`5Bi`5D))
  659. X+ #define PTY_BUF(fdp, i) (&((fdp)->a.pty.pty_buffers`5Bi`5D.buf`5B0`5D))
  660. X+ #define PTY_LEN(fdp, i) ((fdp)->a.pty.pty_buffers`5Bi`5D.len)
  661. X+ #define PTY_STAT(fdp, i) ((fdp)->a.pty.pty_buffers`5Bi`5D.stat)
  662. X+ #define PTY_LASTLEN(fdp, i) ((fdp)->a.pty.pty_lastlen`5Bi`5D)
  663. X+`20
  664. X+ #define MBX_BUF(fdp) ((fdp)->a.mbx.mbx_buffer)
  665. X+ #define MBX_IOSB(fdp) ((fdp)->a.mbx.iosb)
  666. X+`20
  667. X+ #define NET_BUF(fdp) ((fdp)->a.net.net_buffer)
  668. X+ #define NET_IOSB(fdp) ((fdp)->a.net.iosb)
  669. X+`20
  670. X+ /* the table of pds structs */
  671. X+ static struct vms_pseudo_fd vms_fd_tab`5BMAXDESC`5D = `7B`7B1`7D,`7B1`7D,`
  672. V7B1`7D`7D;
  673. X+`20
  674. X+ /* the select emulator for vms */
  675. X+`20
  676. X+ /*
  677. X+  * tests for input available on all channels given in the mask TEST_FDS.
  678. X+  * for all channels on which input is available, the corresponding bit is
  679. X+  * set in READY_FDS. the total number of ready channels is returned.
  680. X+  */
  681. X+`20
  682. X+ static int select_test (test_fds, ready_fds)
  683. X+      int test_fds, *ready_fds;
  684. X+ `7B
  685. X+   int fd;
  686. X+   int ravail = 0;
  687. X+`20
  688. X+   *ready_fds = 0;
  689. X+`20
  690. X+   /* pfd 0 always refers to the keyboard */
  691. X+   if (test_fds & 1)
  692. X+     if (detect_input_pending ())
  693. X+       `7B
  694. X+ `09*ready_fds `7C= 1;
  695. X+ `09++ravail;
  696. X+       `7D
  697. X+`20
  698. X+   for (fd=3; fd<MAXDESC; fd++)
  699. X+     if ((test_fds & (1<<fd)) && vms_fd_tab`5Bfd`5D.input_avail)
  700. X+       `7B
  701. X+ `09*ready_fds `7C= (1<<fd);
  702. X+ `09++ravail;
  703. X+       `7D
  704. X+`20
  705. X+   return ravail;
  706. X+ `7D
  707. X+`20
  708. X+ /* Emulate as much as select as is possible under vms and needed by Gnu Em
  709. Vacs
  710. X+  * Only checks read descriptors.
  711. X+  */
  712. X+`20
  713. X+ /* Only rfds are checked.  */
  714. X+ /* note that select is #defined as sys_select to avoid conflicting with
  715. X+    the multinet socketlib */
  716. X+ int
  717. X+ select (nfds, rfds, wfds, efds, timeout)
  718. X+      int nfds;
  719. X+      int *rfds, *wfds, *efds, *timeout;
  720. X+ `7B
  721. X+   int orfds = 0, ravail;
  722. X+   int timeoutval = timeout ? *timeout : 100000;
  723. X+   extern int process_tick, update_tick;
  724. X+   int time `5B2`5D;
  725. X+   int dum_10000000 = -10000000, dum_0 = 0;
  726. X+  `20
  727. X+   /* Convert to VMS format */
  728. X+   LIB$EMUL (&timeoutval, &dum_10000000, &dum_0, time);
  729. X+`20
  730. X+   if (rfds)
  731. X+     `7B
  732. X+       orfds = *rfds;
  733. X+       *rfds = 0;
  734. X+     `7D
  735. X+   if (wfds)
  736. X+     *wfds = 0;
  737. X+   if (efds)
  738. X+     *efds = 0;
  739. X+`20
  740. X+   if ((ravail = select_test (orfds, rfds)) != 0 `7C`7C timeoutval == 0)
  741. X+     return ravail;
  742. X+`20
  743. X+   /* Clear a flag, and tell ast routine above to set it.  */
  744. X+   SYS$CLREF (input_ef);
  745. X+   waiting_for_ast = 1;
  746. X+   /* Check for timing error: ast happened while we were doing that.  */
  747. X+   if ((ravail = select_test (orfds, rfds)) == 0)
  748. X+     `7B
  749. X+       int timed_out = 0;
  750. X+`20
  751. X+       /* No timing error: wait for flag to be set.  */
  752. X+       /* warning: the DEC C RTL uses timer 1 for alarm(). */
  753. X+       SYS$CANTIM (2, 0);
  754. X+       if (SYS$SETIMR (timer_ef, time, 0, 2) & 1) /* Set timer */
  755. X+ `09while (ravail == 0 && process_tick == update_tick && !timed_out)
  756. X+ `09  `7B
  757. X+ `09    int eflist;
  758. X+`20
  759. X+ `09    /* Wait for timer expiry or input */
  760. X+ `09    SYS$WFLOR (timer_ef, timer_eflist);
  761. X+ `09    sys$clref (process_ef);
  762. X+ `09    ravail = select_test (orfds, rfds);
  763. X+ `09    sys$readef (timer_ef, &eflist);
  764. X+ `09    timed_out = (eflist & ((unsigned) 1 << (timer_ef % 32)));
  765. X+ `09  `7D
  766. X+     `7D
  767. X+   waiting_for_ast = 0;
  768. X+  `20
  769. X+   return ravail;
  770. X+ `7D
  771. X+`20
  772. X+ /* the input AST function for pfd's.
  773. X+    set the input_avail flag in the pfd struct and set the local event
  774. X+    flag which the select emulator is waiting on. */
  775. X+`20
  776. X+ static void vms_input_ast (fdp)
  777. X+      struct vms_pseudo_fd *fdp;
  778. X+ `7B
  779. X+   fdp->input_avail = 1;
  780. X+   sys$setef (process_ef);
  781. X+ `7D
  782. X+`20
  783. X+ /* start input on the pfd described by the indicated slot. */
  784. X+ static void vms_start_input (fdp)
  785. X+      struct vms_pseudo_fd *fdp;
  786. X+ `7B
  787. X+   int status;
  788. X+`20
  789. X+   if (fdp->is_pty)
  790. X+     `7B
  791. X+ #ifdef HAVE_VMS_PTYS
  792. X+       status = ptd$read (process_ef, fdp->chan, vms_input_ast, fdp,
  793. X+ `09`09`09 PTY_STRUCT (fdp, PTY_READBUF), PTYBUF_SIZE);
  794. X+ #endif
  795. X+     `7D
  796. X+   else if (fdp->is_net)
  797. X+     `7B
  798. X+ #ifdef HAVE_SOCKETS
  799. X+       status = sys$qio(process_ef, fdp->chan, IO$_RECEIVE, &NET_IOSB (fdp)
  800. V,
  801. X+ `09`09       vms_input_ast, fdp, NET_BUF (fdp), NETBUFSIZ,
  802. X+ `09`09       0, 0, 0, 0);
  803. X+ #endif
  804. X+     `7D
  805. X+   else
  806. X+     `7B
  807. X+       status = sys$qio(process_ef, fdp->chan, IO$_READVBLK, &MBX_IOSB (fdp
  808. V),
  809. X+ `09`09       vms_input_ast, fdp, MBX_BUF (fdp), MSGSIZE,
  810. X+ `09`09       0, 0, 0, 0);
  811. X+     `7D
  812. X+   if (! (status & 1))
  813. X+     lib$signal (status);
  814. X+ `7D
  815. X+`20
  816. X+`20
  817. X+ /* functions for reading and writing pfds */
  818. X+`20
  819. X+ int vms_read_fd(fd, buf, len, translate)
  820. X+      int fd, len, translate;
  821. X+      char *buf;
  822. X+ `7B
  823. X+   struct vms_pseudo_fd *fdp = &vms_fd_tab`5Bfd`5D;
  824. X+   char *chars;
  825. X+   int nchars;
  826. X+`20
  827. X+   if (!fdp->inuse) abort();
  828. X+`20
  829. X+   /* return now if there's nothing to read */
  830. X+   if ( ! fdp->input_avail)
  831. X+     return 0;
  832. X+`20
  833. X+   /* reading from net streams */
  834. X+   if (fdp->is_net)
  835. X+     `7B
  836. X+       chars = NET_BUF (fdp);
  837. X+       nchars = NET_IOSB (fdp).size;
  838. X+       /* if nchars == 0 the connection has gone away?
  839. X+ `09 try returning 0 here so waiting_for_process_input will terminate
  840. X+ `09 the stream. */
  841. X+       if (nchars == 0) return 0;
  842. X+     `7D
  843. X+`20
  844. X+   /* reading from ptys */
  845. X+   else if (fdp->is_pty)
  846. X+     `7B
  847. X+       char *p;
  848. X+`20
  849. X+       chars = PTY_BUF (fdp, PTY_READBUF);
  850. X+       nchars = PTY_LEN (fdp, PTY_READBUF);
  851. X+`20
  852. X+       /* remove carriage returns and NUL's if translation is on */
  853. X+       if (translate)
  854. X+ `09for (p = chars; p < chars+nchars; p++)
  855. X+ `09  if (*p == '\r' `7C`7C *p == '\0')
  856. X+ `09    `7B
  857. X+ `09      --nchars;
  858. X+ `09      memcpy (p, p+1, nchars - (p-chars));
  859. X+ `09      --p;
  860. X+ `09    `7D
  861. X+     `7D
  862. X+`20
  863. X+   /* reading from mbxs */
  864. X+   else
  865. X+     `7B
  866. X+       chars = MBX_BUF (fdp);
  867. X+       nchars = MBX_IOSB (fdp).size;
  868. X+`20
  869. X+       /* Hack around VMS oddity of sending extraneous CR/LF characters for
  870. X+        * some of the commands (but not most). (if translation is on)
  871. X+        */
  872. X+       if (translate)
  873. X+ `09`7B
  874. X+ `09  if (nchars > 0 && *chars == '\r')
  875. X+ `09    `7B
  876. X+ `09      chars++;
  877. X+ `09      nchars--;
  878. X+ `09    `7D
  879. X+ `09  if (nchars > 0 && chars`5Bnchars - 1`5D == '\n')
  880. X+ `09    nchars--;
  881. X+ `09  if (nchars > 0 && chars`5Bnchars - 1`5D == '\r')
  882. X+ `09    nchars--;
  883. X+      `20
  884. X+ `09  /* add a newline onto the end */
  885. X+ `09  chars`5Bnchars++`5D = '\n';
  886. X+ `09`7D
  887. X+     `7D
  888. X+`20
  889. X+   /* copy the data to the output buffer */
  890. X+   if (nchars > len) nchars = len;
  891. X+   memcpy (buf, chars, nchars);
  892. X+`20
  893. X+   /* queue another read to the channel */
  894. X+   fdp->input_avail = 0;
  895. X+   vms_start_input (fdp);
  896. X+`20
  897. X+   /* we can't just return 0; if we do, wait_reading_process_input() will
  898. X+      think that the process has died.  so, do the following to fake it out
  899. V. */
  900. X+   if (nchars == 0)
  901. X+     `7B
  902. X+       nchars = -1;
  903. X+       errno = EWOULDBLOCK;
  904. X+     `7D
  905. X+`20
  906. X+   return nchars;
  907. X+ `7D
  908. X+`20
  909. X+ #ifdef HAVE_VMS_PTYS
  910. X+`20
  911. X+ static int vms_write_pty(fdp, buf, len, translate)
  912. X+      struct vms_pseudo_fd *fdp;
  913. X+      char *buf;
  914. X+      int len, translate;
  915. X+ `7B
  916. X+   int i, status;
  917. X+`20
  918. X+   /* we can't write more than PTYBUF_SIZE characters at once... */
  919. X+   if (len > PTYBUF_SIZE)
  920. X+     len = PTYBUF_SIZE;
  921. X+`20
  922. X+   /* find a free buffer */
  923. X+   for (i = 0; i < PTY_BUFFERS; i++)
  924. X+     if (i != PTY_READBUF && PTY_STAT (fdp, i) != 0)
  925. X+       break;
  926. X+`20
  927. X+   /* if we couldn't find one, return an error status with
  928. X+      errno = EWOULDBLOCK */
  929. X+   if (i >= PTY_BUFFERS)
  930. X+     `7B
  931. X+       errno = EWOULDBLOCK;
  932. X+       return -1;
  933. X+     `7D
  934. X+`20
  935. X+   /* if the previous write resulted in a data overrun error, requeue that
  936. X+      write, and return an EWOULDBLOCK error. */
  937. X+   if (PTY_STAT (fdp, i) == SS$_DATAOVERUN)
  938. X+     `7B
  939. X+       int j;
  940. X+`20
  941. X+       /* the number of characters that the last request tried to write
  942. X+ `09 is in PTY_LASTLEN(fdp, i).  the number of characters that were
  943. X+ `09 actually written is in PTY_LEN(fdp, i). */
  944. X+`20
  945. X+       len = PTY_LASTLEN (fdp, i) - PTY_LEN (fdp, i);
  946. X+       for (j=0; j<len; j++)
  947. X+ `09PTY_BUF (fdp, i)`5Bj`5D = PTY_BUF (fdp, i)`5Bj + PTY_LEN (fdp, i)`5D;
  948. X+       PTY_LASTLEN(fdp, i) = len;
  949. X+`20
  950. X+       ptd$write (fdp->chan, 0, 0, PTY_STRUCT (fdp, i), len, 0, 0);
  951. X+       errno = EWOULDBLOCK;
  952. X+       return -1;
  953. X+     `7D
  954. X+`20
  955. X+   /* copy the data to the pty buffer */
  956. X+   memcpy (PTY_BUF (fdp, i), buf, len);
  957. X+`20
  958. X+   if (translate)
  959. X+     `7B
  960. X+`20
  961. X+       /* if the buffer consists of the single character `5ED, change it to
  962. V `5EZ.
  963. X+ `09 also translate NL's to CR's */
  964. X+       if (len == 1 && PTY_BUF (fdp, i)`5B0`5D == '\004')
  965. X+ `09PTY_BUF (fdp, i)`5B0`5D = '\032';
  966. X+       else
  967. X+ `09`7B
  968. X+ `09  char *p;
  969. X+ `09  for (p = PTY_BUF (fdp, i); p < PTY_BUF (fdp, i) + len; p++)
  970. X+ `09    if (*p == '\n')
  971. X+ `09      *p = '\r';
  972. X+ `09`7D
  973. X+     `7D
  974. X+`20
  975. X+`20
  976. X+   /* que the write */
  977. X+   PTY_LASTLEN (fdp, i) = len;
  978. X+   status = ptd$write (fdp->chan, 0, 0, PTY_STRUCT (fdp, i), len, 0, 0);
  979. X+   if (! (status & 1))
  980. X+     return -1;
  981. X+`20
  982. X+   return len;
  983. X+ `7D
  984. X+`20
  985. X+ #endif
  986. X+`20
  987. X+ static int vms_write_mbx(fdp, buf, len, translate)
  988. X+      struct vms_pseudo_fd *fdp;
  989. X+      char *buf;
  990. X+      int len, translate;
  991. X+ `7B
  992. X+   int status, oldrwm;
  993. X+   int xlen = len;
  994. X+`20
  995. X+   /* turn off resource-wait mode to prevent blocking on a full mbx */
  996. X+   oldrwm = sys$setrwm(1);
  997. X+`20
  998. X+   /* as a special hack, if the buffer consists of the single character `5E
  999. VD,
  1000. X+      write EOF to the mailbox. */
  1001. X+`20
  1002. X+   if (len == 1 && buf`5B0`5D == '\004' && translate)
  1003. X+     status = sys$qiow (0, fdp->chan, IO$_WRITEOF `7C IO$M_NOW,
  1004. X+ `09`09       0, 0, 0, buf, xlen, 0, 0, 0, 0);
  1005. X+   else
  1006. X+     `7B
  1007. X+       /* strip trailing newlines if translation is on */
  1008. X+       if (xlen > 0 && buf`5Bxlen-1`5D == '\n' && translate)
  1009. X+ `09--xlen;
  1010. X+       status = sys$qiow (0, fdp->chan, IO$_WRITEVBLK `7C IO$M_NOW,
  1011. X+ `09`09`09 0, 0, 0, buf, xlen, 0, 0, 0, 0);
  1012. X+     `7D
  1013. X+`20
  1014. X+   /* restore the previous state of resource-waiting */
  1015. X+   if (oldrwm == SS$_WASCLR)
  1016. X+     sys$setrwm (0);
  1017. X+`20
  1018. X+   if (! (status & 1))
  1019. X+     `7B
  1020. X+       if (status = SS$_MBFULL)
  1021. X+ `09errno = EWOULDBLOCK;
  1022. X+       else
  1023. X+ `09errno = EVMSERR;
  1024. X+      `20
  1025. X+       return -1;
  1026. X+     `7D
  1027. X+`20
  1028. X+   return len;
  1029. X+ `7D
  1030. X+`20
  1031. X+ #ifdef HAVE_SOCKETS
  1032. X+`20
  1033. X+ static int vms_write_net(fdp, buf, len)
  1034. X+      struct vms_pseudo_fd *fdp;
  1035. X+      char *buf;
  1036. X+      int len;
  1037. X+ `7B
  1038. X+   extern int socket_errno;
  1039. X+   int status;
  1040. X+   int dum_0 = 0, dum_1 = 1;
  1041. X+`20
  1042. X+   /* turn on nonblocking mode */
  1043. X+   if (socket_ioctl (fdp->chan, FIONBIO, &dum_1) != 0)
  1044. X+     `7B
  1045. X+       errno = socket_errno;
  1046. X+       return -1;
  1047. X+     `7D
  1048. X+`20
  1049. X+   /* do the write */
  1050. X+   status = socket_write (fdp->chan, buf, len);
  1051. X+   if (status == -1) errno = socket_errno;
  1052. X+`20
  1053. X+   /* back to blocking mode so reads will work properly */
  1054. X+   if (socket_ioctl (fdp->chan, FIONBIO, &dum_0) != 0)
  1055. X+     `7B
  1056. X+       errno = socket_errno;
  1057. X+       return -1;
  1058. X+     `7D
  1059. X+`20
  1060. X+   return status;
  1061. X+ `7D
  1062. X+`20
  1063. X+ #endif
  1064. X+`20
  1065. X+ int vms_write_fd(fd, buf, len, translate)
  1066. X+      int fd, len, translate;
  1067. X+      char *buf;
  1068. X+ `7B
  1069. X+   struct vms_pseudo_fd *fdp = &vms_fd_tab`5Bfd`5D;
  1070. X+`20
  1071. X+   if (!fdp->inuse) abort ();
  1072. X+`20
  1073. X+   if (fdp->is_pty)
  1074. X+     `7B
  1075. X+ #ifdef HAVE_VMS_PTYS
  1076. X+       /* it's a pty */
  1077. X+       return vms_write_pty (fdp, buf, len, translate);
  1078. X+ #endif
  1079. X+     `7D
  1080. X+   else if (fdp->is_net)
  1081. X+     `7B
  1082. X+ #ifdef HAVE_SOCKETS
  1083. X+       /* it's a socket */
  1084. X+       return vms_write_net (fdp, buf, len);
  1085. X+ #endif
  1086. X+     `7D
  1087. X+   else
  1088. X+     `7B
  1089. X+       /* it's a mailbox */
  1090. X+       return vms_write_mbx (fdp, buf, len, translate);
  1091. X+     `7D
  1092. X+ `7D
  1093. X+`20
  1094. X+ /* close a pfd and free its buffers */
  1095. X+`20
  1096. X+ void vms_close_fd (fd)
  1097. X+      int fd;
  1098. X+ `7B
  1099. X+   int dum_PTY_BUFFERS = PTY_BUFFERS;
  1100. X+   struct vms_pseudo_fd *fdp = &vms_fd_tab`5Bfd`5D;
  1101. X+`20
  1102. X+   if ( ! fdp->inuse) abort ();
  1103. X+`20
  1104. X+   if (fdp->is_pty)
  1105. X+     `7B
  1106. X+ #ifdef HAVE_VMS_PTYS
  1107. X+       ptd$delete (fdp->chan);
  1108. X+       lib$free_vm_page (&dum_PTY_BUFFERS, &fdp->a.pty.pty_buffers);
  1109. X+ #endif
  1110. X+     `7D
  1111. X+   else if (fdp->is_net)
  1112. X+     `7B
  1113. X+ #ifdef HAVE_SOCKETS
  1114. X+       socket_close (fdp->chan);
  1115. X+       if (NET_BUF (fdp))
  1116. X+ `09`7B
  1117. X+ `09  free (NET_BUF (fdp));
  1118. X+ `09  NET_BUF (fdp) = 0;
  1119. X+ `09`7D
  1120. X+ #endif
  1121. X+     `7D
  1122. X+   else
  1123. X+     `7B
  1124. X+       sys$dassgn (fdp->chan);
  1125. X+       if (MBX_BUF (fdp))
  1126. X+ `09`7B
  1127. X+ `09  free (MBX_BUF (fdp));
  1128. X+ `09  MBX_BUF (fdp) = 0;
  1129. X+ `09`7D
  1130. X+     `7D
  1131. X+   fdp->inuse = 0;
  1132. X+   fdp->input_avail = 0;
  1133. X+ `7D
  1134. X+`20
  1135. X+ /* functions for creating pfds */
  1136. X+`20
  1137. X+ /* Creates a temporary mailbox and returns the channel in CHAN.
  1138. X+  * 'buffer_factor' is used to allow sending messages asynchronously
  1139. X+  * till some point.
  1140. X+  */
  1141. X+`20
  1142. X+ static int
  1143. X+ create_mbx (chan, buffer_factor)
  1144. X+      int *chan;
  1145. X+      int buffer_factor;
  1146. X+ `7B
  1147. X+   int status;
  1148. X+`20
  1149. X+   status = sys$crembx (0, chan, MSGSIZE, MSGSIZE * buffer_factor, 0, 0, 0)
  1150. V;
  1151. X+   if (! (status & 1))
  1152. X+     `7B
  1153. X+       message ("Unable to create mailbox.  Need TMPMBX privilege.");
  1154. X+       return 0;
  1155. X+     `7D
  1156. X+   return 1;
  1157. X+ `7D                             /* create_mbx */
  1158. X+`20
  1159. X+ void vms_get_device_name (fd, dsc)
  1160. X+      int fd;
  1161. X+      struct dsc$descriptor_s *dsc;
  1162. X+ `7B
  1163. X+   int status;
  1164. X+   short retlen;
  1165. X+   struct vms_pseudo_fd *fdp = &vms_fd_tab`5Bfd`5D;
  1166. X+   int dum_DVI$_DEVNAM = DVI$_DEVNAM;
  1167. X+`20
  1168. X+   if (!fdp->inuse)
  1169. X+     abort();
  1170. X+`20
  1171. X+   status = lib$getdvi (&dum_DVI$_DEVNAM, &fdp->chan, 0, 0, dsc,
  1172. X+ `09`09       &retlen);
  1173. X+   if (! (status & 1))
  1174. X+     lib$signal (status);
  1175. X+`20
  1176. X+   dsc->dsc$w_length = retlen;
  1177. X+ `7D
  1178. X+`20
  1179. X+ int vms_pipe (fds)
  1180. X+      int fds`5B2`5D;
  1181. X+ `7B
  1182. X+   int i, j;
  1183. X+   struct vms_pseudo_fd *fdp;
  1184. X+`20
  1185. X+   /* search vms_fd_tab for two free pseudo-fds; store their indices in FDS
  1186. V. */
  1187. X+   for (i=3, j=0; j<2 && i<MAXDESC; i++)
  1188. X+     if ( ! vms_fd_tab`5Bi`5D.inuse)
  1189. X+       fds`5Bj++`5D = i;
  1190. X+`20
  1191. X+   /* return an error status if we didn't find two free slots */
  1192. X+   if (j<2) return -1;
  1193. X+`20
  1194. X+   /* create the output mailbox */
  1195. X+   fdp = &vms_fd_tab`5Bfds`5B1`5D`5D;
  1196. X+   fdp->inuse = 1;
  1197. X+   fdp->is_pty = fdp->is_net = 0;
  1198. X+   if (! create_mbx (&fdp->chan, 2))
  1199. X+     return -1;
  1200. X+`20
  1201. X+   /* and the input mailbox */
  1202. X+   fdp = &vms_fd_tab`5Bfds`5B0`5D`5D;
  1203. X+   fdp->inuse = 1;
  1204. X+   fdp->is_pty = fdp->is_net = 0;
  1205. X+   MBX_BUF (fdp) = (char *) xmalloc (MSGSIZE+1);
  1206. X+   fdp->input_avail = 0;
  1207. X+   if (! create_mbx (&fdp->chan, 1))
  1208. X+     return -1;
  1209. X+   vms_start_input (fdp);
  1210. X+`20
  1211. X+   /* done! */
  1212. X+   return 0;
  1213. X+ `7D
  1214. X+`20
  1215. X+ #ifdef HAVE_VMS_PTYS
  1216. X+`20
  1217. X+ int vms_make_pty(fds)
  1218. X+      int fds`5B2`5D;
  1219. X+ `7B
  1220. X+   int i, status;
  1221. X+   struct vms_pseudo_fd *fdp;
  1222. X+   struct ptybuf *addarr`5B2`5D;
  1223. X+   struct
  1224. X+     `7B
  1225. X+       char class;
  1226. X+       char type;
  1227. X+       unsigned short scr_wid;
  1228. X+       unsigned long tt_char : 24, scr_len : 8;
  1229. X+       unsigned long tt2_char;
  1230. X+     `7D term_mode;
  1231. X+   int dum_PTY_BUFFERS = PTY_BUFFERS;
  1232. X+  `20
  1233. X+   /* search vms_fd_tab for a free pseudo-fd; store its index in FDS. */
  1234. X+   for (i=3; i<MAXDESC; i++)
  1235. X+     if (! vms_fd_tab`5Bi`5D.inuse)
  1236. X+       `7B
  1237. X+ `09fds`5B0`5D = fds`5B1`5D = i;
  1238. X+ `09break;
  1239. X+       `7D
  1240. X+`20
  1241. X+   fdp = &vms_fd_tab`5Bfds`5B1`5D`5D;
  1242. X+`20
  1243. X+   /* return an error status if we didn't find a free slot */
  1244. X+   if (i >= MAXDESC)
  1245. X+     return -1;
  1246. X+`20
  1247. X+   /* allocate some buffers for the pty */
  1248. X+   status = lib$get_vm_page (&dum_PTY_BUFFERS, &fdp->a.pty.pty_buffers);
  1249. X+   if (! (status & 1))
  1250. X+     return -1;
  1251. X+`20
  1252. X+   /* mark buffers as not busy */
  1253. X+   for (i=0; i<PTY_BUFFERS; i++)
  1254. X+     PTY_STAT(fdp, i) = 1;
  1255. X+`20
  1256. X+ #if 0
  1257. X+   /* get the current terminal characteristics */
  1258. X+   SYS$QIOW (0, input_chan, IO$_SENSEMODE, 0, 0, 0,
  1259. X+           &term_mode, sizeof(term_mode), 0, 0, 0, 0);
  1260. X+`20
  1261. X+   /* use those characteristics for the new pty, with the exception
  1262. X+      of pasthru.. */
  1263. X+   term_mode.tt2_char &= `7ETT2$M_PASTHRU;
  1264. X+ #endif
  1265. X+   term_mode.class = DC$_TERM;
  1266. X+   term_mode.type = TT$_UNKNOWN;
  1267. X+   term_mode.scr_wid = 511;
  1268. X+   term_mode.scr_len = 255;
  1269. X+   term_mode.tt_char = TT$M_ESCAPE `7C TT$M_LOWER `7C TT$M_MECHFORM `7C TT$
  1270. VM_NOECHO;
  1271. X+   term_mode.tt2_char = TT2$M_ALTYPEAHD;
  1272. X+`20
  1273. X+   /* create the pty */
  1274. X+   addarr`5B0`5D = fdp->a.pty.pty_buffers;
  1275. X+   addarr`5B1`5D = addarr`5B0`5D + PTY_BUFFERS;
  1276. X+   status = ptd$create (&fdp->chan, 0, &term_mode, sizeof (term_mode),
  1277. X+ `09`09       0, 0, 0, addarr);
  1278. X+   if (! (status & 1))
  1279. X+     return -1;
  1280. X+`20
  1281. X+   /* finish initializing and start the input */
  1282. X+   fdp->inuse = 1;
  1283. X+   fdp->is_pty = 1;
  1284. X+   fdp->is_net = 0;
  1285. X+   fdp->input_avail = 0;
  1286. X+   vms_start_input (fdp);
  1287. X+`20
  1288. X+   return 0;
  1289. X+ `7D
  1290. X+`20
  1291. X+ #endif
  1292. X+`20
  1293. X+ #ifdef HAVE_SOCKETS
  1294. X+`20
  1295. X+ int vms_net_chan(vms_chan, fds)
  1296. X+      int vms_chan;
  1297. X+      int fds`5B2`5D;
  1298. X+ `7B
  1299. X+   int i;
  1300. X+   struct vms_pseudo_fd *fdp;
  1301. X+`20
  1302. X+   /* search vms_fd_tab for a free pseudo-fd; store its index in FDS. */
  1303. X+   for (i=3; i<MAXDESC; i++)
  1304. X+     if (! vms_fd_tab`5Bi`5D.inuse)
  1305. X+       `7B
  1306. X+ `09fds`5B0`5D = fds`5B1`5D = i;
  1307. X+ `09break;
  1308. X+       `7D
  1309. X+`20
  1310. X+   /* return an error status if we didn't find a free slot */
  1311. X+   if (i >= MAXDESC)
  1312. X+     return -1;
  1313. X+`20
  1314. X+   fdp = &vms_fd_tab`5Bfds`5B1`5D`5D;
  1315. X+   fdp->inuse = 1;
  1316. X+   fdp->is_pty = 0;
  1317. X+   fdp->is_net = 1;
  1318. X+   fdp->chan = vms_chan;
  1319. X+`20
  1320. X+   NET_BUF (fdp) = (char *) xmalloc (NETBUFSIZ+1);
  1321. X+   fdp->input_avail = 0;
  1322. X+   vms_start_input (fdp);
  1323. X+`20
  1324. X+   /* done! */
  1325. X+   return 0;
  1326. X+ `7D
  1327. X+`20
  1328. X+ #endif
  1329. X+`20
  1330. X+`20
  1331. X+ /* emulate kill() for vms.
  1332. X+    for SIGINT, do a $forcex on the target.
  1333. X+    for SIGQUIT, SIGKILL, and SIGHUP, do a $delprc. */
  1334. X+`20
  1335. X+ kill(pid, signal)
  1336. X+      int pid, signal;
  1337. X+ `7B
  1338. X+   if (pid < 0) pid = -pid;
  1339. X+  `20
  1340. X+   switch (signal)
  1341. X+     `7B
  1342. X+     case SIGINT:
  1343. X+       sys$forcex (&pid, 0, SS$_FORCEDEXIT);
  1344. X+       break;
  1345. X+     case SIGQUIT:
  1346. X+     case SIGKILL:
  1347. X+     case SIGHUP:
  1348. X+       sys$delprc (&pid, 0);
  1349. X+       break;
  1350. X+     default:
  1351. X+       croak ("unimplemented kill signal");
  1352. X+     `7D
  1353. X+ `7D
  1354. X+`20
  1355. X+ char *sys_siglist`5BNSIG + 1`5D =
  1356. X+ `7B
  1357. X+   "bogus signal",                     /* 0 */
  1358. X+   "hangup",                           /* 1  SIGHUP */
  1359. X+   "interrupt",                                /* 2  SIGINT */
  1360. X+   "quit",                             /* 3  SIGQUIT */
  1361. X+   "illegal instruction",              /* 4  SIGILL */
  1362. X+   "trace trap",                               /* 5  SIGTRAP */
  1363. X+   "IOT instruction",                  /* 6  SIGIOT */
  1364. X+   "EMT instruction",                  /* 7  SIGEMT */
  1365. X+   "floating point exception",         /* 8  SIGFPE */
  1366. X+   "kill",                             /* 9  SIGKILL */
  1367. X+   "bus error",                                /* 10 SIGBUS */
  1368. X+   "segmentation violation",           /* 11 SIGSEGV */
  1369. X+   "bad argument to system call",      /* 12 SIGSYS */
  1370. X+   "write on a pipe with no one to read it", /* 13 SIGPIPE */
  1371. X+   "alarm clock",                      /* 14 SIGALRM */
  1372. X+   "software termination signum",      /* 15 SIGTERM */
  1373. X+   "bogus signal",                     /* 16 */
  1374. X+ #ifdef __GNUC__
  1375. X+   "bogus signal",                     /* 17 */
  1376. X+   "bogus signal",                     /* 18 */
  1377. X+   "bogus signal",                     /* 19 */
  1378. X+   "bogus signal",                     /* 20 */
  1379. X+   "bogus signal",                     /* 21 */
  1380. X+   "bogus signal",                     /* 22 */
  1381. X+   "bogus signal",                     /* 23 */
  1382. X+   "bogus signal",                     /* 24 */
  1383. X+   "bogus signal",                     /* 25 */
  1384. X+   "bogus signal",                     /* 26 */
  1385. X+   "bogus signal",                     /* 27 */
  1386. X+   "bogus signal",                     /* 28 */
  1387. X+   "bogus signal",                     /* 29 */
  1388. X+   "bogus signal",                     /* 30 */
  1389. X+   "bogus signal",                     /* 31 */
  1390. X+ #endif
  1391. X+   0 `7D;
  1392. X+`20
  1393. X  #endif /* VMS */
  1394. X  `0C
  1395. X  #ifdef WRONG_NAME_INSQUE
  1396. X*** temacs.opt`09Tue Feb 25 11:59:25 1992
  1397. X--- `5Bscratch.snyder.gnu.emacs-18_58.src`5Dtemacs.opt`09Thu Jul  2 17:36:01
  1398. +-+-+-+-+-+-+-+-  END  OF PART 2 +-+-+-+-+-+-+-+-
  1399.