Skip to content

Conversation

@dgchurchill
Copy link

Firstly, thank you for all your work, straight.el is great!

This is a small fix for a bug I've encountered on Windows with symlinking. It's a bit of a crap fix because I haven't had the time to look properly at it to understand what's going on. I'm posting this mostly in case it helps others and perhaps someone can improve the fix or at least explain what's going on. Please do feel free just to close this PR on the basis that it's not well motivated.

When installing yasnippt-snippets I would see the following output:

$ cd "c:/Users/dave/source/dgchurchill/dotfiles/emacs/"
$ "cmd" "/c" "mklink" "c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg=" "c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg="

symbolic link created for c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg <<===>> c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg

[Return code: 0]

$ cd "c:/Users/dave/source/dgchurchill/dotfiles/emacs/"
$ "cmd" "/c" "mklink" "c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg" "c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg"

Cannot create a file when that file already exists.

[Return code: 1]

For some reason, when creating the link to cfg= the = would be stripped off the end and I'd get a link from cfg to cfg. Maybe this is related to quoting but I'm not really sure.

For whatever reason, appending a space to the end of the names makes everything work correctly.

When installing yasnippt-snippets I would see the following output:

```
$ cd "c:/Users/dave/source/dgchurchill/dotfiles/emacs/"
$ "cmd" "/c" "mklink" "c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg=" "c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg="

symbolic link created for c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg <<===>> c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg

[Return code: 0]

$ cd "c:/Users/dave/source/dgchurchill/dotfiles/emacs/"
$ "cmd" "/c" "mklink" "c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg" "c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg"

Cannot create a file when that file already exists.

[Return code: 1]
```

For some reason, when creating the link to `cfg=` the `=` would be
stripped off the end and I'd get a link from `cfg` to `cfg`. Maybe
this is related to quoting but I'm not really sure.

For whatever reason, appending a space to the end of the names makes
everything work correctly.
@raxod502
Copy link
Member

If you run mklink manually, do you see equals signs getting stripped out also?
What about if you run the cmd /c mklink command manually?

I'm wondering what level this is happening at, which would inform how we can best make sure that it's avoided.

@dgchurchill
Copy link
Author

Sorry I should have mentioned that I originally found my workaround by using Powershell.

If I run the command under Powershell I see the same behaviour:

PS C:\Users\dave> cmd /c mklink "c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg=" "c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg="
symbolic link created for c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg <<===>> c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg

procmon shows that the command line was

"C:\Windows\System32\cmd.exe" /c mklink c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg= c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg=

so the =s made it to cmd.exe, but it seems like cmd.exe itself ignored them.

Quoting the = with a ^ doesn't work either (exactly as above, the ^= ends up on the command line, but both are still ignored by cmd.

Testing the original command directly under cmd.exe actually works:

C:\Users\dave>cmd /c mklink "c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg=" "c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg="
symbolic link created for c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg= <<===>> c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg=

procmon shows the command line in this case has the directories quoted:

cmd  /c mklink "c:\Users\dave\.config\emacs\straight\build-30.2\yasnippet-snippets\snippets\rust-mode\cfg=" "c:\Users\dave\.config\emacs\straight\repos\yasnippet-snippets\snippets\rust-mode\cfg="

Presumably my workaround forced the arguments to be quoted when added to the command line. Seems like this might happen in Emacs' sys_spawnve in w32proc.c. Just wrapping the arguments in double quotes doesn't work because Emacs' quoting then escapes those double quotes with ^s.

I've pushed up an alternate fix here that temporarily sets w32-quote-process-args to nil and wraps the arguments with double quotes. This works for installing the yasnippet-snippets package using symlinks. It seems like this fix should work for any path so long as it doesn't have " in the path itself.

@dgchurchill
Copy link
Author

Reflecting further perhaps the correct place for the fix is in Emacs in the windows sys_spawnve function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants