x. Fixed a slight cosmetic problem when printing commands containing a
`>&word' redirection.
+y. Fixed a problem that could cause here documents to not be created correctly
+ if the system temporary directory did not allow writing.
+
2. Changes to Readline
a. Change to history expansion functions to treat `^' as equivalent to word
config.h.in
- add HAVE_WCSDUP define
+
+ 2/9
+ ---
+builtins/shift.def
+ - fix a call to sh_erange that possibly dereferences a NULL pointer
+
+ 2/12
+ ----
+general.c
+ - start at a general set of file property checking functions:
+ file_isdir(), file_iswdir() (is writable directory)
+
+general.h
+ - extern declarations for new functions
+
+lib/sh/tmpfile.c
+ - use file_iswdir() to make sure the temporary directory used for
+ here documents and other temp files is writable in get_sys_tmpdir()
+
+ 2/17
+ ----
+bashline.c
+ - fix conditional binding of emacs-mode M-~ -- there is a default
+ binding for it (rl_tilde_expand), so a straight call to
+ rl_bind_key_if_unbound_in_map doesn't do the right thing
rl_bind_key_if_unbound_in_map ('/', bash_complete_filename, emacs_meta_keymap);
rl_bind_key_if_unbound_in_map ('/', bash_possible_filename_completions, emacs_ctlx_keymap);
- rl_bind_key_if_unbound_in_map ('~', bash_complete_username, emacs_meta_keymap);
+ /* Have to jump through hoops here because there is a default binding for
+ M-~ (rl_tilde_expand) */
+ kseq[0] = '~';
+ kseq[1] = '\0';
+ func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
+ if (func == 0 || func == 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);
rl_bind_key_if_unbound_in_map ('@', bash_complete_hostname, emacs_meta_keymap);
return (EXECUTION_SUCCESS);
else if (times < 0)
{
- sh_erange (list->word->word, _("shift count"));
+ sh_erange (list ? list->word->word : NULL, _("shift count"));
return (EXECUTION_FAILURE);
}
else if (times > number_of_args ())
/* **************************************************************** */
/* */
+/* Functions to inspect pathnames */
+/* */
+/* **************************************************************** */
+
+int
+file_isdir (fn)
+ char *fn;
+{
+ struct stat sb;
+
+ return ((stat (fn, &sb) == 0) && S_ISDIR (sb.st_mode));
+}
+
+int
+file_iswdir (fn)
+ char *fn;
+{
+ return (file_isdir (fn) && test_eaccess (fn, W_OK) == 0);
+}
+
+
+/* **************************************************************** */
+/* */
/* Functions to manipulate pathnames */
/* */
/* **************************************************************** */
extern int same_file __P((char *, char *, struct stat *, struct stat *));
#endif
+extern int file_isdir __P((char *));
+extern int file_iswdir __P((char *));
+
extern char *make_absolute __P((char *, char *));
extern int absolute_pathname __P((const char *));
extern int absolute_program __P((const char *));
#ifdef P_tmpdir
sys_tmpdir = P_tmpdir;
- if (stat (sys_tmpdir, &sb) == 0)
+ if (file_iswdir (sys_tmpdir))
return sys_tmpdir;
#endif
sys_tmpdir = "/tmp";
- if (stat (sys_tmpdir, &sb) == 0)
+ if (file_iswdir (sys_tmpdir))
return sys_tmpdir;
sys_tmpdir = "/var/tmp";
- if (stat (sys_tmpdir, &sb) == 0)
+ if (file_iswdir (sys_tmpdir))
return sys_tmpdir;
sys_tmpdir = "/usr/tmp";
- if (stat (sys_tmpdir, &sb) == 0)
+ if (file_iswdir (sys_tmpdir))
return sys_tmpdir;
sys_tmpdir = DEFAULT_TMPDIR;