* delqueue.cc: Delete.
* fhandler.h (fhandler_base::close_fs): Drop declaration.
(fhandler_disk_file::close): Drop declaration.
* fhandler_disk_file.cc (fhandler_base::fstat_fs): Call close instead of
close_fs.
(fhandler_base::fstat_helper): Use open FH_UNIX handle in call to
get_file_attribute.
(fhandler_base::open_fs): Call close instead of get_file_attribute.
(fhandler_disk_file::close): Remove.
(fhandler_base::close_fs): Remove.
* fhandler_socket.cc (fhandler_socket::close): Just call
fhandler_base::close for FH_UNIX sockets.
* shared.cc (user_shared_initialize): Drop call to
user_shared->delqueue.init.
* shared_info.h (CURR_USER_MAGIC): Change according to below change.
(MAX_DELQUEUES_PENDING): Remove.
(class delqueue_list): Remove.
(class user_info): Remove delqueue.
* syscalls.cc (close_all_files): Drop call to
user_shared->delqueue.process_queue.
(unlink): Drop delqueue handling.
+2007-08-13 Corinna Vinschen <corinna@vinschen.de>
+
+ * Makefile.in (DLL_OFILES): Remove delqueue.o.
+ * delqueue.cc: Delete.
+ * fhandler.h (fhandler_base::close_fs): Drop declaration.
+ (fhandler_disk_file::close): Drop declaration.
+ * fhandler_disk_file.cc (fhandler_base::fstat_fs): Call close instead of
+ close_fs.
+ (fhandler_base::fstat_helper): Use open FH_UNIX handle in call to
+ get_file_attribute.
+ (fhandler_base::open_fs): Call close instead of get_file_attribute.
+ (fhandler_disk_file::close): Remove.
+ (fhandler_base::close_fs): Remove.
+ * fhandler_socket.cc (fhandler_socket::close): Just call
+ fhandler_base::close for FH_UNIX sockets.
+ * shared.cc (user_shared_initialize): Drop call to
+ user_shared->delqueue.init.
+ * shared_info.h (CURR_USER_MAGIC): Change according to below change.
+ (MAX_DELQUEUES_PENDING): Remove.
+ (class delqueue_list): Remove.
+ (class user_info): Remove delqueue.
+ * syscalls.cc (close_all_files): Drop call to
+ user_shared->delqueue.process_queue.
+ (unlink): Drop delqueue handling.
+
2007-08-13 Corinna Vinschen <corinna@vinschen.de>
* devices.in (dev_storage): Use native NT device name for kmsg mailslot.
# Please maintain this list in sorted order, with maximum files per 86 col line
#
DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \
- cygtls.o dcrt0.o debug.o delqueue.o devices.o dir.o dlfcn.o dll_init.o \
+ cygtls.o dcrt0.o debug.o devices.o dir.o dlfcn.o dll_init.o \
dtable.o environ.o errno.o exceptions.o exec.o external.o fcntl.o \
fhandler.o fhandler_clipboard.o fhandler_console.o fhandler_disk_file.o \
fhandler_dsp.o fhandler_fifo.o fhandler_floppy.o fhandler_mailslot.o \
+++ /dev/null
-/* delqueue.cc
-
- Copyright 1996, 1998, 1999, 2000, 2001, 2007 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#include "winsup.h"
-#include "shared_info.h"
-
-/* FIXME: this delqueue module is very flawed and should be rewritten.
- First, having an array of a fixed size for keeping track of the
- unlinked but not yet deleted files is bad. Second, some programs
- will unlink files and then create a new one in the same location
- and this behavior is not supported in the current code. Probably
- we should find a move/rename function that will work on open files,
- and move delqueue files to some special location or some such
- hack... */
-
-void
-delqueue_list::init ()
-{
- empty = 1;
- memset (inuse, 0, MAX_DELQUEUES_PENDING);
-}
-
-void
-delqueue_list::queue_file (const char *dosname)
-{
- char temp[CYG_MAX_PATH], *end;
- GetFullPathName (dosname, sizeof (temp), temp, &end);
-
- /* Note about race conditions: The only time we get to this point is
- when a delete fails because someone's holding the descriptor open.
- In those cases, other programs will be unable to delete the file
- also, so any entries referring to that file will not be removed
- from the queue while we're here. */
-
- if (!empty)
- {
- /* check for duplicates */
- for (int i=0; i < MAX_DELQUEUES_PENDING; i++)
- if (inuse[i] && strcmp (name[i], temp) == 0)
- return;
- }
-
- for (int i = 0; i < MAX_DELQUEUES_PENDING; i++)
- if (!inuse[i])
- {
- /* set the name first, in case someone else is running the
- queue they'll get a valid name */
- strcpy (name[i], temp);
- inuse[i] = 1;
- empty = 0;
- debug_printf ("adding '%s' to queue %d", temp, i);
- return;
- }
-
- system_printf ("Out of queue slots");
-}
-
-void
-delqueue_list::process_queue ()
-{
- if (empty)
- return;
- /* We set empty to 1 here, rather than later, to avoid a race
- condition - some other program might queue up a file while we're
- processing, and it will zero out empty also. */
- empty = 1; /* but might get set to zero again, below */
-
- syscall_printf ("Running delqueue");
-
- for (int i = 0; i < MAX_DELQUEUES_PENDING; i++)
- if (inuse[i])
- {
- if (DeleteFileA (name[i]))
- {
- syscall_printf ("Deleted %s", name[i]);
- inuse[i] = 0;
- }
- else
- {
- int res = GetLastError ();
- empty = 0;
- if (res == ERROR_SHARING_VIOLATION)
- {
- /* File still inuse, that's ok */
- syscall_printf ("Still using %s", name[i]);
- }
- else
- {
- syscall_printf ("Hmm, don't know what to do with '%s', %E", name[i]);
- inuse[i] = 0;
- }
- }
- }
-}
virtual int open (int, mode_t = 0);
int open_fs (int, mode_t = 0);
virtual int close ();
- int close_fs ();
virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
int __stdcall fstat_fs (struct __stat64 *buf) __attribute__ ((regparm (2)));
int __stdcall fstat_helper (struct __stat64 *buf,
fhandler_disk_file (path_conv &pc);
int open (int flags, mode_t mode);
- int close ();
int lock (int, struct __flock64 *);
bool isdevice () { return false; }
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
{
/* We now have a valid handle, regardless of the "nohandle" state.
Since fhandler_base::open only calls CloseHandle if !nohandle,
- we have to set it to false before calling close_fs and restore
+ we have to set it to false before calling close and restore
the state afterwards. */
res = fstat_by_handle (buf);
bool no_handle = nohandle ();
nohandle (false);
- close_fs ();
+ close ();
nohandle (no_handle);
set_io_handle (NULL);
}
else if (pc.issocket ())
buf->st_mode = S_IFSOCK;
- if (!get_file_attribute (is_fs_special () ? NULL: get_handle (), pc,
+ if (!get_file_attribute (is_fs_special () && !pc.issocket ()
+ ? NULL : get_handle (), pc,
&buf->st_mode, &buf->st_uid, &buf->st_gid))
{
/* If read-only attribute is set, modify ntsec return value */
if (pc.has_buggy_open () && !pc.exists ())
{
debug_printf ("Buggy open detected.");
- close_fs ();
+ close ();
set_errno (ENOENT);
return 0;
}
return res;
}
-int
-fhandler_disk_file::close ()
-{
- return close_fs ();
-}
-
-int
-fhandler_base::close_fs ()
-{
- int res = fhandler_base::close ();
- if (!res)
- user_shared->delqueue.process_queue ();
- return res;
-}
-
ssize_t __stdcall
fhandler_disk_file::pread (void *buf, size_t count, _off64_t offset)
{
{
int res = 0;
+ if (get_device () == FH_UNIX)
+ return fhandler_base::close ();
+
/* HACK to allow a graceful shutdown even if shutdown() hasn't been
called by the application. Note that this isn't the ultimate
solution but it helps in many cases. */
{
debug_printf ("initializing user shared");
user_shared->mountinfo.init (); /* Initialize the mount table. */
- user_shared->delqueue.init (); /* Initialize the queue of deleted files. */
user_shared->cb = sizeof (*user_shared);
}
else
#define USER_VERSION 1 // increment when mount table changes and
#define USER_VERSION_MAGIC CYGWIN_VERSION_MAGIC (USER_MAGIC, USER_VERSION)
-#define CURR_USER_MAGIC 0x38edd704U
+#define CURR_USER_MAGIC 0xb2232e71U
class reg_key;
struct device;
void read_cygdrive_info_from_registry ();
};
-/******** Close-on-delete queue ********/
-
-/* First pass at a file deletion queue structure.
-
- We can't keep this list in the per-process info, since
- one process may open a file, and outlive a process which
- wanted to unlink the file - and the data would go away.
-*/
-
-#define MAX_DELQUEUES_PENDING 100
-
-class delqueue_list
-{
- char name[MAX_DELQUEUES_PENDING][CYG_MAX_PATH];
- char inuse[MAX_DELQUEUES_PENDING];
- int empty;
-
-public:
- void init ();
- void queue_file (const char *dosname);
- void process_queue ();
-};
-
class user_info
{
public:
DWORD version;
DWORD cb;
- delqueue_list delqueue;
bool warned_msdos;
mount_info mountinfo;
};
cygheap->close_ctty ();
cygheap->fdtab.unlock ();
- user_shared->delqueue.process_queue ();
}
int
if (NT_SUCCESS (status))
res = 0;
else
- {
- /* FIXME: Can we get rid of the delqueue now? */
- if (status == STATUS_SHARING_VIOLATION)
- {
- /* Add file to the "to be deleted" queue. */
- syscall_printf ("Sharing violation, couldn't delete file");
- user_shared->delqueue.queue_file (win32_name);
- res = 0;
- }
- else
- __seterrno_from_nt_status (status);
- }
+ __seterrno_from_nt_status (status);
done:
syscall_printf ("%d = unlink (%s)", res, ourname);