* syscalls.cc (rmdir): Set cwd to some other location if attempting to rmdir
current working directory.
This commit is contained in:
		@@ -1,3 +1,8 @@
 | 
			
		||||
Mon Sep 17 14:04:27 2001  Christopher Faylor <cgf@cygnus.com>
 | 
			
		||||
 | 
			
		||||
	* syscalls.cc (rmdir): Set cwd to some other location if attempting to
 | 
			
		||||
	rmdir current working directory.
 | 
			
		||||
 | 
			
		||||
Sun Sep 16 23:04:31 2001  Christopher Faylor <cgf@cygnus.com>
 | 
			
		||||
 | 
			
		||||
	* dtable.h (not_open): Assure inline.
 | 
			
		||||
 
 | 
			
		||||
@@ -401,8 +401,29 @@ rmdir (const char *dir)
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* This kludge detects if we are attempting to remove the current working
 | 
			
		||||
         directory.  If so, we will move elsewhere to potentially allow the
 | 
			
		||||
	 rmdir to succeed.  This means that cygwin's concept of the current working
 | 
			
		||||
	 directory != Windows concept but, hey, whaddaregonnado?
 | 
			
		||||
	 Note that this will not cause something like the following to work:
 | 
			
		||||
		 $ cd foo
 | 
			
		||||
		 $ rmdir .
 | 
			
		||||
         since the shell will have foo "open" in the above case and so Windows will
 | 
			
		||||
	 not allow the deletion.
 | 
			
		||||
	 FIXME: A potential workaround for this is for cygwin apps to *never* call
 | 
			
		||||
	 SetCurrentDirectory. */
 | 
			
		||||
      if (strcasematch (real_dir, cygheap->cwd.win32)
 | 
			
		||||
	  && !strcasematch ("c:\\", cygheap->cwd.win32))
 | 
			
		||||
	{
 | 
			
		||||
	  DWORD err = GetLastError ();
 | 
			
		||||
	  if (!SetCurrentDirectory ("c:\\"))
 | 
			
		||||
	    SetLastError (err);
 | 
			
		||||
	  else
 | 
			
		||||
	    return rmdir (dir);
 | 
			
		||||
	}
 | 
			
		||||
      if (GetLastError() == ERROR_ACCESS_DENIED)
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
	  /* On 9X ERROR_ACCESS_DENIED is returned if you try to remove
 | 
			
		||||
	     a non-empty directory. */
 | 
			
		||||
	  if (wincap.access_denied_on_delete ())
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
Copyright 2001 Red Hat Inc., Christopher Faylor
 | 
			
		||||
 | 
			
		||||
[This is not yet complete. -cgf]
 | 
			
		||||
 | 
			
		||||
How do signals work?
 | 
			
		||||
 | 
			
		||||
On process startup, cygwin starts a secondary thread that deals with signals.
 | 
			
		||||
@@ -111,3 +109,19 @@ arrival is more or less maintained.  It checks to see if a cygwin
 | 
			
		||||
routine has set a special "restore this errno on returning from a
 | 
			
		||||
signal" value and sets errno to this, if so.  Finally, it restores all
 | 
			
		||||
of the register values that were in effect when sigdelayed was called.
 | 
			
		||||
 | 
			
		||||
Ok, you thought I had forgotten about the 'pending' stuff didn't you?
 | 
			
		||||
Well, if you can rewind up to the discussion of sig_handle we'll return
 | 
			
		||||
to the situation where sigsave was currently active.  In this case,
 | 
			
		||||
setup_handler will set a "pending" flag, will reincrement the appropriate
 | 
			
		||||
element of the above signal array, and will return 0 to indicate that
 | 
			
		||||
the interrupt did not occur.  Otherwise setup_handler returns 1.
 | 
			
		||||
 | 
			
		||||
For pending signals, the theory is that the signal handler thread will
 | 
			
		||||
be forced to be rerun by having some strategic cygwin function call
 | 
			
		||||
sig_send with a __SIGFLUSH argument.  This causes the signal handler
 | 
			
		||||
to rescan the signal array looking for pending signals.
 | 
			
		||||
 | 
			
		||||
This leads us to the sig_send function.  This is the "client side" part
 | 
			
		||||
of the signal manipulation process.  sig_send is the low-level function
 | 
			
		||||
called by a high level process like kill().
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user