Files
MSYS2-packages/bash/0001-bash-4.3-cygwin.patch
2014-03-13 23:16:19 +04:00

755 lines
25 KiB
Diff

diff -Naur a/bashline.c b/bashline.c
--- a/bashline.c 2014-02-10 04:56:58.000000000 +0400
+++ b/bashline.c 2014-03-13 16:36:05.375000000 +0400
@@ -263,6 +263,11 @@
are the only possible matches, even if FIGNORE says to. */
int force_fignore = 1;
+#if __CYGWIN__
+/* If set, shorten "foo.exe" to "foo" when they are the same file. */
+int completion_strip_exe;
+#endif /* __CYGWIN__ */
+
/* Perform spelling correction on directory names during word completion */
int dircomplete_spelling = 0;
@@ -490,11 +495,12 @@
kseq[0] = CTRL('J');
kseq[1] = '\0';
func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
- if (func == rl_vi_editing_mode)
+ extern rl_command_func_t *_imp__rl_vi_editing_mode;
+ if (func == rl_vi_editing_mode || func == _imp__rl_vi_editing_mode)
rl_unbind_key_in_map (CTRL('J'), emacs_meta_keymap);
kseq[0] = CTRL('M');
func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
- if (func == rl_vi_editing_mode)
+ if (func == rl_vi_editing_mode || func == _imp__rl_vi_editing_mode)
rl_unbind_key_in_map (CTRL('M'), emacs_meta_keymap);
#if defined (VI_MODE)
rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap);
@@ -513,7 +519,8 @@
kseq[0] = '~';
kseq[1] = '\0';
func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
- if (func == 0 || func == rl_tilde_expand)
+ extern rl_command_func_t *_imp__rl_tilde_expand;
+ if (func == 0 || func == rl_tilde_expand || func == _imp__rl_tilde_expand)
rl_bind_keyseq_in_map (kseq, bash_complete_username, emacs_meta_keymap);
rl_bind_key_if_unbound_in_map ('~', bash_possible_username_completions, emacs_ctlx_keymap);
@@ -536,7 +543,8 @@
kseq[0] = TAB;
kseq[1] = '\0';
func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
- if (func == 0 || func == rl_tab_insert)
+ extern rl_command_func_t *_imp__rl_tab_insert;
+ if (func == 0 || func == rl_tab_insert || func == _imp__rl_tab_insert)
rl_bind_key_in_map (TAB, dynamic_complete_history, emacs_meta_keymap);
/* Tell the completer that we want a crack first. */
@@ -2105,9 +2113,33 @@
else
#endif
cval = val;
+#if defined(__CYGWIN__)
+ /* executable_or_directory will do the right thing on //server,
+ but calling stat("//server") is an order of magnitude slower
+ than noting that readdir("//") only returns directories. */
+ if (match && (searching_path ? executable_file (val)
+ : ((val[0] == '/' && val[1] == '/'
+ && ! strchr (&val[2], '/'))
+ || executable_or_directory (val))))
+#endif
if (match && executable_completion ((searching_path ? val : cval), searching_path))
{
+#if __CYGWIN__
+ if (completion_strip_exe)
+ {
+ int val_len = strlen (val);
+ char *candidate;
+ if (val_len > 4 && !strcasecmp (&val[val_len - 4], ".exe")
+ && (candidate = strdup (val)))
+ {
+ candidate[val_len - 4] = '\0';
+ if (same_file (val, candidate, NULL, NULL))
+ temp[strlen (temp) - 4] = '\0';
+ free (candidate);
+ }
+ }
+#endif
if (cval != val)
free (cval);
free (val);
@@ -2843,6 +2875,17 @@
int r;
fn = bash_tilde_expand (name, 0);
+#if __CYGWIN__
+ /* stat("//server") can only be successful as a directory, but takes
+ a several-second timeout to fail. It is much faster to assume
+ that //server is a valid name than it is to wait for the stat,
+ even though it gives false positives on bad names. */
+ if (fn[0] == '/' && fn[1] == '/' && ! strchr (&fn[2], '/'))
+ {
+ free (fn);
+ return 1;
+ }
+#endif /* __CYGWIN__ */
r = file_isdir (fn);
free (fn);
diff -Naur a/builtins/set.def b/builtins/set.def
--- a/builtins/set.def 2013-04-19 15:20:34.000000000 +0400
+++ b/builtins/set.def 2014-03-13 16:36:05.375000000 +0400
@@ -56,6 +56,13 @@
#if defined (READLINE)
extern int no_line_editing;
#endif /* READLINE */
+#if __CYGWIN__
+extern int igncr;
+static int set_minus_o_option_maybe (int, const char *, int);
+# define INTERACTIVE_ONLY ,1
+#else /* ! __CYGWIN__ */
+# define INTERACTIVE_ONLY
+#endif
$BUILTIN set
$FUNCTION set_builtin
@@ -92,6 +99,9 @@
#if defined (HISTORY)
history enable command history
#endif
+#if __CYGWIN__
+ igncr on cygwin, ignore \r in line endings
+#endif
ignoreeof the shell will not exit upon reading EOF
interactive-comments
allow comments to appear in interactive commands
@@ -188,29 +198,41 @@
int *variable;
setopt_set_func_t *set_func;
setopt_get_func_t *get_func;
+#if __CYGWIN__
+ /* Cygwin users have taken to exporting SHELLOPTS for the
+ cygwin-specific igncr. As a result, we need to make sure
+ SHELLOPTS parsing does not turn on interactive options when
+ exported from an interactive shell, but parsed in a
+ non-interactive setting, since some interactive options violate
+ POSIX /bin/sh rules. */
+ int interactive_only;
+#endif /* __CYGWIN__ */
} o_options[] = {
{ "allexport", 'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (BRACE_EXPANSION)
{ "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif
#if defined (READLINE)
- { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
+ { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode INTERACTIVE_ONLY},
#endif
{ "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "errtrace", 'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "functrace", 'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (BANG_HISTORY)
- { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL INTERACTIVE_ONLY},
#endif /* BANG_HISTORY */
#if defined (HISTORY)
- { "history", '\0', &enable_history_list, bash_set_history, (setopt_get_func_t *)NULL },
+ { "history", '\0', &enable_history_list, bash_set_history, (setopt_get_func_t *)NULL INTERACTIVE_ONLY},
+#endif
+#if __CYGWIN__
+ { "igncr", '\0', &igncr, NULL, (setopt_get_func_t *)NULL },
#endif
{ "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
{ "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (JOB_CONTROL)
- { "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL INTERACTIVE_ONLY},
#endif
{ "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
@@ -229,7 +251,7 @@
{ "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "verbose", 'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (READLINE)
- { "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
+ { "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode INTERACTIVE_ONLY},
#endif
{ "xtrace", 'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
@@ -416,6 +438,15 @@
set_minus_o_option (on_or_off, option_name)
int on_or_off;
char *option_name;
+#if __CYGWIN__
+{
+ /* See cygwin comments above. */
+ return set_minus_o_option_maybe (on_or_off, option_name, 0);
+}
+static int
+set_minus_o_option_maybe (int on_or_off, const char *option_name,
+ int avoid_interactive)
+#endif /* __CYGWIN__ */
{
register int i;
@@ -423,6 +454,10 @@
{
if (STREQ (option_name, o_options[i].name))
{
+#if __CYGWIN__
+ if (o_options[i].interactive_only && avoid_interactive)
+ return EXECUTION_SUCCESS;
+#endif /* __CYGWIN__ */
if (o_options[i].letter == 0)
{
SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
@@ -548,7 +583,11 @@
vptr = 0;
while (vname = extract_colon_unit (value, &vptr))
{
+#if __CYGWIN__
+ set_minus_o_option_maybe (FLAG_ON, vname, !interactive_shell);
+#else /* !__CYGWIN__ */
set_minus_o_option (FLAG_ON, vname);
+#endif
free (vname);
}
}
diff -Naur a/builtins/shopt.def b/builtins/shopt.def
--- a/builtins/shopt.def 2013-02-27 18:43:20.000000000 +0400
+++ b/builtins/shopt.def 2014-03-13 16:36:05.375000000 +0400
@@ -91,6 +91,10 @@
extern int glob_asciirange;
extern int lastpipe_opt;
+#if __CYGWIN__
+extern int completion_strip_exe;
+#endif
+
#if defined (EXTENDED_GLOB)
extern int extended_glob;
#endif
@@ -161,6 +165,9 @@
{ "compat40", &shopt_compat40, set_compatibility_level },
{ "compat41", &shopt_compat41, set_compatibility_level },
{ "compat42", &shopt_compat41, set_compatibility_level },
+#if __CYGWIN__
+ { "completion_strip_exe", &completion_strip_exe, NULL },
+#endif
#if defined (READLINE)
{ "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL},
{ "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
diff -Naur a/config-top.h b/config-top.h
--- a/config-top.h 2012-08-19 04:51:30.000000000 +0400
+++ b/config-top.h 2014-03-13 16:36:05.375000000 +0400
@@ -80,10 +80,10 @@
#define KSH_COMPATIBLE_SELECT
/* System-wide .bashrc file for interactive shells. */
-/* #define SYS_BASHRC "/etc/bash.bashrc" */
+#define SYS_BASHRC "/etc/bash.bashrc"
/* System-wide .bash_logout for login shells. */
-/* #define SYS_BASH_LOGOUT "/etc/bash.bash_logout" */
+#define SYS_BASH_LOGOUT "/etc/bash.bash_logout"
/* Define this to make non-interactive shells begun with argv[0][0] == '-'
run the startup files when not in posix mode. */
@@ -93,7 +93,7 @@
sshd and source the .bashrc if so (like the rshd behavior). This checks
for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment,
which can be fooled under certain not-uncommon circumstances. */
-/* #define SSH_SOURCE_BASHRC */
+#define SSH_SOURCE_BASHRC
/* Define if you want the case-capitalizing operators (~[~]) and the
`capcase' variable attribute (declare -c). */
diff -Naur a/doc/bash.1 b/doc/bash.1
--- a/doc/bash.1 2014-02-06 18:03:52.000000000 +0400
+++ b/doc/bash.1 2014-03-13 16:36:05.390600000 +0400
@@ -1658,6 +1658,14 @@
Expands to the effective user ID of the current user, initialized at
shell startup. This variable is readonly.
.TP
+.B EXECIGNORE
+A colon-separated list of extended glob (see \fBPattern Matching\fP)
+patterns. Files with full paths matching one of these patterns are
+not considered executable for the purposes of completion and PATH
+searching, but the \fB[\fP, \fB[[\fP, and \fBtest\fP builtins are not
+affected. Use this variable to deal with systems that set the
+executable bit on files that are not actually executable.
+.TP
.B FUNCNAME
An array variable containing the names of all shell functions
currently in the execution call stack.
@@ -9332,6 +9340,10 @@
attempts spelling correction on directory names during word completion
if the directory name initially supplied does not exist.
.TP 8
+.B completion_strip_exe
+If set, whenever bash sees `foo.exe' during completion, it checks if
+`foo' is the same file and strips the suffix.
+.TP 8
.B dotglob
If set,
.B bash
diff -Naur a/doc/bashref.texi b/doc/bashref.texi
--- a/doc/bashref.texi 2014-02-22 22:20:36.000000000 +0400
+++ b/doc/bashref.texi 2014-03-13 16:36:05.390600000 +0400
@@ -4999,6 +4999,10 @@
buffer.
If not set, Bash attempts to preserve what the user typed.
+@item completion_strip_exe
+If set, whenever bash sees `foo.exe' during completion, it checks if
+`foo' is the same file and strips the suffix.
+
@item dirspell
If set, Bash
attempts spelling correction on directory names during word completion
@@ -5578,6 +5582,14 @@
The numeric effective user id of the current user. This variable
is readonly.
+@item EXECIGNORE
+A colon-separated list of extended glob ((@pxref{Pattern Matching})
+patterns. Files with full paths matching one of these patterns are
+not considered executable for the purposes of completion and PATH
+searching, but the @code{[}, @code{[[}, and @code{test} builtins are
+not affected. Use this variable to deal with systems that set the
+executable bit on files that are not actually executable.
+
@item FCEDIT
The editor used as a default by the @option{-e} option to the @code{fc}
builtin command.
diff -Naur a/doc/builtins.1 b/doc/builtins.1
--- a/doc/builtins.1 2012-02-21 23:32:05.000000000 +0400
+++ b/doc/builtins.1 2014-03-13 16:36:05.390600000 +0400
@@ -19,6 +19,6 @@
ulimit, umask, unalias, unset, wait \- bash built-in commands, see \fBbash\fR(1)
.SH BASH BUILTIN COMMANDS
.nr zZ 1
-.so bash.1
+.so man1/bash.1
.SH SEE ALSO
bash(1), sh(1)
diff -Naur a/doc/Makefile.in b/doc/Makefile.in
--- a/doc/Makefile.in 2013-10-31 00:18:12.000000000 +0400
+++ b/doc/Makefile.in 2014-03-13 16:36:05.390600000 +0400
@@ -176,7 +176,7 @@
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/bashref.texi
bash.info: bashref.info
- ${SHELL} ${INFOPOST} < $(srcdir)/bashref.info > $@ ; \
+ ${SHELL} ${INFOPOST} < bashref.info > $@ ; \
bash.txt: bash.1
bash.ps: bash.1
@@ -237,9 +237,9 @@
-$(INSTALL_DATA) $(srcdir)/bashbug.1 $(DESTDIR)$(man1dir)/bashbug${man1ext}
-$(INSTALL_DATA) $(OTHER_DOCS) $(DESTDIR)$(docdir)
# uncomment the next lines to install the builtins man page
-# sed 's:bash\.1:man1/&:' $(srcdir)/builtins.1 > $${TMPDIR:-/var/tmp}/builtins.1
-# -$(INSTALL_DATA) $${TMPDIR:-/var/tmp}/builtins.1 $(DESTDIR)$(man1dir)/bash_builtins${man1ext}
-# -$(RM) $${TMPDIR:-/var/tmp}/builtins.1
+ sed 's:bash\.1:man1/&:' $(srcdir)/builtins.1 > $${TMPDIR:-/tmp}/builtins.1
+ -$(INSTALL_DATA) $${TMPDIR:-/tmp}/builtins.1 $(DESTDIR)$(man1dir)/bash_builtins${man1ext}
+ -$(RM) $${TMPDIR:-/tmp}/builtins.1
-if test -f bash.info; then d=.; else d=$(srcdir); fi; \
$(INSTALL_DATA) $$d/bash.info $(DESTDIR)$(infodir)/bash.info
# run install-info if it is present to update the info directory
diff -Naur a/execute_cmd.c b/execute_cmd.c
--- a/execute_cmd.c 2014-01-31 19:54:52.000000000 +0400
+++ b/execute_cmd.c 2014-03-13 16:36:05.406200000 +0400
@@ -5280,6 +5280,13 @@
internal_error (_("%s: cannot execute binary file: %s"), command, strerror (i));
return (EX_BINARY_FILE);
}
+#if __CYGWIN__
+ extern int sh_setlinebuf (FILE *);
+ /* Let stdio know that fd may have changed from text to binary. */
+ freopen (NULL, "w", stdout);
+ /* Bash builtins (foolishly) rely on line-buffering. */
+ sh_setlinebuf (stdout);
+#endif /* __CYGWIN__ */
}
/* We have committed to attempting to execute the contents of this file
diff -Naur a/findcmd.c b/findcmd.c
--- a/findcmd.c 2012-10-15 15:45:04.000000000 +0400
+++ b/findcmd.c 2014-03-13 16:36:05.406200000 +0400
@@ -48,6 +48,8 @@
extern int errno;
#endif
+#include <glob/strmatch.h>
+
extern int posixly_correct;
extern int last_command_exit_value;
@@ -77,6 +79,38 @@
containing the file of interest. */
int dot_found_in_search = 0;
+static struct ignorevar execignore =
+{
+ "EXECIGNORE",
+ (struct ign *)0,
+ 0,
+ (char *)0,
+ (sh_iv_item_func_t *)0,
+};
+
+void
+setup_exec_ignore (char *varname)
+{
+ setup_ignore_patterns (&execignore);
+}
+
+/* Return whether we should never consider file executable
+ * even if the system tells us it is. */
+static int
+is_on_exec_blacklist (char *name)
+{
+ struct ign *p;
+ int flags = FNM_EXTMATCH | FNM_CASEFOLD;
+
+ for (p = execignore.ignores; p && p->val; p++)
+ {
+ if (strmatch (p->val, (char *)name, flags) != FNM_NOMATCH)
+ return (1);
+ }
+
+ return (0);
+}
+
/* Return some flags based on information about this file.
The EXISTS bit is non-zero if the file is found.
The EXECABLE bit is non-zero the file is executble.
@@ -104,7 +138,7 @@
file access mechanisms into account. eaccess uses the effective
user and group IDs, not the real ones. We could use sh_eaccess,
but we don't want any special treatment for /dev/fd. */
- if (eaccess (name, X_OK) == 0)
+ if (!is_on_exec_blacklist (name) && eaccess (name, X_OK) == 0)
r |= FS_EXECABLE;
if (eaccess (name, R_OK) == 0)
r |= FS_READABLE;
diff -Naur a/findcmd.h b/findcmd.h
--- a/findcmd.h 2012-01-15 03:56:25.000000000 +0400
+++ b/findcmd.h 2014-03-13 16:36:05.406200000 +0400
@@ -31,5 +31,6 @@
extern char *find_path_file __P((const char *));
extern char *search_for_command __P((const char *, int));
extern char *user_command_matches __P((const char *, int, int));
+extern void setup_exec_ignore __P((char *));
#endif /* _FINDCMD_H_ */
diff -Naur a/input.c b/input.c
--- a/input.c 2014-02-07 18:13:08.000000000 +0400
+++ b/input.c 2014-03-13 16:36:05.406200000 +0400
@@ -44,6 +44,10 @@
#include "quit.h"
#include "trap.h"
+#if __CYGWIN__
+int igncr;
+#endif /* __CYGWIN__ */
+
#if !defined (errno)
extern int errno;
#endif /* !errno */
@@ -561,6 +565,19 @@
{
CHECK_TERMSIG;
+#if __CYGWIN__
+ /* shopt igncr means to discard carriage returns from input stream.
+ If cr is the only character in the buffer, then recurse to pick
+ up the next character; otherwise flatten the buffer. */
+ if (igncr)
+ {
+ int ch;
+ while ((ch = bufstream_getc (buffers[bash_input.location.buffered_fd]))
+ == '\r')
+ ;
+ return ch;
+ }
+#endif /* __CYGWIN__ */
#if !defined (DJGPP)
return (bufstream_getc (buffers[bash_input.location.buffered_fd]));
#else
diff -Naur a/lib/sh/pathcanon.c b/lib/sh/pathcanon.c
--- a/lib/sh/pathcanon.c 2012-07-30 03:55:01.000000000 +0400
+++ b/lib/sh/pathcanon.c 2014-03-13 16:36:05.421800000 +0400
@@ -194,6 +194,8 @@
*q++ = DIRSEP;
while (*p && (ISDIRSEP(*p) == 0))
*q++ = *p++;
+ }
+ }
/* Check here for a valid directory with _path_isdir. */
if (flags & PATH_CHECKEXISTS)
{
@@ -211,8 +213,7 @@
}
*q = c;
}
- }
- }
+
/* Empty string is really ``.'' or `/', depending on what we started with. */
if (q == result)
diff -Naur a/lib/sh/pathphys.c b/lib/sh/pathphys.c
--- a/lib/sh/pathphys.c 2013-05-28 23:33:58.000000000 +0400
+++ b/lib/sh/pathphys.c 2014-03-13 16:36:05.421800000 +0400
@@ -35,6 +35,7 @@
#include <stdio.h>
#include <chartypes.h>
#include <errno.h>
+#include <stdlib.h>
#include "shell.h"
@@ -76,6 +77,10 @@
char *path;
int flags;
{
+#if __CYGWIN__
+ /* realpath does this right without all the hassle */
+ return realpath (path, NULL);
+#else
char tbuf[PATH_MAX+1], linkbuf[PATH_MAX+1];
char *result, *p, *q, *qsave, *qbase, *workpath;
int double_slash_path, linklen, nlink;
@@ -249,6 +254,7 @@
}
return (result);
+#endif /* !__CYGWIN__ */
}
char *
diff -Naur a/lib/sh/tmpfile.c b/lib/sh/tmpfile.c
--- a/lib/sh/tmpfile.c 2013-12-19 02:50:13.000000000 +0400
+++ b/lib/sh/tmpfile.c 2014-03-13 16:36:05.421800000 +0400
@@ -96,7 +96,7 @@
if (tdir && (file_iswdir (tdir) == 0 || strlen (tdir) > PATH_MAX))
tdir = 0;
- if (tdir == 0)
+ if (tdir == 0 || !file_iswdir (tdir))
tdir = get_sys_tmpdir ();
#if defined (HAVE_PATHCONF) && defined (_PC_NAME_MAX)
@@ -118,14 +118,15 @@
struct stat sb;
int r, tdlen;
- filename = (char *)xmalloc (PATH_MAX + 1);
+ filename = NULL;
tdir = get_tmpdir (flags);
tdlen = strlen (tdir);
lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
#ifdef USE_MKTEMP
- sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+ if (asprintf (&filename, "%s/%s.XXXXXX", tdir, lroot) < 0)
+ return NULL;
if (mktemp (filename) == 0)
{
free (filename);
@@ -138,7 +139,9 @@
(unsigned long) time ((time_t *)0) ^
(unsigned long) dollar_dollar_pid ^
(unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++);
- sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
+ free (filename);
+ if (asprintf (&filename, "%s/%s-%lu", tdir, lroot, filenum) < 0)
+ return NULL;
if (tmpnamelen > 0 && tmpnamelen < 32)
filename[tdlen + 1 + tmpnamelen] = '\0';
# ifdef HAVE_LSTAT
@@ -163,14 +166,19 @@
char *filename, *tdir, *lroot;
int fd, tdlen;
- filename = (char *)xmalloc (PATH_MAX + 1);
+ filename = NULL;
tdir = get_tmpdir (flags);
tdlen = strlen (tdir);
lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
#ifdef USE_MKSTEMP
- sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+ if (asprintf (&filename, "%s/%s.XXXXXX", tdir, lroot) < 0)
+ {
+ if (namep)
+ *namep = NULL;
+ return -1;
+ }
fd = mkstemp (filename);
if (fd < 0 || namep == 0)
{
@@ -187,7 +195,13 @@
(unsigned long) time ((time_t *)0) ^
(unsigned long) dollar_dollar_pid ^
(unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++);
- sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
+ free (filename);
+ if (asprintf (&filename, "%s/%s-%lu", tdir, lroot, filenum) < 0)
+ {
+ if (namep)
+ *namep = NULL;
+ return -1;
+ }
if (tmpnamelen > 0 && tmpnamelen < 32)
filename[tdlen + 1 + tmpnamelen] = '\0';
fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600);
diff -Naur a/parse.y b/parse.y
--- a/parse.y 2014-02-11 18:42:10.000000000 +0400
+++ b/parse.y 2014-03-13 16:36:05.437400000 +0400
@@ -1526,14 +1526,20 @@
string = bash_input.location.string;
/* If the string doesn't exist, or is empty, EOF found. */
- if (string && *string)
+ while (string && *string)
{
c = *string++;
bash_input.location.string = string;
+#if __CYGWIN__
+ {
+ extern int igncr;
+ if (igncr && c == '\r')
+ continue;
+ }
+#endif /* __CYGWIN__ */
return (c);
}
- else
- return (EOF);
+ return (EOF);
}
static int
diff -Naur a/pathexp.h b/pathexp.h
--- a/pathexp.h 2009-01-04 22:32:40.000000000 +0300
+++ b/pathexp.h 2014-03-13 16:36:05.437400000 +0400
@@ -86,7 +86,7 @@
typedef int sh_iv_item_func_t __P((struct ign *));
struct ignorevar {
- char *varname; /* FIGNORE or GLOBIGNORE */
+ char *varname; /* FIGNORE or GLOBIGNORE or EXECIGNORE */
struct ign *ignores; /* Store the ignore strings here */
int num_ignores; /* How many are there? */
char *last_ignoreval; /* Last value of variable - cached for speed */
diff -Naur a/shell.c b/shell.c
--- a/shell.c 2014-01-14 17:04:32.000000000 +0400
+++ b/shell.c 2014-03-13 16:36:05.437400000 +0400
@@ -336,7 +336,10 @@
struct stat sb;
if (stat ("/tmp", &sb) < 0)
- internal_warning (_("could not find /tmp, please create!"));
+ {
+ if (mkdir ("/tmp", S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX) != 0)
+ internal_warning (_("could not find /tmp, please create!"));
+ }
else
{
if (S_ISDIR (sb.st_mode) == 0)
diff -Naur a/subst.c b/subst.c
--- a/subst.c 2014-01-24 01:26:37.000000000 +0400
+++ b/subst.c 2014-03-13 16:36:05.453000000 +0400
@@ -5260,7 +5260,13 @@
#endif
continue;
}
-
+#if __CYGWIN__
+ {
+ extern int igncr;
+ if (igncr && c == '\r')
+ continue;
+ }
+#endif /* __CYGWIN__ */
/* Add the character to ISTRING, possibly after resizing it. */
RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
@@ -5376,6 +5382,27 @@
sys_error (_("cannot make pipe for command substitution"));
goto error_exit;
}
+#if __CYGWIN__
+ /* Passing a pipe through std fds can cause hangs when talking to a
+ non-cygwin child. Move it. */
+ if (fildes[0] < 3)
+ {
+ int fd = fcntl (fildes[0], F_DUPFD, 3);
+ close (fildes[0]);
+ fildes[0] = fd;
+ }
+ if (fildes[1] < 3)
+ {
+ int fd = fcntl (fildes[1], F_DUPFD, 3);
+ close (fildes[1]);
+ fildes[1] = fd;
+ }
+ if (fildes[0] < 0 || fildes[1] < 0)
+ {
+ sys_error (_("cannot make pipe for command substitution"));
+ goto error_exit;
+ }
+#endif /* __CYGWIN__ */
old_pid = last_made_pid;
#if defined (JOB_CONTROL)
diff -Naur a/variables.c b/variables.c
--- a/variables.c 2014-02-14 20:55:12.000000000 +0400
+++ b/variables.c 2014-03-13 16:36:05.453000000 +0400
@@ -4622,6 +4622,8 @@
{ "FUNCNEST", sv_funcnest },
+ { "EXECIGNORE", sv_execignore },
+
{ "GLOBIGNORE", sv_globignore },
#if defined (HISTORY)
@@ -4818,6 +4820,13 @@
setup_glob_ignore (name);
}
+/* What to do when EXECIGNORE changes. */
+void
+sv_execignore (char *name)
+{
+ setup_exec_ignore (name);
+}
+
#if defined (READLINE)
void
sv_comp_wordbreaks (name)
diff -Naur a/variables.h b/variables.h
--- a/variables.h 2014-01-09 00:33:29.000000000 +0400
+++ b/variables.h 2014-03-13 16:36:05.468600000 +0400
@@ -373,6 +373,7 @@
extern void sv_mail __P((char *));
extern void sv_funcnest __P((char *));
extern void sv_globignore __P((char *));
+extern void sv_execignore __P((char *));
extern void sv_ignoreeof __P((char *));
extern void sv_strict_posix __P((char *));
extern void sv_optind __P((char *));