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: shell-init: error retrieving current directory


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 16.08.2013 17:47, Corinna Vinschen wrote:
> On Aug 16 12:00, Andy Koppe wrote:
>> This might be the same issue as a couple of previous unresolved
>> reports with the same error message, but I'm not sure, so here's a new
>> thread.
>>
>> Steps to reproduce:
>> - On Windows 7, install 64-bit Cygwin into C:\cygwin, and let it
>> create a desktop shortcut.
>> - Edit /etc/fstab to change the cygdrive prefix to /.
>> - Double click 'Cygwin64 Terminal' desktop shortcut.
>>
>> Result: a bunch of errors before the bash prompt.
>>
>> shell-init: error retrieving current directory: getcwd: cannot access
>> parent directories: Bad file descriptor
>> job-working-directory: error retrieving current directory: getcwd:
>> cannot access parent directories: No such file or directory
>> job-working-directory: error retrieving current directory: getcwd:
>> cannot access parent directories: No such file or directory
>> job-working-directory: error retrieving current directory: getcwd:
>> cannot access parent directories: No such file or directory
>> chdir: error retrieving current directory: getcwd: cannot access
>> parent directories: No error
>>
>> The errors remain if the shortcut target is changed from invoking
>> mintty to invoking bash directly: 'C:\cygwin\bin\bash.exe -l'.
>>
>> The errors go away if 'C:\cygwin\bin' is put into the shortcut's
>> otherwise empty 'Start In' field. (But they stay if 'C:\' is put there
>> instead.)
>>
>> They also go away if the cygdrive prefix is changed to anything but
>> the root directory.
>>
>> I couldn't reproduce the issue with a 32-bit install.
> 
> I tried to find the cause for this issue, but as far as I can tell, it's
> not a problem in Cygwin.  For some reason bash seems to implement its
> own getcwd function, which plays a lot with calling stat on ., ..,
> ../.., etc.  All results from stat seem to make sense.  The error code
> itself (Bad file descriptor, etc) doesn't matter.  It's just some
> arbitrary value errno is set to at the time bash decides it doesn't like
> what the system calls return.  By tweaking the internal function which
> implements the core of the system getcwd function, I could return any
> error value at will.
> 
> Eric, can you please have a look into this issue?  Something's weird
> with bash's getcwd implementation which is apparently only triggered
> in the 64 bit version.

I've debugged this a bit, and here's what i see:
  Working directory is c:/foo

Bash does a stat on '/' and '.', remembers ino of '.' as 'thisino', ino
of '/' as 'rootino'. Same for dev (thisdev and rootdev).

Then does the following until it gets an error, or thisino == rootino &&
thisdev == rootdev (that is, until observed directory is '/'):
  dotp = '..'
  does stat on dotp ('..') (this is a stat on 'c:/' in our case)
  saves ino and dev to dotino and dotdev
  checks whether this directory is a mount point. It is a mount point
when dotdev != thisdev - that is, when going up the directory tree
caused a change in dev value. Whether this will work at all or not
depends on how Cygwin assigns dev numbers to directories.
  opens the directory dotp ('..'), which is c:/
  reads each entry in that directory, and for each entry that isn't '.'
or '..':
    if dotp was a mount point OR ino of the entry == thisino (that is,
it looks either for mount points, or for the previous directory, to
verify that '..' and previously observer directory are linked together
in the directory tree):
      grabs name of the entry, puts it into the buffer
      does lstat on the buffer, breaks the loop if stated ino and dev
match thisino and thisdev (i.e. checks for symlinks? not sure what's the
point)
  if an entry was found (i.e tree doesn't have holes):
    prepends name of the entry to cwd buffer
    updates thisdev and thisino
  otherwise:
    fails, returns NULL

next iteration:
  dotp = '../..'
  stat ('../..'). Due to cygwin's cleverness, this is a stat on
'c:/cygwin' (that is, '/'), not on 'c:/' (which it would normally be on
W32 - can't go above c:/)
  checks for mountpoints (not a mountpoint, at least in my case - there
was a transision from c:/ up to /, but dev didn't change) - not a mount
point
  opens the directory dotp ('../..'), which is 'c:/cygwin' or '/'
  reads each entry:
    checks whether the entry is the directory from the previous
iteration ('c:/'). This check always fails, because Cygwin doesn't list
/c in /
  since no entry is found, and this was not a mount point, getcwd()
fails and returns NULL


I remember someone pointing out that not listing local disks mountpoints
in / when cygdrive prefix is empty is a feature. Maybe not so much...

You might be able to fix this by forcing / to have a different dev number.


- -- 
O< ascii ribbon - stop html email! - www.asciiribbon.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (MingW32)

iQEcBAEBAgAGBQJSFSJgAAoJEOs4Jb6SI2CwgtoH/jAqrEy8BcFzV02D462kym3W
UXy39lBDnCGTl+mO9u3E+eNAH8SKvzdHyYk8y9sBrt2TTd9HZJMz6X9IgRRsTG/E
vUNXlh6O8i2/iK+aJcD1IfBo3CTA37N3VeHWCebPiMyGzjBM6cGqi0ycLGh8vpAj
qqV6zGpAzBEJv1gNEcjG49kk6OYsM//bGqDxRzP5nZvJFuGOlaGN0G3/X+6fq2Q7
ApT1VDb5JZ2FAzVdxh+j8bBbYJJ/gyDUrjCQXrBWSQC5PW3YRvA4z73a8IGspnkw
kXK+dE9MYyBvLLFjMjmjrZn1PNVvGypHsgh820EJQlZv90wFuDzr4y99q2hU5pQ=
=/iJK
-----END PGP SIGNATURE-----

--
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]