Hello everybody, On Thu, Aug 20, 2015 at 09:28:09AM -0400, yary wrote: > The nul character (ascii 0) is invalid in file/paths for most filesystems > and can be safely used as a separator, if elisp strings and sed can handle > them then that's the answer. >
I've made some tests with stat and sed and it seems that stat support the null character only with --printf switch. sed seems to catch null with \o0. For the fear of shell's handling of null char : the first problem is the stat program. Linux and BSD have differents options (and I don't know how it work on Solaris nor in HP*UX nor ...) So maybe the solution is to first check for the version of stat and use an alist of options for each ones (maybe a custom option) but that's a bigger work. Modified patch is at end of this e-mail > -y > > On Thu, Aug 20, 2015 at 4:38 AM, Michael Albinus <[email protected]> > wrote: > > > [email protected] (Pierre Téchoueyres) writes: > > > > > Hello everybody, > > > > Hi Pierre, > > > > > After digging into the traces (thanks to `tramp-verbose'), I've found > > > `tramp-do-file-attributes-with-stat' and > > > `tramp-do-directory-files-and-attributes-with-stat'. > > > On each of theses functions a replace of // is done. > > > > > > But this is done to workaround a bug in pdks on Opsware and I can't test > > > it. > > > > > > The workaround I propose is to replace the //%N// of the stat command by > > > **%N**. I thing it's impossible to create a link with stars (*) in name. > > > > Oh, it's possible: > > > > # touch /tmp/\*\*tmp\*\* > > # ln -s /tmp/\*\*tmp\*\* /tmp/\*\*\*tmp\*\*\* > > # ls -al /tmp/*tmp* > > lrwxrwxrwx 1 albinus albinus 12 Aug 20 10:00 /tmp/***tmp*** -> > > /tmp/**tmp** > > -rw-rw-r-- 1 albinus albinus 0 Aug 20 10:00 /tmp/**tmp** > > > > And your patch makes the Tramp test suite fail. Try > > > > # make check Sorry I should have do that first. But ... this won't work on my win7 computer (I think it's a problem between msys and emacs). > > > > The problem is, that in function `tramp--test-special-characters' the > > file "*foo*bar*baz*" is checked. With your mask "**", the stat command > > temporarily returns "***foo*bar*baz***", Tramp cannot decide safely, > > which of the "**" characters has to be replaced in sed. > > > > So we would need another mask, which won't appear most likely in the > > file name. Maybe you play with generating an arbitrary string, as > > `tramp-end-of-heredoc' does? > > I've tried to figure how to add tests for link with // in path but without any success. Sorry. > > Best regards, Michael. Best regards Pierre --8<---------------cut here---------------start------------->8--- 1 file changed, 12 insertions(+), 12 deletions(-) lisp/tramp-sh.el | 24 ++++++++++++------------ modified lisp/tramp-sh.el @@ -1304,18 +1304,18 @@ target of the symlink differ." (concat ;; On Opsware, pdksh (which is the true name of ksh there) ;; doesn't parse correctly the sequence "((". Therefore, we add - ;; a space. Apostrophes in the stat output are masked as "//", + ;; a space. Apostrophes in the stat output are masked as "\\0", (null char) ;; in order to make a proper shell escape of them in file names. - "( (%s %s || %s -h %s) && (%s -c " - "'((//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' " - "%s | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g') || echo nil)") + "( (%s %s || %s -h %s) && (%s --printf " + "'((\\0%%N\\0) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \\0%%A\\0 t %%ie0 -1)\\n' " + "%s | sed -e 's/\"/\\\\\"/g' -e 's/\\o0/\"/g') || echo nil)") (tramp-get-file-exists-command vec) (tramp-shell-quote-argument localname) (tramp-get-test-command vec) (tramp-shell-quote-argument localname) (tramp-get-remote-stat vec) - (if (eq id-format 'integer) "%ue0" "//%U//") - (if (eq id-format 'integer) "%ge0" "//%G//") + (if (eq id-format 'integer) "%ue0" "\\0%U\\0") + (if (eq id-format 'integer) "%ge0" "\\0%G\\0") (tramp-shell-quote-argument localname)))) (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list) @@ -1747,12 +1747,12 @@ be non-negative integers." ;; We must care about file names with spaces, or starting with ;; "-"; this would confuse xargs. "ls -aQ" might be a solution, ;; but it does not work on all remote systems. Apostrophes in - ;; the stat output are masked as "//", in order to make a proper + ;; the stat output are masked as "\\0" (null char), in order to make a proper ;; shell escape of them in file names. "cd %s && echo \"(\"; (%s %s -a | " - "xargs %s -c " - "'(//%%n// (//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' " - "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g'); echo \")\"") + "xargs %s -printf " + "'(\\0%%n\\0 (\\0%%N\\0) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \\0%%A\\0 t %%ie0 -1)' " + "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\o0/\"/g' ); echo \")\"") (tramp-shell-quote-argument localname) (tramp-get-ls-command vec) ;; On systems which have no quoting style, file names with @@ -1760,8 +1760,8 @@ be non-negative integers." (if (tramp-get-ls-command-with-quoting-style vec) "--quoting-style=shell" "") (tramp-get-remote-stat vec) - (if (eq id-format 'integer) "%ue0" "//%U//") - (if (eq id-format 'integer) "%ge0" "//%G//")))) + (if (eq id-format 'integer) "%ue0" "\\0%U\\0") + (if (eq id-format 'integer) "%ge0" "\\0%G\\0")))) ;; This function should return "foo/" for directories and "bar" for ;; files. --8<---------------cut here---------------end--------------->8--- _______________________________________________ Tramp-devel mailing list [email protected] https://lists.gnu.org/mailman/listinfo/tramp-devel
