1 /* fhandler_mailslot.cc. See fhandler.h for a description of the fhandler classes.
3 Copyright 2005, 2007 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
19 /**********************************************************************/
20 /* fhandler_mailslot */
22 fhandler_mailslot::fhandler_mailslot ()
28 fhandler_mailslot::fstat (struct __stat64 *buf)
30 debug_printf ("here");
32 fhandler_base::fstat (buf);
33 if (is_auto_device ())
35 buf->st_mode = S_IFCHR | S_IRUSR | S_IWUSR;
36 buf->st_uid = geteuid32 ();
37 buf->st_gid = getegid32 ();
39 buf->st_blksize = PREFERRED_IO_BLKSIZE;
40 time_as_timestruc_t (&buf->st_ctim);
41 buf->st_atim = buf->st_mtim = buf->st_birthtim = buf->st_ctim;
47 fhandler_mailslot::open (int flags, mode_t mode)
52 OBJECT_ATTRIBUTES attr;
54 LARGE_INTEGER timeout;
56 switch (flags & O_ACCMODE)
58 case O_RDONLY: /* Server */
59 timeout.QuadPart = (flags & O_NONBLOCK) ? 0LL : 0x8000000000000000LL;
60 status = NtCreateMailslotFile (&x, GENERIC_READ | SYNCHRONIZE,
61 pc.get_object_attr (attr, sec_none),
62 &io, FILE_SYNCHRONOUS_IO_NONALERT,
64 if (!NT_SUCCESS (status))
66 /* FIXME: It's not possible to open the read side of an existing
67 mailslot again. You'll get a handle, but using it in ReadFile
68 returns ERROR_INVALID_PARAMETER. On the other hand,
69 NtCreateMailslotFile returns with STATUS_OBJECT_NAME_EXISTS if
70 the mailslot has been created already.
71 So this is an exclusive open for now. *Duplicating* read side
72 handles works, though, so it might be an option to duplicate
73 the handle from the first process to the current process for
74 opening the mailslot. */
76 if (status != STATUS_OBJECT_NAME_COLLISION)
78 __seterrno_from_nt_status (status);
81 status = NtOpenFile (&x, GENERIC_READ | SYNCHRONIZE,
82 pc.get_object_attr (attr, sec_none), &io,
83 FILE_SHARE_VALID_FLAGS,
84 FILE_SYNCHRONOUS_IO_NONALERT);
86 if (!NT_SUCCESS (status))
88 __seterrno_from_nt_status (status);
93 set_flags (flags, O_BINARY);
97 case O_WRONLY: /* Client */
98 /* The client is the DLL exclusively. Don't allow opening from
100 extern fhandler_mailslot *dev_kmsg;
101 if (this != dev_kmsg)
103 set_errno (EPERM); /* As on Linux. */
106 status = NtOpenFile (&x, GENERIC_WRITE | SYNCHRONIZE,
107 pc.get_object_attr (attr, sec_none), &io,
108 FILE_SHARE_VALID_FLAGS,
109 FILE_SYNCHRONOUS_IO_NONALERT);
110 if (!NT_SUCCESS (status))
112 __seterrno_from_nt_status (status);
116 set_flags (flags, O_BINARY);
128 fhandler_mailslot::write (const void *ptr, size_t len)
130 /* Check for 425/426 byte weirdness */
131 if (len == 425 || len == 426)
134 buf[425] = buf[426] = '\0';
135 memcpy (buf, ptr, len);
136 return raw_write (buf, 427);
138 return raw_write (ptr, len);
142 fhandler_mailslot::ioctl (unsigned int cmd, void *buf)
152 FILE_MAILSLOT_SET_INFORMATION fmsi;
153 fmsi.ReadTimeout.QuadPart = buf ? 0LL : 0x8000000000000000LL;
154 status = NtSetInformationFile (get_handle (), &io, &fmsi, sizeof fmsi,
155 FileMailslotSetInformation);
156 if (!NT_SUCCESS (status))
158 debug_printf ("NtSetInformationFile (%X): %08x",
159 fmsi.ReadTimeout.QuadPart, status);
160 __seterrno_from_nt_status (status);
166 res = fhandler_base::ioctl (cmd, buf);