+void
+create_pty (process)
+ Lisp_Object process;
+{
+ int inchannel, outchannel;
+
+ /* Use volatile to protect variables from being clobbered by longjmp. */
+ volatile int forkin, forkout;
+ volatile int pty_flag = 0;
+
+ inchannel = outchannel = -1;
+
+#ifdef HAVE_PTYS
+ if (!NILP (Vprocess_connection_type))
+ outchannel = inchannel = allocate_pty ();
+
+ if (inchannel >= 0)
+ {
+#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
+ /* On most USG systems it does not work to open the pty's tty here,
+ then close it and reopen it in the child. */
+#ifdef O_NOCTTY
+ /* Don't let this terminal become our controlling terminal
+ (in case we don't have one). */
+ forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
+#else
+ forkout = forkin = emacs_open (pty_name, O_RDWR, 0);
+#endif
+ if (forkin < 0)
+ report_file_error ("Opening pty", Qnil);
+#if defined (RTU) || defined (UNIPLUS) || defined (DONT_REOPEN_PTY)
+ /* In the case that vfork is defined as fork, the parent process
+ (Emacs) may send some data before the child process completes
+ tty options setup. So we setup tty before forking. */
+ child_setup_tty (forkout);
+#endif /* RTU or UNIPLUS or DONT_REOPEN_PTY */
+#else
+ forkin = forkout = -1;
+#endif /* not USG, or USG_SUBTTY_WORKS */
+ pty_flag = 1;
+ }
+#endif /* HAVE_PTYS */
+
+#ifdef O_NONBLOCK
+ fcntl (inchannel, F_SETFL, O_NONBLOCK);
+ fcntl (outchannel, F_SETFL, O_NONBLOCK);
+#else
+#ifdef O_NDELAY
+ fcntl (inchannel, F_SETFL, O_NDELAY);
+ fcntl (outchannel, F_SETFL, O_NDELAY);
+#endif
+#endif
+
+ /* Record this as an active process, with its channels.
+ As a result, child_setup will close Emacs's side of the pipes. */
+ chan_process[inchannel] = process;
+ XPROCESS (process)->infd = inchannel;
+ XPROCESS (process)->outfd = outchannel;
+
+ /* Previously we recorded the tty descriptor used in the subprocess.
+ It was only used for getting the foreground tty process, so now
+ we just reopen the device (see emacs_get_tty_pgrp) as this is
+ more portable (see USG_SUBTTY_WORKS above). */
+
+ XPROCESS (process)->pty_flag = pty_flag;
+ XPROCESS (process)->status = Qrun;
+ setup_process_coding_systems (process);
+
+ FD_SET (inchannel, &input_wait_mask);
+ FD_SET (inchannel, &non_keyboard_wait_mask);
+ if (inchannel > max_process_desc)
+ max_process_desc = inchannel;
+
+ XPROCESS (process)->pid = -2;
+ XPROCESS (process)->tty_name = build_string (pty_name);
+}
+