OSDN Git Service

* syscalls.cc (rmdir): Set cwd to some other location if attempting to rmdir
authorcgf <cgf>
Mon, 17 Sep 2001 18:10:02 +0000 (18:10 +0000)
committercgf <cgf>
Mon, 17 Sep 2001 18:10:02 +0000 (18:10 +0000)
current working directory.

winsup/cygwin/ChangeLog
winsup/cygwin/dir.cc
winsup/cygwin/how-signals-work.txt

index 54fe58d..83d4a9b 100644 (file)
@@ -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.
index ab2bfab..7b9b2d6 100644 (file)
@@ -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 ())
index ca1d8ef..710ce39 100644 (file)
@@ -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().