* syscalls.cc (unlink): Always attempt to use FILE_FLAG_CLOSE_ON_DELETE to
delete files since this allows us to preserve the protection of hard linked files. (link): Generate full path for potentially recalculated .lnk target.
This commit is contained in:
parent
35c6ce031e
commit
ed269ceaa2
@ -1,3 +1,10 @@
|
|||||||
|
2003-03-08 Christopher Faylor <cgf@redhat.com>
|
||||||
|
|
||||||
|
* syscalls.cc (unlink): Always attempt to use FILE_FLAG_CLOSE_ON_DELETE
|
||||||
|
to delete files since this allows us to preserve the protection of hard
|
||||||
|
linked files.
|
||||||
|
(link): Generate full path for potentially recalculated .lnk target.
|
||||||
|
|
||||||
2003-03-08 Christopher Faylor <cgf@redhat.com>
|
2003-03-08 Christopher Faylor <cgf@redhat.com>
|
||||||
|
|
||||||
Revert below changes regarding _pinfo::cmdline.
|
Revert below changes regarding _pinfo::cmdline.
|
||||||
|
@ -133,27 +133,31 @@ unlink (const char *ourname)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for shortcut as symlink condition. */
|
SetFileAttributes (win32_name, (DWORD) win32_name & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM));
|
||||||
if (win32_name.issymlink ())
|
/* Attempt to use "delete on close" semantics to handle removing
|
||||||
SetFileAttributes (win32_name, (DWORD) win32_name & ~FILE_ATTRIBUTE_READONLY);
|
a file which may be open. */
|
||||||
|
HANDLE h;
|
||||||
|
h = CreateFile (win32_name, GENERIC_READ, FILE_SHARE_DELETE, &sec_none_nih,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
|
||||||
|
|
||||||
|
(void) SetFileAttributes (win32_name, (DWORD) win32_name);
|
||||||
|
(void) DeleteFile (win32_name);
|
||||||
DWORD lasterr;
|
DWORD lasterr;
|
||||||
lasterr = 0;
|
lasterr = GetLastError ();
|
||||||
for (int i = 0; i < 2; i++)
|
if (h != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle (h);
|
||||||
|
|
||||||
|
if (GetFileAttributes (win32_name) == INVALID_FILE_ATTRIBUTES
|
||||||
|
|| (!win32_name.isremote () && wincap.has_delete_on_close ()))
|
||||||
{
|
{
|
||||||
if (DeleteFile (win32_name))
|
syscall_printf ("DeleteFile succeeded");
|
||||||
{
|
goto ok;
|
||||||
syscall_printf ("DeleteFile succeeded");
|
}
|
||||||
goto ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
lasterr = GetLastError ();
|
if (DeleteFile (win32_name))
|
||||||
if (i || lasterr != ERROR_ACCESS_DENIED)
|
{
|
||||||
break; /* Couldn't delete it. */
|
syscall_printf ("DeleteFile after CreateFile/ClosHandle succeeded");
|
||||||
|
goto ok;
|
||||||
/* if access denied, chmod to be writable, in case it is not,
|
|
||||||
and try again */
|
|
||||||
(void) chmod (win32_name, 0777);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Windows 9x seems to report ERROR_ACCESS_DENIED rather than sharing
|
/* Windows 9x seems to report ERROR_ACCESS_DENIED rather than sharing
|
||||||
@ -163,45 +167,6 @@ unlink (const char *ourname)
|
|||||||
&& !win32_name.isremote ())
|
&& !win32_name.isremote ())
|
||||||
lasterr = ERROR_SHARING_VIOLATION;
|
lasterr = ERROR_SHARING_VIOLATION;
|
||||||
|
|
||||||
/* 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 ()
|
|
||||||
&& wincap.has_delete_on_close ();
|
|
||||||
|
|
||||||
/* 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) == INVALID_FILE_ATTRIBUTES
|
|
||||||
|| 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 this is a sharing
|
/* FILE_FLAGS_DELETE_ON_CLOSE was a bust. If this is a sharing
|
||||||
violation, then queue the file for deletion when the process
|
violation, then queue the file for deletion when the process
|
||||||
exits. Otherwise, punt. */
|
exits. Otherwise, punt. */
|
||||||
@ -649,7 +614,7 @@ link (const char *a, const char *b)
|
|||||||
strcpy (new_lnk_buf, b);
|
strcpy (new_lnk_buf, b);
|
||||||
strcat (new_lnk_buf, ".lnk");
|
strcat (new_lnk_buf, ".lnk");
|
||||||
b = new_lnk_buf;
|
b = new_lnk_buf;
|
||||||
real_b.check (b, PC_SYM_NOFOLLOW);
|
real_b.check (b, PC_SYM_NOFOLLOW | PC_FULL);
|
||||||
}
|
}
|
||||||
/* Try to make hard link first on Windows NT */
|
/* Try to make hard link first on Windows NT */
|
||||||
if (wincap.has_hard_links ())
|
if (wincap.has_hard_links ())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user