aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2001-06-18 21:18:59 +0000
committerChristopher Faylor <me@cgf.cx>2001-06-18 21:18:59 +0000
commit20a2c4436224db8bf0b9dd47c58749a36a1dfc17 (patch)
tree9445a0987f1ef7a5fe0638e13b3254ac211ebe3b /winsup
parent36623e6535b5e5cddd1bab84ada4b06af9b22474 (diff)
downloadnewlib-20a2c4436224db8bf0b9dd47c58749a36a1dfc17.zip
newlib-20a2c4436224db8bf0b9dd47c58749a36a1dfc17.tar.gz
newlib-20a2c4436224db8bf0b9dd47c58749a36a1dfc17.tar.bz2
* 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog20
-rw-r--r--winsup/cygwin/fhandler_tty.cc2
-rw-r--r--winsup/cygwin/fork.cc12
-rw-r--r--winsup/cygwin/syscalls.cc129
4 files changed, 99 insertions, 64 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 218b0c7..03b3b26 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index f0076ca..293f4e6 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -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
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 651d935..b448554 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -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);
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 4e96ccc..23b6540 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -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 access denied, chmod to be writable, in case it is not,
+ and try again */
+ (void) chmod (win32_name, 0777);
+ }
- if (i > 0)
- {
- if (os_being_run == winNT || lasterr != ERROR_ACCESS_DENIED)
- goto err;
+ /* Tried to delete file by normal DeleteFile and by resetting protection
+ and then deleting. That didn't work.
- if (win32_name.isremote ())
- {
- syscall_printf ("access denied on remote drive");
- goto err; /* Can't detect this, unfortunately */
- }
- lasterr = ERROR_SHARING_VIOLATION;
- }
+ 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.
- syscall_printf ("i %d, couldn't delete file, %E", i);
+ 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. */
- /* 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;
- }
+ bool delete_on_close_ok;
- /* 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;
+ delete_on_close_ok = !win32_name.isremote () && os_being_run == winNT;
- err:
- __seterrno ();
- res = -1;
- break;
+ /* 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. */
}
-done:
+ /* 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)
{