aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorNick Roberts2009-08-13 13:22:55 +0000
committerNick Roberts2009-08-13 13:22:55 +0000
commit850d0752fb8ab02e3ffc80567578f9e9a4cb77f9 (patch)
treeabdfaa4a174ad4122539bcdd91de04ef20984c26 /src/process.c
parent79a1c8a97058e8542a2fdbe3aabc4c513b79e46f (diff)
downloademacs-850d0752fb8ab02e3ffc80567578f9e9a4cb77f9.tar.gz
emacs-850d0752fb8ab02e3ffc80567578f9e9a4cb77f9.zip
(create_pty): New function.
(Fstart_process): Use it to allow Emacs to just associate a pty with the buffer. See associated change in gdb-mi.el. (list_processes_1): Deal with no program name. (start_process_unwind): Use pid == -2 to mean no process.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c226
1 files changed, 158 insertions, 68 deletions
diff --git a/src/process.c b/src/process.c
index 5b8a940b183..15ed971b3e2 100644
--- a/src/process.c
+++ b/src/process.c
@@ -284,6 +284,7 @@ static int keyboard_bit_set P_ ((SELECT_TYPE *));
284static void deactivate_process P_ ((Lisp_Object)); 284static void deactivate_process P_ ((Lisp_Object));
285static void status_notify P_ ((struct Lisp_Process *)); 285static void status_notify P_ ((struct Lisp_Process *));
286static int read_process_output P_ ((Lisp_Object, int)); 286static int read_process_output P_ ((Lisp_Object, int));
287static void create_pty P_ ((Lisp_Object));
287 288
288/* If we support a window system, turn on the code to poll periodically 289/* If we support a window system, turn on the code to poll periodically
289 to detect C-g. It isn't actually used when doing interrupt input. */ 290 to detect C-g. It isn't actually used when doing interrupt input. */
@@ -1530,6 +1531,8 @@ list_processes_1 (query_only)
1530 while (1) 1531 while (1)
1531 { 1532 {
1532 tem1 = Fcar (tem); 1533 tem1 = Fcar (tem);
1534 if (NILP (tem1))
1535 break;
1533 Finsert (1, &tem1); 1536 Finsert (1, &tem1);
1534 tem = Fcdr (tem); 1537 tem = Fcdr (tem);
1535 if (NILP (tem)) 1538 if (NILP (tem))
@@ -1579,8 +1582,9 @@ at end of BUFFER, unless you specify an output stream or filter
1579function to handle the output. BUFFER may also be nil, meaning that 1582function to handle the output. BUFFER may also be nil, meaning that
1580this process is not associated with any buffer. 1583this process is not associated with any buffer.
1581 1584
1582PROGRAM is the program file name. It is searched for in PATH. 1585PROGRAM is the program file name. It is searched for in PATH. If
1583Remaining arguments are strings to give program as arguments. 1586nil, just associate a pty with the buffer. Remaining arguments are
1587strings to give program as arguments.
1584 1588
1585If you want to separate standard output from standard error, invoke 1589If you want to separate standard output from standard error, invoke
1586the command through a shell and redirect one of them using the shell 1590the command through a shell and redirect one of them using the shell
@@ -1634,7 +1638,8 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1634 1638
1635 program = args[2]; 1639 program = args[2];
1636 1640
1637 CHECK_STRING (program); 1641 if (!NILP (program))
1642 CHECK_STRING (program);
1638 1643
1639 proc = make_process (name); 1644 proc = make_process (name);
1640 /* If an error occurs and we can't start the process, we want to 1645 /* If an error occurs and we can't start the process, we want to
@@ -1680,7 +1685,8 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1680 args2[0] = Qstart_process; 1685 args2[0] = Qstart_process;
1681 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 1686 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
1682 GCPRO2 (proc, current_dir); 1687 GCPRO2 (proc, current_dir);
1683 coding_systems = Ffind_operation_coding_system (nargs + 1, args2); 1688 if (!NILP (program))
1689 coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
1684 UNGCPRO; 1690 UNGCPRO;
1685 if (CONSP (coding_systems)) 1691 if (CONSP (coding_systems))
1686 val = XCAR (coding_systems); 1692 val = XCAR (coding_systems);
@@ -1698,7 +1704,8 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1698 args2[0] = Qstart_process; 1704 args2[0] = Qstart_process;
1699 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 1705 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
1700 GCPRO2 (proc, current_dir); 1706 GCPRO2 (proc, current_dir);
1701 coding_systems = Ffind_operation_coding_system (nargs + 1, args2); 1707 if (!NILP (program))
1708 coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
1702 UNGCPRO; 1709 UNGCPRO;
1703 } 1710 }
1704 if (CONSP (coding_systems)) 1711 if (CONSP (coding_systems))
@@ -1709,80 +1716,86 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1709 XPROCESS (proc)->encode_coding_system = val; 1716 XPROCESS (proc)->encode_coding_system = val;
1710 } 1717 }
1711 1718
1712 /* If program file name is not absolute, search our path for it.
1713 Put the name we will really use in TEM. */
1714 if (!IS_DIRECTORY_SEP (SREF (program, 0))
1715 && !(SCHARS (program) > 1
1716 && IS_DEVICE_SEP (SREF (program, 1))))
1717 {
1718 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1719
1720 tem = Qnil;
1721 GCPRO4 (name, program, buffer, current_dir);
1722 openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK));
1723 UNGCPRO;
1724 if (NILP (tem))
1725 report_file_error ("Searching for program", Fcons (program, Qnil));
1726 tem = Fexpand_file_name (tem, Qnil);
1727 }
1728 else
1729 {
1730 if (!NILP (Ffile_directory_p (program)))
1731 error ("Specified program for new process is a directory");
1732 tem = program;
1733 }
1734 1719
1735 /* If program file name starts with /: for quoting a magic name, 1720 XPROCESS (proc)->decoding_buf = make_uninit_string (0);
1736 discard that. */ 1721 XPROCESS (proc)->decoding_carryover = 0;
1737 if (SBYTES (tem) > 2 && SREF (tem, 0) == '/' 1722 XPROCESS (proc)->encoding_buf = make_uninit_string (0);
1738 && SREF (tem, 1) == ':')
1739 tem = Fsubstring (tem, make_number (2), Qnil);
1740 1723
1741 { 1724 XPROCESS (proc)->inherit_coding_system_flag
1742 struct gcpro gcpro1; 1725 = !(NILP (buffer) || !inherit_process_coding_system);
1743 GCPRO1 (tem);
1744 1726
1745 /* Encode the file name and put it in NEW_ARGV. 1727 if (!NILP (program))
1746 That's where the child will use it to execute the program. */ 1728 {
1747 tem = Fcons (ENCODE_FILE (tem), Qnil); 1729 /* If program file name is not absolute, search our path for it.
1730 Put the name we will really use in TEM. */
1731 if (!IS_DIRECTORY_SEP (SREF (program, 0))
1732 && !(SCHARS (program) > 1
1733 && IS_DEVICE_SEP (SREF (program, 1))))
1734 {
1735 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1736
1737 tem = Qnil;
1738 GCPRO4 (name, program, buffer, current_dir);
1739 openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK));
1740 UNGCPRO;
1741 if (NILP (tem))
1742 report_file_error ("Searching for program", Fcons (program, Qnil));
1743 tem = Fexpand_file_name (tem, Qnil);
1744 }
1745 else
1746 {
1747 if (!NILP (Ffile_directory_p (program)))
1748 error ("Specified program for new process is a directory");
1749 tem = program;
1750 }
1748 1751
1749 /* Here we encode arguments by the coding system used for sending 1752 /* If program file name starts with /: for quoting a magic name,
1750 data to the process. We don't support using different coding 1753 discard that. */
1751 systems for encoding arguments and for encoding data sent to the 1754 if (SBYTES (tem) > 2 && SREF (tem, 0) == '/'
1752 process. */ 1755 && SREF (tem, 1) == ':')
1756 tem = Fsubstring (tem, make_number (2), Qnil);
1753 1757
1754 for (i = 3; i < nargs; i++)
1755 { 1758 {
1756 tem = Fcons (args[i], tem); 1759 struct gcpro gcpro1;
1757 CHECK_STRING (XCAR (tem)); 1760 GCPRO1 (tem);
1758 if (STRING_MULTIBYTE (XCAR (tem)))
1759 XSETCAR (tem,
1760 code_convert_string_norecord
1761 (XCAR (tem), XPROCESS (proc)->encode_coding_system, 1));
1762 }
1763 1761
1764 UNGCPRO; 1762 /* Encode the file name and put it in NEW_ARGV.
1765 } 1763 That's where the child will use it to execute the program. */
1764 tem = Fcons (ENCODE_FILE (tem), Qnil);
1766 1765
1767 /* Now that everything is encoded we can collect the strings into 1766 /* Here we encode arguments by the coding system used for sending
1768 NEW_ARGV. */ 1767 data to the process. We don't support using different coding
1769 new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); 1768 systems for encoding arguments and for encoding data sent to the
1770 new_argv[nargs - 2] = 0; 1769 process. */
1771 1770
1772 for (i = nargs - 3; i >= 0; i--) 1771 for (i = 3; i < nargs; i++)
1773 { 1772 {
1774 new_argv[i] = SDATA (XCAR (tem)); 1773 tem = Fcons (args[i], tem);
1775 tem = XCDR (tem); 1774 CHECK_STRING (XCAR (tem));
1776 } 1775 if (STRING_MULTIBYTE (XCAR (tem)))
1776 XSETCAR (tem,
1777 code_convert_string_norecord
1778 (XCAR (tem), XPROCESS (proc)->encode_coding_system, 1));
1779 }
1777 1780
1778 XPROCESS (proc)->decoding_buf = make_uninit_string (0); 1781 UNGCPRO;
1779 XPROCESS (proc)->decoding_carryover = 0; 1782 }
1780 XPROCESS (proc)->encoding_buf = make_uninit_string (0);
1781 1783
1782 XPROCESS (proc)->inherit_coding_system_flag 1784 /* Now that everything is encoded we can collect the strings into
1783 = !(NILP (buffer) || !inherit_process_coding_system); 1785 NEW_ARGV. */
1786 new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
1787 new_argv[nargs - 2] = 0;
1784 1788
1785 create_process (proc, (char **) new_argv, current_dir); 1789 for (i = nargs - 3; i >= 0; i--)
1790 {
1791 new_argv[i] = SDATA (XCAR (tem));
1792 tem = XCDR (tem);
1793 }
1794
1795 create_process (proc, (char **) new_argv, current_dir);
1796 }
1797 else
1798 create_pty (proc);
1786 1799
1787 return unbind_to (count, proc); 1800 return unbind_to (count, proc);
1788} 1801}
@@ -1799,7 +1812,7 @@ start_process_unwind (proc)
1799 abort (); 1812 abort ();
1800 1813
1801 /* Was PROC started successfully? */ 1814 /* Was PROC started successfully? */
1802 if (XPROCESS (proc)->pid <= 0) 1815 if (XPROCESS (proc)->pid == -1)
1803 remove_process (proc); 1816 remove_process (proc);
1804 1817
1805 return Qnil; 1818 return Qnil;
@@ -2268,6 +2281,83 @@ create_process (process, new_argv, current_dir)
2268 report_file_error ("Doing vfork", Qnil); 2281 report_file_error ("Doing vfork", Qnil);
2269} 2282}
2270 2283
2284void
2285create_pty (process)
2286 Lisp_Object process;
2287{
2288 int inchannel, outchannel;
2289
2290 /* Use volatile to protect variables from being clobbered by longjmp. */
2291 volatile int forkin, forkout;
2292 volatile int pty_flag = 0;
2293
2294 inchannel = outchannel = -1;
2295
2296#ifdef HAVE_PTYS
2297 if (!NILP (Vprocess_connection_type))
2298 outchannel = inchannel = allocate_pty ();
2299
2300 if (inchannel >= 0)
2301 {
2302#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
2303 /* On most USG systems it does not work to open the pty's tty here,
2304 then close it and reopen it in the child. */
2305#ifdef O_NOCTTY
2306 /* Don't let this terminal become our controlling terminal
2307 (in case we don't have one). */
2308 forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
2309#else
2310 forkout = forkin = emacs_open (pty_name, O_RDWR, 0);
2311#endif
2312 if (forkin < 0)
2313 report_file_error ("Opening pty", Qnil);
2314#if defined (RTU) || defined (UNIPLUS) || defined (DONT_REOPEN_PTY)
2315 /* In the case that vfork is defined as fork, the parent process
2316 (Emacs) may send some data before the child process completes
2317 tty options setup. So we setup tty before forking. */
2318 child_setup_tty (forkout);
2319#endif /* RTU or UNIPLUS or DONT_REOPEN_PTY */
2320#else
2321 forkin = forkout = -1;
2322#endif /* not USG, or USG_SUBTTY_WORKS */
2323 pty_flag = 1;
2324 }
2325#endif /* HAVE_PTYS */
2326
2327#ifdef O_NONBLOCK
2328 fcntl (inchannel, F_SETFL, O_NONBLOCK);
2329 fcntl (outchannel, F_SETFL, O_NONBLOCK);
2330#else
2331#ifdef O_NDELAY
2332 fcntl (inchannel, F_SETFL, O_NDELAY);
2333 fcntl (outchannel, F_SETFL, O_NDELAY);
2334#endif
2335#endif
2336
2337 /* Record this as an active process, with its channels.
2338 As a result, child_setup will close Emacs's side of the pipes. */
2339 chan_process[inchannel] = process;
2340 XPROCESS (process)->infd = inchannel;
2341 XPROCESS (process)->outfd = outchannel;
2342
2343 /* Previously we recorded the tty descriptor used in the subprocess.
2344 It was only used for getting the foreground tty process, so now
2345 we just reopen the device (see emacs_get_tty_pgrp) as this is
2346 more portable (see USG_SUBTTY_WORKS above). */
2347
2348 XPROCESS (process)->pty_flag = pty_flag;
2349 XPROCESS (process)->status = Qrun;
2350 setup_process_coding_systems (process);
2351
2352 FD_SET (inchannel, &input_wait_mask);
2353 FD_SET (inchannel, &non_keyboard_wait_mask);
2354 if (inchannel > max_process_desc)
2355 max_process_desc = inchannel;
2356
2357 XPROCESS (process)->pid = -2;
2358 XPROCESS (process)->tty_name = build_string (pty_name);
2359}
2360
2271 2361
2272#ifdef HAVE_SOCKETS 2362#ifdef HAVE_SOCKETS
2273 2363