Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-05-25 08:32:59 +0400
committerChristopher Faylor <me@cgf.cx>2005-05-25 08:32:59 +0400
commit125b724dd8cec4f83445e8349dfbb8c7e06e1816 (patch)
treec170bdb4fcf7f807a9cd0d5e8db0e58f43fe1970 /winsup/cygwin
parent2a41ee9e0c97a23d472004a5dd8a951dc3be4728 (diff)
* fhandler.h (fhandler_base::mkdir): New virtual method.
(fhandler_base::rmdir): Ditto. (fhandler_disk_file:mkdir): New method. (fhandler_disk_file:rmdir): Ditto. * dir.cc (mkdir): Implement with fhandlers. (rmdir): Ditto. * fhandler.cc (fhandler_base::mkdir): New virtual method. (fhandler_base::rmdir): Ditto. (fhandler_disk_file::mkdir): New method. (fhandler_disk_file::rmdir): Ditto. fhandler_random.cc: white space.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog13
-rw-r--r--winsup/cygwin/dir.cc117
-rw-r--r--winsup/cygwin/fhandler.cc22
-rw-r--r--winsup/cygwin/fhandler.h4
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc102
-rw-r--r--winsup/cygwin/fhandler_random.cc1
6 files changed, 161 insertions, 98 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c1357eb69..8333b4cbd 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,16 @@
+2005-05-25 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * fhandler.h (fhandler_base::mkdir): New virtual method.
+ (fhandler_base::rmdir): Ditto.
+ (fhandler_disk_file:mkdir): New method.
+ (fhandler_disk_file:rmdir): Ditto.
+ * dir.cc (mkdir): Implement with fhandlers.
+ (rmdir): Ditto.
+ * fhandler.cc (fhandler_base::mkdir): New virtual method.
+ (fhandler_base::rmdir): Ditto.
+ (fhandler_disk_file::mkdir): New method.
+ (fhandler_disk_file::rmdir): Ditto.
+
2005-05-24 Christopher Faylor <cgf@timesys.com>
* include/cygwin/version.h: Bump API minor number to 129.
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
index df0515220..c6a6bc6e6 100644
--- a/winsup/cygwin/dir.cc
+++ b/winsup/cygwin/dir.cc
@@ -221,39 +221,21 @@ extern "C" int
mkdir (const char *dir, mode_t mode)
{
int res = -1;
- SECURITY_ATTRIBUTES sa = sec_none_nih;
- security_descriptor sd;
+ fhandler_base *fh = NULL;
- path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_WRITABLE);
+ if (!(fh = build_fh_name (dir, NULL, PC_SYM_NOFOLLOW | PC_WRITABLE)))
+ goto done; /* errno already set */;
- if (real_dir.error)
+ if (fh->error ())
{
- set_errno (real_dir.case_clash ? ECASECLASH : real_dir.error);
- goto done;
+ debug_printf ("got %d error from build_fh_name", fh->error ());
+ set_errno (fh->error ());
}
+ else if (!fh->mkdir (mode))
+ res = 0;
+ delete fh;
- nofinalslash (real_dir.get_win32 (), real_dir.get_win32 ());
-
- if (allow_ntsec && real_dir.has_acls ())
- set_security_attribute (S_IFDIR | ((mode & 07777) & ~cygheap->umask),
- &sa, sd);
-
- if (CreateDirectoryA (real_dir.get_win32 (), &sa))
- {
- if (!allow_ntsec && allow_ntea)
- set_file_attribute (false, NULL, real_dir.get_win32 (),
- S_IFDIR | ((mode & 07777) & ~cygheap->umask));
-#ifdef HIDDEN_DOT_FILES
- char *c = strrchr (real_dir.get_win32 (), '\\');
- if ((c && c[1] == '.') || *real_dir.get_win32 () == '.')
- SetFileAttributes (real_dir.get_win32 (), FILE_ATTRIBUTE_HIDDEN);
-#endif
- res = 0;
- }
- else
- __seterrno ();
-
-done:
+ done:
syscall_printf ("%d = mkdir (%s, %d)", res, dir, mode);
return res;
}
@@ -263,80 +245,21 @@ extern "C" int
rmdir (const char *dir)
{
int res = -1;
+ fhandler_base *fh = NULL;
- path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_WRITABLE);
+ if (!(fh = build_fh_name (dir, NULL, PC_SYM_NOFOLLOW | PC_WRITABLE)))
+ goto done; /* errno already set */;
- if (real_dir.error)
- set_errno (real_dir.error);
- else if (!real_dir.exists ())
- set_errno (ENOENT);
- else if (!real_dir.isdir ())
- set_errno (ENOTDIR);
- else
+ if (fh->error ())
{
- /* Even own directories can't be removed if R/O attribute is set. */
- if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY))
- SetFileAttributes (real_dir,
- (DWORD) real_dir & ~FILE_ATTRIBUTE_READONLY);
-
- for (bool is_cwd = false; ; is_cwd = true)
- {
- DWORD err;
- int rc = RemoveDirectory (real_dir);
- DWORD att = GetFileAttributes (real_dir);
-
- /* Sometimes smb indicates failure when it really succeeds, so check for
- this case specifically. */
- if (rc || att == INVALID_FILE_ATTRIBUTES)
- {
- /* RemoveDirectory on a samba drive doesn't return an error if the
- directory can't be removed because it's not empty. Checking for
- existence afterwards keeps us informed about success. */
- if (att == INVALID_FILE_ATTRIBUTES)
- {
- res = 0;
- break;
- }
- err = ERROR_DIR_NOT_EMPTY;
- }
- else
- err = GetLastError ();
-
- /* 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. (Actually it does on 9X.)
- 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)
- && !is_cwd
- && SetCurrentDirectory ("c:\\"))
- continue;
-
- /* On 9X ERROR_ACCESS_DENIED is returned
- if you try to remove a non-empty directory. */
- if (err == ERROR_ACCESS_DENIED
- && wincap.access_denied_on_delete ())
- err = ERROR_DIR_NOT_EMPTY;
-
- __seterrno_from_win_error (err);
-
- /* Directory still exists, restore its characteristics. */
- if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY))
- SetFileAttributes (real_dir, real_dir);
- if (is_cwd)
- SetCurrentDirectory (real_dir);
- break;
- }
+ debug_printf ("got %d error from build_fh_name", fh->error ());
+ set_errno (fh->error ());
}
+ else if (!fh->rmdir ())
+ res = 0;
+ delete fh;
+ done:
syscall_printf ("%d = rmdir (%s)", res, dir);
return res;
}
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index ba81cd3a6..6c0eaec38 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -1509,6 +1509,28 @@ fhandler_base::set_nonblocking (int yes)
openflags = (openflags & ~O_NONBLOCK_MASK) | new_flags;
}
+int
+fhandler_base::mkdir (mode_t)
+{
+ if (exists ())
+ set_errno (EEXIST);
+ else
+ set_errno (EROFS);
+ return -1;
+}
+
+int
+fhandler_base::rmdir ()
+{
+ if (!exists ())
+ set_errno (ENOENT);
+ else if (!pc.isdir ())
+ set_errno (ENOTDIR);
+ else
+ set_errno (EROFS);
+ return -1;
+}
+
DIR *
fhandler_base::opendir ()
{
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index c51144308..ff2f315e3 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -346,6 +346,8 @@ class fhandler_base
void operator delete (void *);
virtual HANDLE get_guard () const {return NULL;}
virtual void set_eof () {}
+ virtual int mkdir (mode_t mode);
+ virtual int rmdir ();
virtual DIR *opendir ();
virtual dirent *readdir (DIR *);
virtual _off64_t telldir (DIR *);
@@ -664,6 +666,8 @@ class fhandler_disk_file: public fhandler_base
int msync (HANDLE h, caddr_t addr, size_t len, int flags);
bool fixup_mmap_after_fork (HANDLE h, DWORD access, int flags,
_off64_t offset, DWORD size, void *address);
+ int mkdir (mode_t mode);
+ int rmdir ();
DIR *opendir ();
struct dirent *readdir (DIR *);
_off64_t telldir (DIR *);
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index e5b79e80b..e1ec5b377 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -1138,6 +1138,108 @@ fhandler_disk_file::lock (int cmd, struct __flock64 *fl)
return 0;
}
+int
+fhandler_disk_file::mkdir (mode_t mode)
+{
+ int res = -1;
+ SECURITY_ATTRIBUTES sa = sec_none_nih;
+ security_descriptor sd;
+
+ if (allow_ntsec && has_acls ())
+ set_security_attribute (S_IFDIR | ((mode & 07777) & ~cygheap->umask),
+ &sa, sd);
+
+ if (CreateDirectoryA (get_win32_name (), &sa))
+ {
+ if (!allow_ntsec && allow_ntea)
+ set_file_attribute (false, NULL, get_win32_name (),
+ S_IFDIR | ((mode & 07777) & ~cygheap->umask));
+#ifdef HIDDEN_DOT_FILES
+ char *c = strrchr (real_dir.get_win32 (), '\\');
+ if ((c && c[1] == '.') || *get_win32_name () == '.')
+ SetFileAttributes (get_win32_name (), FILE_ATTRIBUTE_HIDDEN);
+#endif
+ res = 0;
+ }
+ else
+ __seterrno ();
+
+ return res;
+}
+
+int
+fhandler_disk_file::rmdir ()
+{
+ int res = -1;
+
+ /* Even own directories can't be removed if R/O attribute is set. */
+ if (pc.has_attribute (FILE_ATTRIBUTE_READONLY))
+ SetFileAttributes (get_win32_name (),
+ (DWORD) pc & ~FILE_ATTRIBUTE_READONLY);
+
+ for (bool is_cwd = false; ; is_cwd = true)
+ {
+ DWORD err, att = 0;
+ int rc = RemoveDirectory (get_win32_name ());
+
+ if (isremote () && exists ())
+ att = GetFileAttributes (get_win32_name ());
+
+ /* Sometimes smb indicates failure when it really succeeds, so check for
+ this case specifically. */
+ if (rc || att == INVALID_FILE_ATTRIBUTES)
+ {
+ /* RemoveDirectory on a samba drive doesn't return an error if the
+ directory can't be removed because it's not empty. Checking for
+ existence afterwards keeps us informed about success. */
+ if (!isremote () || att == INVALID_FILE_ATTRIBUTES)
+ {
+ res = 0;
+ break;
+ }
+ err = ERROR_DIR_NOT_EMPTY;
+ }
+ else
+ err = GetLastError ();
+
+ /* 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. (Actually it does on 9X.)
+ FIXME: A potential workaround for this is for cygwin apps to *never* call
+ SetCurrentDirectory. */
+
+ extern char windows_system_directory[];
+ if (strcasematch (get_win32_name (), cygheap->cwd.win32)
+ && !strcasematch (windows_system_directory, cygheap->cwd.win32)
+ && !is_cwd
+ && SetCurrentDirectory (windows_system_directory))
+ continue;
+
+ /* On 9X ERROR_ACCESS_DENIED is returned
+ if you try to remove a non-empty directory. */
+ if (err == ERROR_ACCESS_DENIED
+ && wincap.access_denied_on_delete ())
+ err = ERROR_DIR_NOT_EMPTY;
+
+ __seterrno_from_win_error (err);
+
+ /* Directory still exists, restore its characteristics. */
+ if (pc.has_attribute (FILE_ATTRIBUTE_READONLY))
+ SetFileAttributes (get_win32_name (), (DWORD) pc);
+ if (is_cwd)
+ SetCurrentDirectory (get_win32_name ());
+ break;
+ }
+
+ return res;
+}
+
DIR *
fhandler_disk_file::opendir ()
{
diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc
index 6de3baac7..abca009f3 100644
--- a/winsup/cygwin/fhandler_random.cc
+++ b/winsup/cygwin/fhandler_random.cc
@@ -168,4 +168,3 @@ fhandler_dev_random::dump ()
{
paranoid_printf ("here, fhandler_dev_random");
}
-