* 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.
This commit is contained in:
parent
2a41ee9e0c
commit
125b724dd8
|
@ -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>
|
2005-05-24 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
* include/cygwin/version.h: Bump API minor number to 129.
|
* include/cygwin/version.h: Bump API minor number to 129.
|
||||||
|
|
|
@ -221,39 +221,21 @@ extern "C" int
|
||||||
mkdir (const char *dir, mode_t mode)
|
mkdir (const char *dir, mode_t mode)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
SECURITY_ATTRIBUTES sa = sec_none_nih;
|
fhandler_base *fh = NULL;
|
||||||
security_descriptor sd;
|
|
||||||
|
|
||||||
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);
|
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||||
goto done;
|
set_errno (fh->error ());
|
||||||
}
|
}
|
||||||
|
else if (!fh->mkdir (mode))
|
||||||
|
res = 0;
|
||||||
|
delete fh;
|
||||||
|
|
||||||
nofinalslash (real_dir.get_win32 (), real_dir.get_win32 ());
|
done:
|
||||||
|
|
||||||
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:
|
|
||||||
syscall_printf ("%d = mkdir (%s, %d)", res, dir, mode);
|
syscall_printf ("%d = mkdir (%s, %d)", res, dir, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -263,80 +245,21 @@ extern "C" int
|
||||||
rmdir (const char *dir)
|
rmdir (const char *dir)
|
||||||
{
|
{
|
||||||
int res = -1;
|
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)
|
if (fh->error ())
|
||||||
set_errno (real_dir.error);
|
|
||||||
else if (!real_dir.exists ())
|
|
||||||
set_errno (ENOENT);
|
|
||||||
else if (!real_dir.isdir ())
|
|
||||||
set_errno (ENOTDIR);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* Even own directories can't be removed if R/O attribute is set. */
|
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||||
if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY))
|
set_errno (fh->error ());
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (!fh->rmdir ())
|
||||||
|
res = 0;
|
||||||
|
delete fh;
|
||||||
|
|
||||||
|
done:
|
||||||
syscall_printf ("%d = rmdir (%s)", res, dir);
|
syscall_printf ("%d = rmdir (%s)", res, dir);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1509,6 +1509,28 @@ fhandler_base::set_nonblocking (int yes)
|
||||||
openflags = (openflags & ~O_NONBLOCK_MASK) | new_flags;
|
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 *
|
DIR *
|
||||||
fhandler_base::opendir ()
|
fhandler_base::opendir ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -346,6 +346,8 @@ class fhandler_base
|
||||||
void operator delete (void *);
|
void operator delete (void *);
|
||||||
virtual HANDLE get_guard () const {return NULL;}
|
virtual HANDLE get_guard () const {return NULL;}
|
||||||
virtual void set_eof () {}
|
virtual void set_eof () {}
|
||||||
|
virtual int mkdir (mode_t mode);
|
||||||
|
virtual int rmdir ();
|
||||||
virtual DIR *opendir ();
|
virtual DIR *opendir ();
|
||||||
virtual dirent *readdir (DIR *);
|
virtual dirent *readdir (DIR *);
|
||||||
virtual _off64_t telldir (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);
|
int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
||||||
bool fixup_mmap_after_fork (HANDLE h, DWORD access, int flags,
|
bool fixup_mmap_after_fork (HANDLE h, DWORD access, int flags,
|
||||||
_off64_t offset, DWORD size, void *address);
|
_off64_t offset, DWORD size, void *address);
|
||||||
|
int mkdir (mode_t mode);
|
||||||
|
int rmdir ();
|
||||||
DIR *opendir ();
|
DIR *opendir ();
|
||||||
struct dirent *readdir (DIR *);
|
struct dirent *readdir (DIR *);
|
||||||
_off64_t telldir (DIR *);
|
_off64_t telldir (DIR *);
|
||||||
|
|
|
@ -1138,6 +1138,108 @@ fhandler_disk_file::lock (int cmd, struct __flock64 *fl)
|
||||||
return 0;
|
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 *
|
DIR *
|
||||||
fhandler_disk_file::opendir ()
|
fhandler_disk_file::opendir ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -168,4 +168,3 @@ fhandler_dev_random::dump ()
|
||||||
{
|
{
|
||||||
paranoid_printf ("here, fhandler_dev_random");
|
paranoid_printf ("here, fhandler_dev_random");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue