diff options
| author | Daiki Ueno | 2015-03-23 12:40:29 +0900 |
|---|---|---|
| committer | Daiki Ueno | 2015-03-23 16:27:29 +0900 |
| commit | 47e0e319329a1ecf9da4fa1afd2b9f2738fada67 (patch) | |
| tree | 6260b8887776e71e448a62a707d6d15b5e3a1fcc /src/process.c | |
| parent | 165bea78008ec7545698f2e893821b4090f20c79 (diff) | |
| download | emacs-47e0e319329a1ecf9da4fa1afd2b9f2738fada67.tar.gz emacs-47e0e319329a1ecf9da4fa1afd2b9f2738fada67.zip | |
Generalize start-process with keyword args
* src/process.c (Fmake_process): New function.
(create_process, create_pty): Check p->pty_flag instead of
Vprocess_connection_type.
(syms_of_process): Register QCcommand, QCconnection_type, Qpty,
Qpipe, and Smake_process. Unregister Sstart_process.
* lisp/subr.el (start-process): New function, ported from the C
implementation.
* doc/lispref/processes.texi (Asynchronous Processes): Mention
`make-process'.
* etc/NEWS: Mention `make-process'.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 175 |
1 files changed, 132 insertions, 43 deletions
diff --git a/src/process.c b/src/process.c index 1d935ba8a3e..5abe7489d0d 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1355,34 +1355,63 @@ DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, | |||
| 1355 | 1355 | ||
| 1356 | static void start_process_unwind (Lisp_Object proc); | 1356 | static void start_process_unwind (Lisp_Object proc); |
| 1357 | 1357 | ||
| 1358 | DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, | 1358 | DEFUN ("make-process", Fmake_process, Smake_process, 0, MANY, 0, |
| 1359 | doc: /* Start a program in a subprocess. Return the process object for it. | 1359 | doc: /* Start a program in a subprocess. Return the process object for it. |
| 1360 | NAME is name for process. It is modified if necessary to make it unique. | ||
| 1361 | BUFFER is the buffer (or buffer name) to associate with the process. | ||
| 1362 | 1360 | ||
| 1363 | Process output (both standard output and standard error streams) goes | 1361 | This is similar to `start-process', but arguments are specified as |
| 1364 | at end of BUFFER, unless you specify an output stream or filter | 1362 | keyword/argument pairs. The following arguments are defined: |
| 1365 | function to handle the output. BUFFER may also be nil, meaning that | ||
| 1366 | this process is not associated with any buffer. | ||
| 1367 | 1363 | ||
| 1368 | PROGRAM is the program file name. It is searched for in `exec-path' | 1364 | :name NAME -- NAME is name for process. It is modified if necessary |
| 1369 | (which see). If nil, just associate a pty with the buffer. Remaining | 1365 | to make it unique. |
| 1370 | arguments are strings to give program as arguments. | 1366 | |
| 1367 | :buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate | ||
| 1368 | with the process. Process output goes at end of that buffer, unless | ||
| 1369 | you specify an output stream or filter function to handle the output. | ||
| 1370 | BUFFER may be also nil, meaning that this process is not associated | ||
| 1371 | with any buffer. | ||
| 1371 | 1372 | ||
| 1372 | If you want to separate standard output from standard error, invoke | 1373 | :command COMMAND -- COMMAND is a list starting with the program file |
| 1373 | the command through a shell and redirect one of them using the shell | 1374 | name, followed by strings to give to the program as arguments. |
| 1374 | syntax. | 1375 | |
| 1376 | :coding CODING -- If CODING is a symbol, it specifies the coding | ||
| 1377 | system used for both reading and writing for this process. If CODING | ||
| 1378 | is a cons (DECODING . ENCODING), DECODING is used for reading, and | ||
| 1379 | ENCODING is used for writing. | ||
| 1380 | |||
| 1381 | :noquery BOOL -- When exiting Emacs, query the user if BOOL is nil and | ||
| 1382 | the process is running. If BOOL is not given, query before exiting. | ||
| 1375 | 1383 | ||
| 1376 | usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | 1384 | :stop BOOL -- Start process in the `stopped' state if BOOL non-nil. |
| 1385 | In the stopped state, a process does not accept incoming data, but you | ||
| 1386 | can send outgoing data. The stopped state is cleared by | ||
| 1387 | `continue-process' and set by `stop-process'. | ||
| 1388 | |||
| 1389 | :connection-type TYPE -- TYPE is control type of device used to | ||
| 1390 | communicate with subprocesses. Values are `pipe' to use a pipe, `pty' | ||
| 1391 | to use a pty, or nil to use the default specified through | ||
| 1392 | `process-connection-type'. | ||
| 1393 | |||
| 1394 | :filter FILTER -- Install FILTER as the process filter. | ||
| 1395 | |||
| 1396 | :sentinel SENTINEL -- Install SENTINEL as the process sentinel. | ||
| 1397 | |||
| 1398 | usage: (make-process &rest ARGS) */) | ||
| 1377 | (ptrdiff_t nargs, Lisp_Object *args) | 1399 | (ptrdiff_t nargs, Lisp_Object *args) |
| 1378 | { | 1400 | { |
| 1379 | Lisp_Object buffer, name, program, proc, current_dir, tem; | 1401 | Lisp_Object buffer, name, command, program, proc, contact, current_dir, tem; |
| 1380 | unsigned char **new_argv; | ||
| 1381 | ptrdiff_t i; | 1402 | ptrdiff_t i; |
| 1382 | ptrdiff_t count = SPECPDL_INDEX (); | 1403 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1404 | struct gcpro gcpro1; | ||
| 1383 | USE_SAFE_ALLOCA; | 1405 | USE_SAFE_ALLOCA; |
| 1384 | 1406 | ||
| 1385 | buffer = args[1]; | 1407 | if (nargs == 0) |
| 1408 | return Qnil; | ||
| 1409 | |||
| 1410 | /* Save arguments for process-contact and clone-process. */ | ||
| 1411 | contact = Flist (nargs, args); | ||
| 1412 | GCPRO1 (contact); | ||
| 1413 | |||
| 1414 | buffer = Fplist_get (contact, QCbuffer); | ||
| 1386 | if (!NILP (buffer)) | 1415 | if (!NILP (buffer)) |
| 1387 | buffer = Fget_buffer_create (buffer); | 1416 | buffer = Fget_buffer_create (buffer); |
| 1388 | 1417 | ||
| @@ -1402,10 +1431,14 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1402 | UNGCPRO; | 1431 | UNGCPRO; |
| 1403 | } | 1432 | } |
| 1404 | 1433 | ||
| 1405 | name = args[0]; | 1434 | name = Fplist_get (contact, QCname); |
| 1406 | CHECK_STRING (name); | 1435 | CHECK_STRING (name); |
| 1407 | 1436 | ||
| 1408 | program = args[2]; | 1437 | command = Fplist_get (contact, QCcommand); |
| 1438 | if (CONSP (command)) | ||
| 1439 | program = XCAR (command); | ||
| 1440 | else | ||
| 1441 | program = Qnil; | ||
| 1409 | 1442 | ||
| 1410 | if (!NILP (program)) | 1443 | if (!NILP (program)) |
| 1411 | CHECK_STRING (program); | 1444 | CHECK_STRING (program); |
| @@ -1423,7 +1456,22 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1423 | pset_buffer (XPROCESS (proc), buffer); | 1456 | pset_buffer (XPROCESS (proc), buffer); |
| 1424 | pset_sentinel (XPROCESS (proc), Qinternal_default_process_sentinel); | 1457 | pset_sentinel (XPROCESS (proc), Qinternal_default_process_sentinel); |
| 1425 | pset_filter (XPROCESS (proc), Qinternal_default_process_filter); | 1458 | pset_filter (XPROCESS (proc), Qinternal_default_process_filter); |
| 1426 | pset_command (XPROCESS (proc), Flist (nargs - 2, args + 2)); | 1459 | pset_command (XPROCESS (proc), Fcopy_sequence (command)); |
| 1460 | |||
| 1461 | if (tem = Fplist_get (contact, QCnoquery), !NILP (tem)) | ||
| 1462 | XPROCESS (proc)->kill_without_query = 1; | ||
| 1463 | if (tem = Fplist_get (contact, QCstop), !NILP (tem)) | ||
| 1464 | pset_command (XPROCESS (proc), Qt); | ||
| 1465 | |||
| 1466 | tem = Fplist_get (contact, QCconnection_type); | ||
| 1467 | if (EQ (tem, Qpty)) | ||
| 1468 | XPROCESS (proc)->pty_flag = true; | ||
| 1469 | else if (EQ (tem, Qpipe)) | ||
| 1470 | XPROCESS (proc)->pty_flag = false; | ||
| 1471 | else if (NILP (tem)) | ||
| 1472 | XPROCESS (proc)->pty_flag = !NILP (Vprocess_connection_type); | ||
| 1473 | else | ||
| 1474 | report_file_error ("Unknown connection type", tem); | ||
| 1427 | 1475 | ||
| 1428 | #ifdef HAVE_GNUTLS | 1476 | #ifdef HAVE_GNUTLS |
| 1429 | /* AKA GNUTLS_INITSTAGE(proc). */ | 1477 | /* AKA GNUTLS_INITSTAGE(proc). */ |
| @@ -1453,15 +1501,29 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1453 | Lisp_Object val, *args2; | 1501 | Lisp_Object val, *args2; |
| 1454 | struct gcpro gcpro1, gcpro2; | 1502 | struct gcpro gcpro1, gcpro2; |
| 1455 | 1503 | ||
| 1456 | val = Vcoding_system_for_read; | 1504 | tem = Fplist_get (contact, QCcoding); |
| 1505 | if (!NILP (tem)) | ||
| 1506 | { | ||
| 1507 | val = tem; | ||
| 1508 | if (CONSP (val)) | ||
| 1509 | val = XCAR (val); | ||
| 1510 | } | ||
| 1511 | else | ||
| 1512 | val = Vcoding_system_for_read; | ||
| 1457 | if (NILP (val)) | 1513 | if (NILP (val)) |
| 1458 | { | 1514 | { |
| 1459 | SAFE_ALLOCA_LISP (args2, nargs + 1); | 1515 | ptrdiff_t nargs2 = 3 + XINT (Flength (command)); |
| 1460 | args2[0] = Qstart_process; | 1516 | Lisp_Object tem2; |
| 1461 | for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; | 1517 | SAFE_ALLOCA_LISP (args2, nargs2); |
| 1518 | i = 0; | ||
| 1519 | args2[i++] = Qstart_process; | ||
| 1520 | args2[i++] = name; | ||
| 1521 | args2[i++] = buffer; | ||
| 1522 | for (tem2 = command; CONSP (tem2); tem2 = XCDR (tem2)) | ||
| 1523 | args2[i++] = XCAR (tem2); | ||
| 1462 | GCPRO2 (proc, current_dir); | 1524 | GCPRO2 (proc, current_dir); |
| 1463 | if (!NILP (program)) | 1525 | if (!NILP (program)) |
| 1464 | coding_systems = Ffind_operation_coding_system (nargs + 1, args2); | 1526 | coding_systems = Ffind_operation_coding_system (nargs2, args2); |
| 1465 | UNGCPRO; | 1527 | UNGCPRO; |
| 1466 | if (CONSP (coding_systems)) | 1528 | if (CONSP (coding_systems)) |
| 1467 | val = XCAR (coding_systems); | 1529 | val = XCAR (coding_systems); |
| @@ -1470,17 +1532,30 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1470 | } | 1532 | } |
| 1471 | pset_decode_coding_system (XPROCESS (proc), val); | 1533 | pset_decode_coding_system (XPROCESS (proc), val); |
| 1472 | 1534 | ||
| 1473 | val = Vcoding_system_for_write; | 1535 | if (!NILP (tem)) |
| 1536 | { | ||
| 1537 | val = tem; | ||
| 1538 | if (CONSP (val)) | ||
| 1539 | val = XCDR (val); | ||
| 1540 | } | ||
| 1541 | else | ||
| 1542 | val = Vcoding_system_for_write; | ||
| 1474 | if (NILP (val)) | 1543 | if (NILP (val)) |
| 1475 | { | 1544 | { |
| 1476 | if (EQ (coding_systems, Qt)) | 1545 | if (EQ (coding_systems, Qt)) |
| 1477 | { | 1546 | { |
| 1478 | SAFE_ALLOCA_LISP (args2, nargs + 1); | 1547 | ptrdiff_t nargs2 = 3 + XINT (Flength (command)); |
| 1479 | args2[0] = Qstart_process; | 1548 | Lisp_Object tem2; |
| 1480 | for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; | 1549 | SAFE_ALLOCA_LISP (args2, nargs2); |
| 1550 | i = 0; | ||
| 1551 | args2[i++] = Qstart_process; | ||
| 1552 | args2[i++] = name; | ||
| 1553 | args2[i++] = buffer; | ||
| 1554 | for (tem2 = command; CONSP (tem2); tem2 = XCDR (tem2)) | ||
| 1555 | args2[i++] = XCAR (tem2); | ||
| 1481 | GCPRO2 (proc, current_dir); | 1556 | GCPRO2 (proc, current_dir); |
| 1482 | if (!NILP (program)) | 1557 | if (!NILP (program)) |
| 1483 | coding_systems = Ffind_operation_coding_system (nargs + 1, args2); | 1558 | coding_systems = Ffind_operation_coding_system (nargs2, args2); |
| 1484 | UNGCPRO; | 1559 | UNGCPRO; |
| 1485 | } | 1560 | } |
| 1486 | if (CONSP (coding_systems)) | 1561 | if (CONSP (coding_systems)) |
| @@ -1506,16 +1581,20 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1506 | 1581 | ||
| 1507 | if (!NILP (program)) | 1582 | if (!NILP (program)) |
| 1508 | { | 1583 | { |
| 1584 | Lisp_Object program_args = XCDR (command); | ||
| 1585 | unsigned char **new_argv; | ||
| 1586 | ptrdiff_t new_argc; | ||
| 1587 | |||
| 1509 | /* If program file name is not absolute, search our path for it. | 1588 | /* If program file name is not absolute, search our path for it. |
| 1510 | Put the name we will really use in TEM. */ | 1589 | Put the name we will really use in TEM. */ |
| 1511 | if (!IS_DIRECTORY_SEP (SREF (program, 0)) | 1590 | if (!IS_DIRECTORY_SEP (SREF (program, 0)) |
| 1512 | && !(SCHARS (program) > 1 | 1591 | && !(SCHARS (program) > 1 |
| 1513 | && IS_DEVICE_SEP (SREF (program, 1)))) | 1592 | && IS_DEVICE_SEP (SREF (program, 1)))) |
| 1514 | { | 1593 | { |
| 1515 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 1594 | struct gcpro gcpro1, gcpro2; |
| 1516 | 1595 | ||
| 1517 | tem = Qnil; | 1596 | tem = Qnil; |
| 1518 | GCPRO4 (name, program, buffer, current_dir); | 1597 | GCPRO2 (buffer, current_dir); |
| 1519 | openp (Vexec_path, program, Vexec_suffixes, &tem, | 1598 | openp (Vexec_path, program, Vexec_suffixes, &tem, |
| 1520 | make_number (X_OK), false); | 1599 | make_number (X_OK), false); |
| 1521 | UNGCPRO; | 1600 | UNGCPRO; |
| @@ -1534,7 +1613,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1534 | tem = remove_slash_colon (tem); | 1613 | tem = remove_slash_colon (tem); |
| 1535 | 1614 | ||
| 1536 | { | 1615 | { |
| 1537 | Lisp_Object arg_encoding = Qnil; | 1616 | Lisp_Object arg_encoding = Qnil, tem2; |
| 1538 | struct gcpro gcpro1; | 1617 | struct gcpro gcpro1; |
| 1539 | GCPRO1 (tem); | 1618 | GCPRO1 (tem); |
| 1540 | 1619 | ||
| @@ -1547,9 +1626,9 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1547 | systems for encoding arguments and for encoding data sent to the | 1626 | systems for encoding arguments and for encoding data sent to the |
| 1548 | process. */ | 1627 | process. */ |
| 1549 | 1628 | ||
| 1550 | for (i = 3; i < nargs; i++) | 1629 | for (tem2 = program_args; CONSP (tem2); tem2 = XCDR (tem2)) |
| 1551 | { | 1630 | { |
| 1552 | tem = Fcons (args[i], tem); | 1631 | tem = Fcons (XCAR (tem2), tem); |
| 1553 | CHECK_STRING (XCAR (tem)); | 1632 | CHECK_STRING (XCAR (tem)); |
| 1554 | if (STRING_MULTIBYTE (XCAR (tem))) | 1633 | if (STRING_MULTIBYTE (XCAR (tem))) |
| 1555 | { | 1634 | { |
| @@ -1567,10 +1646,11 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1567 | 1646 | ||
| 1568 | /* Now that everything is encoded we can collect the strings into | 1647 | /* Now that everything is encoded we can collect the strings into |
| 1569 | NEW_ARGV. */ | 1648 | NEW_ARGV. */ |
| 1570 | SAFE_NALLOCA (new_argv, 1, nargs - 1); | 1649 | new_argc = XINT (Flength (tem)); |
| 1571 | new_argv[nargs - 2] = 0; | 1650 | SAFE_NALLOCA (new_argv, 1, new_argc + 1); |
| 1651 | new_argv[new_argc] = 0; | ||
| 1572 | 1652 | ||
| 1573 | for (i = nargs - 2; i-- != 0; ) | 1653 | for (i = new_argc - 1; i >= 0; i--) |
| 1574 | { | 1654 | { |
| 1575 | new_argv[i] = SDATA (XCAR (tem)); | 1655 | new_argv[i] = SDATA (XCAR (tem)); |
| 1576 | tem = XCDR (tem); | 1656 | tem = XCDR (tem); |
| @@ -1581,6 +1661,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1581 | else | 1661 | else |
| 1582 | create_pty (proc); | 1662 | create_pty (proc); |
| 1583 | 1663 | ||
| 1664 | UNGCPRO; | ||
| 1584 | SAFE_FREE (); | 1665 | SAFE_FREE (); |
| 1585 | return unbind_to (count, proc); | 1666 | return unbind_to (count, proc); |
| 1586 | } | 1667 | } |
| @@ -1648,7 +1729,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1648 | 1729 | ||
| 1649 | inchannel = outchannel = -1; | 1730 | inchannel = outchannel = -1; |
| 1650 | 1731 | ||
| 1651 | if (!NILP (Vprocess_connection_type)) | 1732 | if (p->pty_flag) |
| 1652 | outchannel = inchannel = allocate_pty (pty_name); | 1733 | outchannel = inchannel = allocate_pty (pty_name); |
| 1653 | 1734 | ||
| 1654 | if (inchannel >= 0) | 1735 | if (inchannel >= 0) |
| @@ -1701,8 +1782,12 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1701 | p->pty_flag = pty_flag; | 1782 | p->pty_flag = pty_flag; |
| 1702 | pset_status (p, Qrun); | 1783 | pset_status (p, Qrun); |
| 1703 | 1784 | ||
| 1704 | FD_SET (inchannel, &input_wait_mask); | 1785 | if (!EQ (p->command, Qt)) |
| 1705 | FD_SET (inchannel, &non_keyboard_wait_mask); | 1786 | { |
| 1787 | FD_SET (inchannel, &input_wait_mask); | ||
| 1788 | FD_SET (inchannel, &non_keyboard_wait_mask); | ||
| 1789 | } | ||
| 1790 | |||
| 1706 | if (inchannel > max_process_desc) | 1791 | if (inchannel > max_process_desc) |
| 1707 | max_process_desc = inchannel; | 1792 | max_process_desc = inchannel; |
| 1708 | 1793 | ||
| @@ -1894,7 +1979,7 @@ create_pty (Lisp_Object process) | |||
| 1894 | { | 1979 | { |
| 1895 | struct Lisp_Process *p = XPROCESS (process); | 1980 | struct Lisp_Process *p = XPROCESS (process); |
| 1896 | char pty_name[PTY_NAME_SIZE]; | 1981 | char pty_name[PTY_NAME_SIZE]; |
| 1897 | int pty_fd = NILP (Vprocess_connection_type) ? -1 : allocate_pty (pty_name); | 1982 | int pty_fd = !p->pty_flag ? -1 : allocate_pty (pty_name); |
| 1898 | 1983 | ||
| 1899 | if (pty_fd >= 0) | 1984 | if (pty_fd >= 0) |
| 1900 | { | 1985 | { |
| @@ -7269,6 +7354,10 @@ syms_of_process (void) | |||
| 7269 | DEFSYM (QCstop, ":stop"); | 7354 | DEFSYM (QCstop, ":stop"); |
| 7270 | DEFSYM (QCoptions, ":options"); | 7355 | DEFSYM (QCoptions, ":options"); |
| 7271 | DEFSYM (QCplist, ":plist"); | 7356 | DEFSYM (QCplist, ":plist"); |
| 7357 | DEFSYM (QCcommand, ":command"); | ||
| 7358 | DEFSYM (QCconnection_type, ":connection-type"); | ||
| 7359 | DEFSYM (Qpty, "pty"); | ||
| 7360 | DEFSYM (Qpipe, "pipe"); | ||
| 7272 | 7361 | ||
| 7273 | DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event"); | 7362 | DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event"); |
| 7274 | 7363 | ||
| @@ -7371,7 +7460,7 @@ The variable takes effect when `start-process' is called. */); | |||
| 7371 | defsubr (&Sprocess_plist); | 7460 | defsubr (&Sprocess_plist); |
| 7372 | defsubr (&Sset_process_plist); | 7461 | defsubr (&Sset_process_plist); |
| 7373 | defsubr (&Sprocess_list); | 7462 | defsubr (&Sprocess_list); |
| 7374 | defsubr (&Sstart_process); | 7463 | defsubr (&Smake_process); |
| 7375 | defsubr (&Sserial_process_configure); | 7464 | defsubr (&Sserial_process_configure); |
| 7376 | defsubr (&Smake_serial_process); | 7465 | defsubr (&Smake_serial_process); |
| 7377 | defsubr (&Sset_network_process_option); | 7466 | defsubr (&Sset_network_process_option); |