diff options
| author | Paul Eggert | 2013-08-23 10:57:07 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-08-23 10:57:07 -0700 |
| commit | c365c3558065fca4c11c3f46605d1045763485ab (patch) | |
| tree | 9005b8c7afef991fe569928e2cb9a8b2f7e78324 /src/process.c | |
| parent | bb35f42f61663c47d3443a87665462f75dfd3b2c (diff) | |
| download | emacs-c365c3558065fca4c11c3f46605d1045763485ab.tar.gz emacs-c365c3558065fca4c11c3f46605d1045763485ab.zip | |
Don't let very long directory names overrun the stack.
Fix some related minor problems involving "//", vfork.
* callproc.c (encode_current_directory): New function.
(call_process): Don't append "/"; not needed.
* fileio.c (file_name_as_directory_slop): New constant.
(file_name_as_directory): Allow SRC to be longer than SRCLEN;
this can save the caller having to alloca.
(Ffile_name_as_directory, Fdirectory_file_name, Fexpand_file_name):
Use SAFE_ALLOCA, not alloca.
(directory_file_name, Fexpand_file_name): Leave leading "//"
alone, since it can be special even on POSIX platforms.
* callproc.c (call_process):
* process.c (Fformat_network_address):
* sysdep.c (sys_subshell):
Use encode_current_directory rather than rolling our own.
(create_process): No need to encode directory; caller does that now.
* process.h (encode_current_directory): New decl.
* sysdep.c (sys_subshell): Work even if vfork trashes saved_handlers.
Rework to avoid 'goto xyzzy;'.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 32 |
1 files changed, 7 insertions, 25 deletions
diff --git a/src/process.c b/src/process.c index 75cb590fc57..ea1129ffbb8 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1408,22 +1408,9 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1408 | function. The argument list is protected by the caller, so all | 1408 | function. The argument list is protected by the caller, so all |
| 1409 | we really have to worry about is buffer. */ | 1409 | we really have to worry about is buffer. */ |
| 1410 | { | 1410 | { |
| 1411 | struct gcpro gcpro1, gcpro2; | 1411 | struct gcpro gcpro1; |
| 1412 | 1412 | GCPRO1 (buffer); | |
| 1413 | current_dir = BVAR (current_buffer, directory); | 1413 | current_dir = encode_current_directory (); |
| 1414 | |||
| 1415 | GCPRO2 (buffer, current_dir); | ||
| 1416 | |||
| 1417 | current_dir = Funhandled_file_name_directory (current_dir); | ||
| 1418 | if (NILP (current_dir)) | ||
| 1419 | /* If the file name handler says that current_dir is unreachable, use | ||
| 1420 | a sensible default. */ | ||
| 1421 | current_dir = build_string ("~/"); | ||
| 1422 | current_dir = expand_and_dir_to_file (current_dir, Qnil); | ||
| 1423 | if (NILP (Ffile_accessible_directory_p (current_dir))) | ||
| 1424 | report_file_error ("Setting current directory", | ||
| 1425 | BVAR (current_buffer, directory)); | ||
| 1426 | |||
| 1427 | UNGCPRO; | 1414 | UNGCPRO; |
| 1428 | } | 1415 | } |
| 1429 | 1416 | ||
| @@ -1670,7 +1657,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1670 | bool pty_flag = 0; | 1657 | bool pty_flag = 0; |
| 1671 | char pty_name[PTY_NAME_SIZE]; | 1658 | char pty_name[PTY_NAME_SIZE]; |
| 1672 | Lisp_Object lisp_pty_name = Qnil; | 1659 | Lisp_Object lisp_pty_name = Qnil; |
| 1673 | Lisp_Object encoded_current_dir; | ||
| 1674 | 1660 | ||
| 1675 | inchannel = outchannel = -1; | 1661 | inchannel = outchannel = -1; |
| 1676 | 1662 | ||
| @@ -1735,15 +1721,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1735 | /* This may signal an error. */ | 1721 | /* This may signal an error. */ |
| 1736 | setup_process_coding_systems (process); | 1722 | setup_process_coding_systems (process); |
| 1737 | 1723 | ||
| 1738 | encoded_current_dir = ENCODE_FILE (current_dir); | ||
| 1739 | |||
| 1740 | block_input (); | 1724 | block_input (); |
| 1741 | block_child_signal (); | 1725 | block_child_signal (); |
| 1742 | 1726 | ||
| 1743 | #ifndef WINDOWSNT | 1727 | #ifndef WINDOWSNT |
| 1744 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 1728 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 1745 | { | 1729 | { |
| 1746 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; | 1730 | Lisp_Object volatile current_dir_volatile = current_dir; |
| 1747 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; | 1731 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; |
| 1748 | char **volatile new_argv_volatile = new_argv; | 1732 | char **volatile new_argv_volatile = new_argv; |
| 1749 | int volatile forkin_volatile = forkin; | 1733 | int volatile forkin_volatile = forkin; |
| @@ -1752,7 +1736,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1752 | 1736 | ||
| 1753 | pid = vfork (); | 1737 | pid = vfork (); |
| 1754 | 1738 | ||
| 1755 | encoded_current_dir = encoded_current_dir_volatile; | 1739 | current_dir = current_dir_volatile; |
| 1756 | lisp_pty_name = lisp_pty_name_volatile; | 1740 | lisp_pty_name = lisp_pty_name_volatile; |
| 1757 | new_argv = new_argv_volatile; | 1741 | new_argv = new_argv_volatile; |
| 1758 | forkin = forkin_volatile; | 1742 | forkin = forkin_volatile; |
| @@ -1864,11 +1848,9 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1864 | if (pty_flag) | 1848 | if (pty_flag) |
| 1865 | child_setup_tty (xforkout); | 1849 | child_setup_tty (xforkout); |
| 1866 | #ifdef WINDOWSNT | 1850 | #ifdef WINDOWSNT |
| 1867 | pid = child_setup (xforkin, xforkout, xforkout, | 1851 | pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); |
| 1868 | new_argv, 1, encoded_current_dir); | ||
| 1869 | #else /* not WINDOWSNT */ | 1852 | #else /* not WINDOWSNT */ |
| 1870 | child_setup (xforkin, xforkout, xforkout, | 1853 | child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); |
| 1871 | new_argv, 1, encoded_current_dir); | ||
| 1872 | #endif /* not WINDOWSNT */ | 1854 | #endif /* not WINDOWSNT */ |
| 1873 | } | 1855 | } |
| 1874 | 1856 | ||