Cygwin: fhandler_pipe: control blocking mode of the Windows pipe
Add methods 'set_pipe_non_blocking' and 'fcntl' to keep the blocking mode of the Windows pipe in sync with that of the fhandler_pipe object. This applies to pipes created with the 'pipe' and 'pipe2' system calls.
This commit is contained in:
parent
4b25687ea3
commit
d0ad52aa6e
|
@ -1243,6 +1243,7 @@ class fhandler_pipe: public fhandler_base
|
||||||
private:
|
private:
|
||||||
pid_t popen_pid;
|
pid_t popen_pid;
|
||||||
size_t max_atomic_write;
|
size_t max_atomic_write;
|
||||||
|
void set_pipe_non_blocking (bool nonblocking);
|
||||||
public:
|
public:
|
||||||
fhandler_pipe ();
|
fhandler_pipe ();
|
||||||
|
|
||||||
|
@ -1260,6 +1261,7 @@ public:
|
||||||
void __reg3 raw_read (void *ptr, size_t& len);
|
void __reg3 raw_read (void *ptr, size_t& len);
|
||||||
ssize_t __reg3 raw_write (const void *ptr, size_t len);
|
ssize_t __reg3 raw_write (const void *ptr, size_t len);
|
||||||
int ioctl (unsigned int cmd, void *);
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
int fcntl (int cmd, intptr_t);
|
||||||
int __reg2 fstat (struct stat *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
int __reg2 fstatvfs (struct statvfs *buf);
|
int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
int __reg3 fadvise (off_t, off_t, int);
|
int __reg3 fadvise (off_t, off_t, int);
|
||||||
|
|
|
@ -35,6 +35,23 @@ fhandler_pipe::fhandler_pipe ()
|
||||||
need_fork_fixup (true);
|
need_fork_fixup (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This also sets the pipe's read mode to byte_stream unconditionally. */
|
||||||
|
void
|
||||||
|
fhandler_pipe::set_pipe_non_blocking (bool nonblocking)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
FILE_PIPE_INFORMATION fpi;
|
||||||
|
|
||||||
|
fpi.ReadMode = FILE_PIPE_BYTE_STREAM_MODE;
|
||||||
|
fpi.CompletionMode = nonblocking ? FILE_PIPE_COMPLETE_OPERATION
|
||||||
|
: FILE_PIPE_QUEUE_OPERATION;
|
||||||
|
status = NtSetInformationFile (get_handle (), &io, &fpi, sizeof fpi,
|
||||||
|
FilePipeInformation);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
debug_printf ("NtSetInformationFile(FilePipeInformation): %y", status);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode, int64_t uniq_id)
|
fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode, int64_t uniq_id)
|
||||||
{
|
{
|
||||||
|
@ -62,8 +79,7 @@ fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode, int64_t uniq_id)
|
||||||
set_ino (uniq_id);
|
set_ino (uniq_id);
|
||||||
set_unique_id (uniq_id | !!(mode & GENERIC_WRITE));
|
set_unique_id (uniq_id | !!(mode & GENERIC_WRITE));
|
||||||
if (opened_properly)
|
if (opened_properly)
|
||||||
/* ... */
|
set_pipe_non_blocking (is_nonblocking ());
|
||||||
;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,6 +628,20 @@ fhandler_pipe::ioctl (unsigned int cmd, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_pipe::fcntl (int cmd, intptr_t arg)
|
||||||
|
{
|
||||||
|
if (cmd != F_SETFL)
|
||||||
|
return fhandler_base::fcntl (cmd, arg);
|
||||||
|
|
||||||
|
const bool was_nonblocking = is_nonblocking ();
|
||||||
|
int res = fhandler_base::fcntl (cmd, arg);
|
||||||
|
const bool now_nonblocking = is_nonblocking ();
|
||||||
|
if (now_nonblocking != was_nonblocking)
|
||||||
|
set_pipe_non_blocking (now_nonblocking);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_pipe::fstat (struct stat *buf)
|
fhandler_pipe::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue