* fhandler_tty.cc (fhandler_tty_slave::init): Revert 2001-06-16 change.

* fork.cc (fork_copy): Print more debugging info.
(fork_parent): Change order of arguments to accomdate buggy gcc.
(fork): Ditto.
* syscalls.cc (_unlink): Reorganize to try harder to delete file with
DeleteFile and to recover more gracefully if FILE_FLAG_DELETE_ON_CLOSE doesn't
work properly.
This commit is contained in:
Christopher Faylor 2001-06-18 21:18:59 +00:00
parent 36623e6535
commit 20a2c44362
4 changed files with 104 additions and 69 deletions

View File

@ -1,3 +1,17 @@
Mon Jun 18 17:09:25 2001 Christopher Faylor <cgf@cygnus.com>
* fhandler_tty.cc (fhandler_tty_slave::init): Revert 2001-06-16 change.
* fork.cc (fork_copy): Print more debugging info.
(fork_parent): Change order of arguments to accomdate buggy gcc.
(fork): Ditto.
Sun Jun 17 18:54:46 2001 Christopher Faylor <cgf@cygnus.com>
* syscalls.cc (_unlink): Reorganize to try harder to delete file with
DeleteFile and to recover more gracefully if FILE_FLAG_DELETE_ON_CLOSE
doesn't work properly.
Sat Jun 16 13:06:49 2001 Christopher Faylor <cgf@cygnus.com>
* exceptions.cc (sig_handle_tty_stop): Reset PID_STOPPED if not
@ -31,8 +45,8 @@ Fri June 15 09:25:00 Robert Collins <rbtcollins@hotmail.com>
2001-06-14 Egor Duda <deo@logos-m.ru>
* fhandler.cc (fhandler_base::open): Set win32 access flags
to 0, when requested.
* fhandler.cc (fhandler_base::open): Set win32 access flags to 0, when
requested.
* fhandler.h: New status flag FH_QUERYOPEN.
(fhandler::get_query_open): New function.
(fhandler::set_query_open): Ditto.

View File

@ -574,7 +574,7 @@ fhandler_tty_slave::init (HANDLE, DWORD a, mode_t)
if (a == (GENERIC_READ | GENERIC_WRITE))
mode = O_RDWR;
open (0, mode | O_NOCTTY);
open (0, mode);
}
int

View File

@ -104,8 +104,8 @@ fork_copy (PROCESS_INFORMATION &pi, const char *what, ...)
__seterrno ();
/* If this happens then there is a bug in our fork
implementation somewhere. */
system_printf ("%s pass %d failed, %p..%p, done %d, %E",
what, pass, low, high, done);
system_printf ("%s pass %d failed, %p..%p, done %d, windows pid %u, %E",
what, pass, low, high, done, pi.dwProcessId);
goto err;
}
}
@ -340,8 +340,8 @@ slow_pid_reuse (HANDLE h)
}
static int __stdcall
fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll,
bool& load_dlls, child_info_fork &ch)
fork_parent (HANDLE& hParent, dll *&first_dll,
bool& load_dlls, void *stack_here, child_info_fork &ch)
{
HANDLE subproc_ready, forker_finished;
DWORD rc;
@ -646,7 +646,7 @@ fork ()
}
void *esp;
__asm ("movl %%esp,%0": "=r" (esp));
__asm__ volatile ("movl %%esp,%0": "=r" (esp));
myself->set_has_pgid_children ();
@ -657,7 +657,7 @@ fork ()
if (res)
res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls);
else
res = fork_parent (esp, grouped.hParent, grouped.first_dll, grouped.load_dlls, ch);
res = fork_parent (grouped.hParent, grouped.first_dll, grouped.load_dlls, esp, ch);
MALLOC_CHECK;
syscall_printf ("%d = fork()", res);

View File

