* 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
@ -25,14 +39,14 @@ Thu Jun 14 20:19:46 2001 Christopher Faylor <cgf@cygnus.com>
call to get_attributes.
Fri June 15 09:25:00 Robert Collins <rbtcollins@hotmail.com>
* thread.cc (pthread_cond::Signal): Release the condition access
variable correctly.
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,78 +100,99 @@ _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)
{
CloseHandle (h);
syscall_printf ("CreateFile/CloseHandle succeeded");
if (os_being_run == winNT || GetFileAttributes (win32_name) == (DWORD) -1)
{
res = 0;
break;
}
}
if (i > 0)
{
if (os_being_run == winNT || lasterr != ERROR_ACCESS_DENIED)
goto err;
if (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);
/* 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)
{
cygwin_shared->delqueue.queue_file (win32_name);
res = 0;
break;
}
/* if access denied, chmod to be writable in case it is not
/* 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;
err:
__seterrno ();
res = -1;
break;
(void) chmod (win32_name, 0777);
}
done:
/* 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");
/* 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. */
}
/* 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;
/* 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 */
}
syscall_printf ("couldn't delete file, err %d", lasterr);
/* Add file to the "to be deleted" queue. */
cygwin_shared->delqueue.queue_file (win32_name);
/* Success condition. */
ok:
res = 0;
goto done;
/* Error condition. */
err:
__seterrno ();
res = -1;
done:
syscall_printf ("%d = unlink (%s)", res, ourname);
return res;
}
@ -2084,7 +2105,7 @@ seteuid (uid_t uid)
}
/* Only when ntsec is ON! */
/* If no impersonation token is available, try to
/* If no impersonation token is available, try to
authenticate using NtCreateToken() or subauthentication. */
if (allow_ntsec && cygheap->user.token == INVALID_HANDLE_VALUE)
{