Accessing a cygwin symlink from windows - linux

I am quite new to cygwin. I created a symlink as follows
$ ln -s /var/www /cygdrive/d/foo
and when I check the D drive via windows, I see a system file called foo. Is there a way to make foo act as a folder for Windows instead of a system file?

Windows won't be able to read Cygwin-created symlinks, but you can create Windows symlinks using Windows commands, and Cygwin will treat those as symlinks.
On Vista and 7, this can be done with 'mklink'. This is a cmd.exe builtin rather than a standalone utility, so if you want to invoke it from a bash shell you have to do 'cmd /c mklink', and of course it will only understand Windows paths.
For XP, the 'Windows Resource Kit Tools' contain a utility called linkd that can be used to create directory links.

Not that I know of. Cygwin doesn't update the OS to have symlinks, rather, it allows you to 'fake' symlinks from within the Cygwin shell. You can set up the shell to use Windows LNK files, which may do what you want, but ...
From the Cygwin Documentation:
Creating shortcuts with cygutils
Another problem area is between
Unix-style links, which link one file
to another, and Microsoft .lnk files,
which provide a shortcut to a file.
They seem similar at first glance but,
in reality, are fairly different. By
default, Cygwin does not create
symlinks as .lnk files, but there's an
option to do that, see the section
called “The CYGWIN environment
variable”. These symlink .lnk files
are compatible with Windows-created
.lnk files, but they are still
different. They do not include much of
the information that is available in a
standard Microsoft shortcut, such as
the working directory, an icon, etc.
The cygutils package includes a
mkshortcut utility for creating
standard native Microsoft .lnk files.
But here's the problem. If Cygwin
handled these native shortcuts like
any other symlink, you could not
archive Microsoft .lnk files into tar
archives and keep all the information
in them. After unpacking, these
shortcuts would have lost all the
extra information and would be no
different than standard Cygwin
symlinks. Therefore these two types of
links are treated differently.
Unfortunately, this means that the
usual Unix way of creating and using
symlinks does not work with native
Windows shortcuts.

One alternative way to call mklink (/d creates directory link) without function:
link_name="/cygdrive/c/TestLink"
target_dir="/cygwin/c/Windows"
cmd /c mklink /d "`cygpath -w \"$link_name\"`" "`cygpath -w \"$target_dir\"`"
This example uses backticks (`command`) for command substitution.

Related

Access linux paths in windows git powershell

