This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: stat() and tilde prefix (was bad bash tab completion)


Hi,

On 15 Jan 2013 23:33, Shaddy Baddah wrote:
<snip>
From what I make of it, there needs to be a patch that, although can
work generically, adds checks only required for Cygwin. And therefore
is specific to the Cygwin package.

The check would be an extension of the file_exists() function, perhaps
called tilde_file_exists(), which determines if the tilde prefix forms
a directory component of the path (strchr('/')?). If it does not, the
file_exists() check is sufficient. If it does, then the check of if
that directory exists is logically and'ed to the result of
file_exists().

Does that sound about right?

A check like this might be a good idea. Ultimately I would be glad to be able to come up with more correct code in Cygwin while not getting slower, of course. But that's wishful thinking for now.

Bash, patched in the way I have described, seems to fix the tab completion issue.

I will tidy up the work and publish the patch at some point soon. I may
have taken a naive approach, so review comments are welcome.

Please find the patch discussed attached. It probably needs to be a bit more generic, maybe with some precompiler directives to limit it to cygwin? Although if it is just for cygwin, perhaps it can just go in the cygports patch?

Do I need to put an "attn bash maintainer" on the subject line?
diff --git a/bashline.c b/bashline.c
index 3cbb18f..31841fa 100644
--- a/bashline.c
+++ b/bashline.c
@@ -3478,8 +3478,9 @@ quote_word_break_chars (text)
       if (mbschr (rl_completer_word_break_characters, *s))
 	*r++ = '\\';
       /* XXX -- check for standalone tildes here and backslash-quote them */
-      if (s == text && *s == '~' && file_exists (text))
+      if (s == text && *s == '~' && tilde_file_exists (text)) {
         *r++ = '\\';
+      }
       *r++ = *s;
     }
   *r = '\0';
diff --git a/general.c b/general.c
index fdadf1d..b279cbe 100644
--- a/general.c
+++ b/general.c
@@ -544,6 +544,28 @@ file_exists (fn)
 }
 
 int
+tilde_file_exists (fn)
+     char *fn;
+{
+  struct stat sb;
+  char *slash, *dirpart;
+  int istildedir;
+
+  istildedir = 0;
+
+  slash = strchr (fn, '/');
+  if ((slash != 0) && (slash != fn))
+    {
+      dirpart = (char *)xmalloc ((slash - fn) + 1);
+      strncpy (dirpart, fn, (slash - fn) + 1);
+      istildedir = file_isdir (dirpart);
+      free (dirpart);
+    }
+
+  return (!((slash != 0) && (slash != fn) && ! istildedir) && (stat (fn, &sb) == 0));
+}
+
+int
 file_isdir (fn)
      char *fn;
 {
diff --git a/general.h b/general.h
index 2b31c58..f6b7ab4 100644
--- a/general.h
+++ b/general.h
@@ -302,6 +302,7 @@ extern int sh_openpipe __P((int *));
 extern int sh_closepipe __P((int *));
 
 extern int file_exists __P((char *));
+extern int tilde_file_exists __P((char *));
 extern int file_isdir __P((char  *));
 extern int file_iswdir __P((char  *));
 extern int dot_or_dotdot __P((const char *));

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]