* devices.in (dev_storage): Map /dev/zero and /dev/full to \Device\Null.
* devices.cc: Regenerate. * dtable.h (struct dtable): Make fhandler_base friend, rather than fhandler_disk_file. * fhandler.cc (fhandler_base::open_with_arch): Create unique id. (fhandler_base::cleanup): Call del_my_locks. (fhandler_base::fcntl): Handle F_GETLK, F_SETLK and F_SETLKW. * fhandler.h (fhandler_base::get_dev): Return real device number. (fhandler_base::set_unique_id): New inline method. (fhandler_disk_file::lock): Drop declaration. (fhandler_disk_file::get_dev): New method, return pc.fs_serial_number. (fhandler_dev_zero::open): Drop declaration. * fhandler_disk_file.cc (fhandler_disk_file::close): Move del_my_locks call to fhandler_base::open_with_arch. (fhandler_disk_file::fcntl): Move handling of locking commands to fhandler_base::fcntl. (fhandler_base::open_fs): Drop call to NtAllocateLocallyUniqueId. * fhandler_zero.cc (fhandler_dev_zero::open): Remove so that default fhandler_base::open is used to open \Device\Null. * flock.cc (fixup_lockf_after_exec): Finding a single fhandler is enough here. (fhandler_base::lock): Replace fhandler_disk_file::lock. Refuse to lock nohandle devices. Handle read/write test using POSIX flags. Explain why. Never fail on SEEK_CUR or SEEK_END, rather assume position 0, just as Linux. * net.cc (fdsock): Create unique id.
This commit is contained in:
@@ -454,7 +454,7 @@ fixup_lockf_after_exec ()
|
||||
while (cfd.next () >= 0)
|
||||
if (cfd->get_dev () == node->i_dev
|
||||
&& cfd->get_ino () == node->i_ino
|
||||
&& ++cnt > 1)
|
||||
&& ++cnt >= 1)
|
||||
break;
|
||||
if (cnt == 0)
|
||||
{
|
||||
@@ -919,14 +919,7 @@ static void lf_wakelock (lockf_t *, HANDLE);
|
||||
of mandatory locks using the Windows mandatory locking functions, see the
|
||||
fhandler_disk_file::mand_lock method at the end of this file. */
|
||||
int
|
||||
fhandler_base::lock (int, struct flock *)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_disk_file::lock (int a_op, struct flock *fl)
|
||||
fhandler_base::lock (int a_op, struct flock *fl)
|
||||
{
|
||||
off_t start, end, oadd;
|
||||
int error = 0;
|
||||
@@ -934,6 +927,13 @@ fhandler_disk_file::lock (int a_op, struct flock *fl)
|
||||
short a_flags = fl->l_type & (F_POSIX | F_FLOCK);
|
||||
short type = fl->l_type & (F_RDLCK | F_WRLCK | F_UNLCK);
|
||||
|
||||
if (nohandle ())
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
debug_printf ("Locking on nohandle device, return EINVAL.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!a_flags)
|
||||
a_flags = F_POSIX; /* default */
|
||||
if (a_op == F_SETLKW)
|
||||
@@ -952,16 +952,24 @@ fhandler_disk_file::lock (int a_op, struct flock *fl)
|
||||
been opened with a specific open mode, in contrast to POSIX locks
|
||||
which require that a file is opened for reading to place a read
|
||||
lock and opened for writing to place a write lock. */
|
||||
if ((a_flags & F_POSIX) && !(get_access () & GENERIC_READ))
|
||||
/* CV 2013-10-22: Test POSIX R/W mode flags rather than Windows R/W
|
||||
access flags. The reason is that POSIX mode flags are set for
|
||||
all types of fhandlers, while Windows access flags are only set
|
||||
for most of the actual Windows device backed fhandlers. */
|
||||
if ((a_flags & F_POSIX)
|
||||
&& ((get_flags () & O_ACCMODE) == O_WRONLY))
|
||||
{
|
||||
system_printf ("get_access() == %x", get_access ());
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case F_WRLCK:
|
||||
/* See above comment. */
|
||||
if ((a_flags & F_POSIX) && !(get_access () & GENERIC_WRITE))
|
||||
if ((a_flags & F_POSIX)
|
||||
&& ((get_flags () & O_ACCMODE) == O_RDONLY))
|
||||
{
|
||||
system_printf ("get_access() == %x", get_access ());
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
@@ -982,29 +990,32 @@ fhandler_disk_file::lock (int a_op, struct flock *fl)
|
||||
|
||||
case SEEK_CUR:
|
||||
if ((start = lseek (0, SEEK_CUR)) == ILLEGAL_SEEK)
|
||||
return -1;
|
||||
start = 0;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
{
|
||||
NTSTATUS status;
|
||||
IO_STATUS_BLOCK io;
|
||||
FILE_STANDARD_INFORMATION fsi;
|
||||
if (get_device () != FH_FS)
|
||||
start = 0;
|
||||
else
|
||||
{
|
||||
NTSTATUS status;
|
||||
IO_STATUS_BLOCK io;
|
||||
FILE_STANDARD_INFORMATION fsi;
|
||||
|
||||
status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
|
||||
FileStandardInformation);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
return -1;
|
||||
}
|
||||
if (fl->l_start > 0 && fsi.EndOfFile.QuadPart > OFF_MAX - fl->l_start)
|
||||
{
|
||||
set_errno (EOVERFLOW);
|
||||
return -1;
|
||||
}
|
||||
start = fsi.EndOfFile.QuadPart + fl->l_start;
|
||||
}
|
||||
status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
|
||||
FileStandardInformation);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
return -1;
|
||||
}
|
||||
if (fl->l_start > 0 && fsi.EndOfFile.QuadPart > OFF_MAX - fl->l_start)
|
||||
{
|
||||
set_errno (EOVERFLOW);
|
||||
return -1;
|
||||
}
|
||||
start = fsi.EndOfFile.QuadPart + fl->l_start;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Reference in New Issue
Block a user