From ea4e6ec8f9fe4a784d4ce2ef71037e05fb9a876d Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 5 Jun 2002 16:01:55 +0000 Subject: [PATCH] * dir.cc (rmdir): Streamline. Detect attempts to remove directories from "read-only" virtual devices. (Suggested by Pavel Tsekov) * syscalls.cc (unlink): Detect attempts to remove directories from "read-only" virtual devices. (From Pavel Tsekov) --- winsup/cygwin/ChangeLog | 9 +++++++- winsup/cygwin/dir.cc | 43 ++++++++++++++++----------------------- winsup/cygwin/syscalls.cc | 8 ++++++++ 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 022f4190d..958c5d3d1 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2002-06-05 Christopher Faylor + + * dir.cc (rmdir): Streamline. Detect attempts to remove directories + from "read-only" virtual devices. (Suggested by Pavel Tsekov) + * syscalls.cc (unlink): Detect attempts to remove directories + from "read-only" virtual devices. (From Pavel Tsekov) + 2002-06-05 Christopher Faylor * dtable.cc (handle_to_fn): Check error return value from NtQueryObject @@ -61,7 +68,7 @@ 2002-06-04 Christopher Faylor * dtable.cc (handle_to_fn): Correct placement and length of name - buffer. (Suggested by Pavel Tsekov) + buffer. (Suggested by Pavel Tsekov) 2002-06-04 Christopher Faylor diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index c9509b65a..45ba57ff6 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -273,24 +273,19 @@ extern "C" int rmdir (const char *dir) { int res = -1; + DWORD devn; path_conv real_dir (dir, PC_SYM_NOFOLLOW); if (real_dir.error) - { - set_errno (real_dir.error); - res = -1; - } + set_errno (real_dir.error); + else if ((devn = real_dir.get_devn ()) == FH_PROC || devn == FH_REGISTRY + || devn == FH_PROCESS) + set_errno (EROFS); else if (!real_dir.exists ()) - { - set_errno (ENOENT); - res = -1; - } + set_errno (ENOENT); else if (!real_dir.isdir ()) - { - set_errno (ENOTDIR); - res = -1; - } + set_errno (ENOTDIR); else { /* Even own directories can't be removed if R/O attribute is set. */ @@ -330,22 +325,20 @@ rmdir (const char *dir) else if ((res = rmdir (dir))) SetCurrentDirectory (cygheap->cwd.win32); } - if (GetLastError () == ERROR_ACCESS_DENIED) + if (res) { - - /* On 9X ERROR_ACCESS_DENIED is returned if you try to remove - a non-empty directory. */ - if (wincap.access_denied_on_delete ()) - set_errno (ENOTEMPTY); - else + if (GetLastError () != ERROR_ACCESS_DENIED + || !wincap.access_denied_on_delete ()) __seterrno (); - } - else - __seterrno (); + else + set_errno (ENOTEMPTY); /* On 9X ERROR_ACCESS_DENIED is + returned if you try to remove a + non-empty directory. */ - /* If directory still exists, restore R/O attribute. */ - if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY)) - SetFileAttributes (real_dir, real_dir); + /* If directory still exists, restore R/O attribute. */ + if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY)) + SetFileAttributes (real_dir, real_dir); + } } } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 9e28d104e..bf2709d06 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -94,6 +94,7 @@ extern "C" int _unlink (const char *ourname) { int res = -1; + DWORD devn; sigframe thisframe (mainthread); path_conv win32_name (ourname, PC_SYM_NOFOLLOW | PC_FULL); @@ -104,6 +105,13 @@ _unlink (const char *ourname) goto done; } + if ((devn = win32_name.get_devn ()) == FH_PROC || devn == FH_REGISTRY + || devn == FH_PROCESS) + { + set_errno (EROFS); + goto done; + } + syscall_printf ("_unlink (%s)", win32_name.get_win32 ()); if (!win32_name.exists ())