diff options
Diffstat (limited to 'winsup/cygwin/fhandler_mailslot.cc')
-rw-r--r-- | winsup/cygwin/fhandler_mailslot.cc | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/winsup/cygwin/fhandler_mailslot.cc b/winsup/cygwin/fhandler_mailslot.cc new file mode 100644 index 000000000..c29378ae0 --- /dev/null +++ b/winsup/cygwin/fhandler_mailslot.cc @@ -0,0 +1,160 @@ +/* fhandler_mailslot.cc. See fhandler.h for a description of the fhandler classes. + + Copyright 2005 Red Hat, Inc. + + This file is part of Cygwin. + + This software is a copyrighted work licensed under the terms of the + Cygwin license. Please consult the file "CYGWIN_LICENSE" for + details. */ + +#include "winsup.h" +#include <unistd.h> +#include <sys/termios.h> + +#include <ntdef.h> +#include "cygerrno.h" +#include "perprocess.h" +#include "security.h" +#include "path.h" +#include "fhandler.h" +#include "dtable.h" +#include "cygheap.h" +#include "ntdll.h" + +/**********************************************************************/ +/* fhandler_mailslot */ + +fhandler_mailslot::fhandler_mailslot () + : fhandler_base () +{ +} + +int __stdcall +fhandler_mailslot::fstat (struct __stat64 *buf) +{ + debug_printf ("here"); + + fhandler_base::fstat (buf); + if (is_auto_device ()) + { + buf->st_mode = S_IFCHR | S_IRUSR | S_IWUSR; + buf->st_uid = geteuid32 (); + buf->st_gid = getegid32 (); + buf->st_nlink = 1; + buf->st_blksize = S_BLKSIZE; + time_as_timestruc_t (&buf->st_ctim); + buf->st_atim = buf->st_mtim = buf->st_ctim; + } + return 0; +} + +int +fhandler_mailslot::open (int flags, mode_t mode) +{ + int res = 0; + HANDLE x; + + switch (flags & O_ACCMODE) + { + case O_RDONLY: /* Server */ + x = CreateMailslot (get_win32_name (), + 0, /* Any message size */ + (flags & O_NONBLOCK) ? 0 : MAILSLOT_WAIT_FOREVER, + &sec_none); + if (x == INVALID_HANDLE_VALUE) + { + /* FIXME: It's not possible to open the read side of an existing + mailslot using CreateFile. You'll get a handle, but using it + in ReadFile returns ERROR_INVALID_PARAMETER. On the other + hand, CreateMailslot returns with ERROR_ALREADY_EXISTS if the + mailslot has been created already. + So this is an exclusive open for now. *Duplicating* read side + handles works, though, so it might be an option to duplicate + the handle from the first process to the current process for + opening the mailslot. */ +#if 0 + if (GetLastError () != ERROR_ALREADY_EXISTS) + { + __seterrno (); + break; + } + x = CreateFile (get_win32_name (), GENERIC_READ, wincap.shared (), + &sec_none, OPEN_EXISTING, 0, 0); +#endif + if (x == INVALID_HANDLE_VALUE) + { + __seterrno (); + break; + } + } + set_io_handle (x); + set_flags (flags, O_BINARY); + res = 1; + set_open_status (); + break; + case O_WRONLY: /* Client */ + /* The client is the DLL exclusively. Don't allow opening from + application code. */ + extern fhandler_mailslot *dev_kmsg; + if (this != dev_kmsg) + { + set_errno (EPERM); /* As on Linux. */ + break; + } + x = CreateFile (get_win32_name (), GENERIC_WRITE, wincap.shared (), + &sec_none, OPEN_EXISTING, 0, 0); + if (x == INVALID_HANDLE_VALUE) + { + __seterrno (); + break; + } + set_io_handle (x); + set_flags (flags, O_BINARY); + res = 1; + set_open_status (); + break; + default: + set_errno (EINVAL); + break; + } + return res; +} + +int +fhandler_mailslot::write (const void *ptr, size_t len) +{ + /* Check for 425/426 byte weirdness */ + if (len == 425 || len == 426) + { + char buf[427]; + buf[425] = buf[426] = '\0'; + memcpy (buf, ptr, len); + return raw_write (buf, 427); + } + return raw_write (ptr, len); +} + +int +fhandler_mailslot::ioctl (unsigned int cmd, void *buf) +{ + int res = -1; + + switch (cmd) + { + case FIONBIO: + { + DWORD timeout = buf ? 0 : MAILSLOT_WAIT_FOREVER; + if (!SetMailslotInfo (get_handle (), timeout)) + { + debug_printf ("SetMailslotInfo (%u): %E", timeout); + break; + } + } + /*FALLTHRU*/ + default: + res = fhandler_base::ioctl (cmd, buf); + break; + } + return res; +} |