I am running a Windows Powershell provided through the git for windows installation. This shell provides many unix style commands (i.e. "ls", "mv", etc.).
My question is: How do I access Unix style paths from the powershell cmd line on Windows?
Consider this example: the "ls" program is installed and works in the powershell. The path is shown as "/usr/bin/ls" if I type "which ls" as the cmd prompt. But if I try to change my current directory using "cd /usr/bin/", the shell complains that the path is not found.
I can't see any mounted volumes or anything like that using "mount" (perhaps in PowerShell it is a different command?).
I'm asking this question because I have other files that I need to get to which are listed under unix-style paths, and right now I can't get to anything. I figure if I can get to /usr/bin, then I can figure out how to get where I really need to go.
Powershell is not Unix. It may have a few familiar commands like "ls" and "ps", but that's where the similarity ends.
When you installed Git For Windows, you likely installed the Git Bash shell as well. Run that instead to get a more Unix like atmosphere. (Re-install Git For Windows if you didn't select this option on install).
But even with Git Bash, there's still no such folder as /usr/bin. That folder doesn't exist on Windows. If you want a Unix emulation on Windows that includes the traditional folder structure, use Cygwin. And you can run Git on that environment too and access an emulated /usr/bin folder.

Windows Linux Subsystem - File permissions when edited outside bash [duplicate]

As the title suggests, if I paste a c file written somewhere else into the root directory of the Linux Subsystem, I can't compile it.
I did a test where I made two differently titled hello world programs: one in vi that I can get into from the bash interface, and one elsewhere. When I compiled the one made in vi, it worked fine. Trying to do so for the one made elsewhere (after pasting it into the root directory), however, resulted in this:
gcc: error: helloWorld2.c: Input/output error
gcc: fatal error: no input files
compilation terminated
Any help with this would be much appreciated.
Do not change Linux files using Windows apps and tools!
Assuming what you meant by "paste a C file written somewhere else into the root directory of the Linux subsystem" is that you pasted your file into %localappdata%\lxss, this is explicitly unsupported. Files natively created via Linux syscalls in this area have UNIX metadata, which files natively created with Windows tools don't have.
Use /mnt/c (and the like) to access your Windows files from Linux; don't try to modify Linux files from Windows.
Quoting from the Microsoft blog linked at the top of this answer (emphasis from the original):
Therefore, be sure to follow these two rules in order to avoid losing files, and/or corrupting your data:
DO store files in your Windows filesystem that you want to create/modify using Windows tools AND Linux tools
DO NOT create / modify Linux files from Windows apps, tools, scripts or consoles
You cannot copy (by default, who knows how Windows bash is set up!) files into the root directory! Your gcc error is say "no input files", so the copy has most likely failed. Copy the files to your home directory instead, for instance:
cp helloWorld2.c ~/
instead of:
cp helloWorld2.c /

Who handles the paths in Cygwin

I am curious to find out who handles the paths in cygwin.
For instance if I do the following, it works:
cd C:\
However when I do:
$ pwd
/cygdrive/c
Who is responsible for the discrepancy here?
The reason I am curious is that "cd C:" among'st other tools accept windows paths but when it comes to displaying them they show something different.
If I do include the cygwin bin folder in my path (under regular cmd) then I know it all works as in cmd, so what is it thats causing this convertion, is it the bash/shell?
I am curious to find out who handles the paths in cygwin.
Largely, a small bit of C++ code in winsup/cygwin/path.cc. A particularly important function is normalize_posix_path. This code ends up compiled in the DLL cygwin1.dll which is used by all Cygwin applications.
All paths in Cygwin are "POSIX" paths resolved by the Cygwin DLL itself. The normalize_posix_path function recognizes the presence of certain syntax in paths (drive letter names and backslashes), and arranges for them to be treated as "Win32 paths".
That is the reason why you can feed c:/Users/... to a Cygwin program, as an alternative to /cygdrive/c/Users/....
$ pwd
/cygdrive/c
How this works is that Cygwin maintains a native Win32 current working directory, and so it knows perfectly well that this is C:\. However, this native information is mapped backwards to a POSIX path. Cygwin does this by scanning through its mount table where it sees that C:\ is "mounted" as /cygdrive/c. (The pwd utility is just reporting what Cygwin's implementation of the POSIX getcwd function is returning. The backwards mapping happens inside that function). Note that since Cygwin is operating in a virtual POSIX namespace created by its mount table, that space contains abstract places which have no Win32 native counterpart. For instance, you can cd to the /dev directory where you have entries like tty. This has no native location, and so getcwd will just report the POSIX path. Cygwin tries to keep the Cygwin-internal current working directory in sync with the Win32 one when there is a corespondence; it does so without using the SetCurrentDirectory Win32 function, and without maintaining the concept that Windows drives have individual current working directories.
If I do include the cygwin bin folder in my path (under regular cmd) then I know it all works as in cmd, so what is it thats causing this convertion, is it the bash/shell?
Actually, it does not all work as in cmd! Though Cygwin programs understand "Win32-ish" paths, the support is not complete. You can pass a path like D:file.txt to a truly native Windows program. It resolves via the current directory associated with the D drive, which could be D:\bob\documents, in which case the path stands for D:\bob\documents\file.txt. If there is no such directory then it stands for D:\file.txt. A Cygwin program will not understand this drive-relative path. In fact, D:file.txt won't even be recognized as a drive-letter reference (as of Cygwin 2.5.2). This is because the colon is not followed by a directory separator character (backslash or slash).

Setting Working Directory to Desktop in Cygwin

The current directory on cygwin is home/myuser. I navigated to cygwin and found it has a directory called home/myuser and could not figure out how I would navigate to the desktop. I did not want to add a desktop directory there and I could not navigate above the root folder (cygwin). Any idea on how I could do this?
This is essentially covered in the Cygwin FAQ under "How can I access other drives?". No, you're not trying to access another drive, but you are trying to access a folder outside of the Cygwin tree. As the FAQ item says, Cygwin maps your Windows drives as /cygdrive/<drive-letter>, so your desktop is likely something like /cygdrive/c/Users/<username>/Desktop. Note that the path has changed over the years with various versions of Windows and you didn't specify what version you're running, so it may not be exactly that.
Anyway, what I would do, would be to create a symbolic link to that from my Cygwin home folder. Something like this:
ln -s "/cygdrive/c/Users/<username>/Desktop" Desktop
I put the quotes in because depending on what version of windows you have, this path may include spaces.
You'll probably notice from the FAQ that the Cygwin version of bash accepts DOS-style pathnames, so you can actually do the following:
cd "C:/Users/<username>/Desktop"
But I recommend avoiding such syntax. Not all Cygwin apps understand DOS-style paths, and you'll only end up confusing yourself if you have to try to figure out whether what you're doing will work with a DOS-style path or not. It's best to just use the Unix-style paths for everything when in the Cygwin environment, unless you have a very good reason not to.
Add
cd "/cygdrive/c/Users/<username>/Desktop"
to .bashrc file located in <cygwin install directory>/home/<username>. This will change working directory to desktop every time you open Cygwin terminal.

Why are Cygwin import libraries installed with mode 755?

I have a library that I originally developed for Linux. I am now in the process of porting it to Cygwin. I have noticed that every library on my Cygwin system is installed like this:
DLL (cygfoo.dll) installed to /usr/bin mode 755
Static archive (libfoo.a) installed to /usr/lib mode 644
Import library (libfoo.dll.a) installed to /usr/lib mode 755
The first two make perfect sense to me. DLLs are executables so they should be mode 755. Static archives are not executables, so they are mode 644. The third one, however, seems odd to me. Import libraries are in fact static archives, not executables (ar -t libfoo.dll.a lists the contents of the archive). Shouldn't they also be installed mode 644?
Why is it the convention on Cygwin to install import libraries with mode 755?
Back to 2000:
On NTFS partitions, NT/W2K require the execute permission for DLLs to
allow loading a DLL on process startup.
That's no problem unless a person using ntsec gets a tar archive
packed by a person not using ntsec or packing on a FAT partition.
Since Cygwin fakes the execute permission only for the suffixes "exe",
"bat", "com", DLLs are treated as non executable by the stat() call
when ntsec isn't set.
When a person using ntsec unpacks that tar archive, the start of an
application which requires one of the DLLs from the archive will fail
with the Windows message
"The application failed to initialize properly (0xc0000022)"
which isn't that meaningful for most of the users.
To solve that problem we would have to do a simple step. Fake execute
permissions for DLLs when ntsec isn't set or the file system doesn't
support ACLs (FAT/FAT32).
Here: http://cygwin.com/ml/cygwin-developers/2000-10/msg00044.html
The only answer that occurs to me is that the installer is looking for the ".dll" string in the filename to activate the executable attribute (x) of the copied files... should been looking for /.+\.dll$/ (.dll only at the end).
It is understandable that the impedance mismatch between OS's/filesystems force the installer/copier to have a strategy to decide attribute values at the installer operation (it is easier than have to map a attribute list to the copied file... and in windows only have to look for .exe, .com and .dll)
To confirm this rename your "libfoo.dll.a" to "libfoo.dxx.a" and test it...
This is a Windows requirement: since the .dll file contains code that will be executed, it requires the executable bit to be set.
Remove permission to execute the file, and Windows won't let any of the code inside it be executed, even if the process doing the executing is separate.
Side note: it's a common misconception that there's no +x bit for Windows. That's technically true; Windows doesn't use POSIX rwx permissions, although Cygwin does try to provide an interface that resembles them. Windows does use ACLs (Access Control Lists) for permissions, however, and these do have a concept of "execute permissions", which is what Cygwin maps down to its +x bit.
There's a long discussion on the Cygwin mailing list about this, if you want sources/further reading.
Seems it's just a lazy hack resulting in this behavior for filenames containing ".dll". See hasanyasin's answer for the reasoning behind the "fix" (here).

Resources