@ -100,76 +100,97 @@ _unlink (const char *ourname)
/* Check for shortcut as symlink condition. */
if (atts != 0xffffffff && atts & FILE_ATTRIBUTE_READONLY)
{
int len = strlen (win32_name.get_win32 ());
if (len > 4 && strcasematch (win32_name.get_win32 () + len - 4, ".lnk"))
SetFileAttributes (win32_name.get_win32 (),
win32_name.file_attributes () & ~FILE_ATTRIBUTE_READONLY);
int len = strlen (win32_name);
if (len > 4 && strcasematch (win32_name + len - 4, ".lnk"))
SetFileAttributes (win32_name, atts & ~FILE_ATTRIBUTE_READONLY);
}
DWORD lasterr;
lasterr = 0;
for (int i = 0; i < 2; i++)
{
if (DeleteFile (win32_name))
{
syscall_printf ("DeleteFile succeeded");
res = 0;
break;
goto ok;
}
DWORD lasterr;
lasterr = GetLastError ();
if (i || lasterr != ERROR_ACCESS_DENIED || win32_name.issymlink ())
break; /* Couldn't delete it. */
/* FIXME: There's a race here. */
HANDLE h = CreateFile (win32_name, GENERIC_READ,
FILE_SHARE_READ,
&sec_none_nih, OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE, 0);
if (h != INVALID_HANDLE_VALUE)
/* if access denied, chmod to be writable, in case it is not,
and try again */
(void) chmod (win32_name, 0777);
}
/* Tried to delete file by normal DeleteFile and by resetting protection
and then deleting. That didn't work.
There are two possible reasons for this: 1) The file may be opened and
Windows is not allowing it to be deleted, or 2) We may not have permissions
to delete the file.
So, first assume that it may be 1) and try to remove the file using the
Windows FILE_FLAG_DELETE_ON_CLOSE semantics. This seems to work only
spottily on Windows 9x/Me but it does seem to work reliably on NT as
long as the file doesn't exist on a remote drive. */
bool delete_on_close_ok;
delete_on_close_ok = !win32_name.isremote () && os_being_run == winNT;
/* Attempt to use "delete on close" semantics to handle removing
a file which may be open. */
HANDLE h;
h = CreateFile (win32_name, GENERIC_READ, FILE_SHARE_READ, &sec_none_nih,
OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
if (h == INVALID_HANDLE_VALUE)
{
if (GetLastError () == ERROR_FILE_NOT_FOUND)
goto ok;
}
else
{
CloseHandle (h);
syscall_printf ("CreateFile/CloseHandle succeeded");
if (os_being_run == winNT || GetFileAttributes (win32_name) == (DWORD) -1)
{
res = 0;
break;
}
/* Everything is fine if the file has disappeared or if we know that the
FILE_FLAG_DELETE_ON_CLOSE will eventually work. */
if (GetFileAttributes (win32_name) == (DWORD) -1 || delete_on_close_ok)
goto ok; /* The file is either gone already or will eventually be
deleted by the OS. */
}
if (i > 0)
{
if (os_being_run == winNT || lasterr != ERROR_ACCESS_DENIED)
/* FILE_FLAGS_DELETE_ON_CLOSE was a bust. If delete_on_close_ok is
true then it should have worked. If it didn't work, that was an
error. Windows 9x seems to return ERROR_ACCESS_DENIED in "sharing
violation" type of situations. */
if (delete_on_close_ok
|| (lasterr != ERROR_ACCESS_DENIED && lasterr != ERROR_SHARING_VIOLATION))
goto err;
if (win32_name.isremote ())
/* Can't reliably detect sharing violations on remote shares, so if we
didn't specifically get that error, then punt. */
if (lasterr != ERROR_SHARING_VIOLATION && win32_name.isremote ())
{
syscall_printf ("access denied on remote drive");
goto err; /* Can't detect this, unfortunately */
}
lasterr = ERROR_SHARING_VIOLATION;
}
syscall_printf ("i %d, couldn't delete file, %E", i);
syscall_printf ("couldn't delete file, err %d", lasterr);
/* If we get ERROR_SHARING_VIOLATION, the file may still be open -
Windows NT doesn't support deleting a file while it's open. */
if (lasterr == ERROR_SHARING_VIOLATION)
{
/* Add file to the "to be deleted" queue. */
cygwin_shared->delqueue.queue_file (win32_name);
/* Success condition. */
ok:
res = 0;
break;
}
/* if access denied, chmod to be writable in case it is not
and try again */
/* FIXME: Should check whether ourname is directory or file
and only try again if permissions are not sufficient */
if (lasterr == ERROR_ACCESS_DENIED && chmod (win32_name, 0777) == 0)
continue;
goto done;
/* Error condition. */
err:
__seterrno ();
res = -1;
break;
}
done:
syscall_printf ("%d = unlink (%s)", res, ourname);