diff options
author | Christopher Faylor <me@cgf.cx> | 2001-09-17 18:10:02 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2001-09-17 18:10:02 +0000 |
commit | 8238a68bb202ebf40dfa479a798d2a23ac92b40c (patch) | |
tree | ecd83800cc69cab510a7bc30ae6623fc941a6df4 /winsup/cygwin | |
parent | 3e985c99c07bfdea2fb4cabe2662f64fe54c4a7b (diff) | |
download | newlib-8238a68bb202ebf40dfa479a798d2a23ac92b40c.zip newlib-8238a68bb202ebf40dfa479a798d2a23ac92b40c.tar.gz newlib-8238a68bb202ebf40dfa479a798d2a23ac92b40c.tar.bz2 |
* syscalls.cc (rmdir): Set cwd to some other location if attempting to rmdir
current working directory.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 5 | ||||
-rw-r--r-- | winsup/cygwin/dir.cc | 21 | ||||
-rw-r--r-- | winsup/cygwin/how-signals-work.txt | 18 |
3 files changed, 42 insertions, 2 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 54fe58d..83d4a9b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -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. diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index ab2bfab..7b9b2d6 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -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 ()) diff --git a/winsup/cygwin/how-signals-work.txt b/winsup/cygwin/how-signals-work.txt index ca1d8ef..710ce39 100644 --- a/winsup/cygwin/how-signals-work.txt +++ b/winsup/cygwin/how-signals-work.txt @@ -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(). |