1 /* fhandler_mailslot.cc. See fhandler.h for a description of the fhandler classes.
3 Copyright 2005, 2007, 2008, 2009, 2010, 2011 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
17 #include "shared_info.h"
20 /**********************************************************************/
21 /* fhandler_mailslot */
23 fhandler_mailslot::fhandler_mailslot ()
24 : fhandler_base_overlapped ()
29 fhandler_mailslot::fstat (struct __stat64 *buf)
31 debug_printf ("here");
33 fhandler_base_overlapped::fstat (buf);
34 if (is_auto_device ())
36 buf->st_mode = S_IFCHR | S_IRUSR | S_IWUSR;
37 buf->st_uid = geteuid32 ();
38 buf->st_gid = getegid32 ();
40 buf->st_blksize = PREFERRED_IO_BLKSIZE;
41 time_as_timestruc_t (&buf->st_ctim);
42 buf->st_atim = buf->st_mtim = buf->st_birthtim = buf->st_ctim;
48 fhandler_mailslot::get_object_attr (OBJECT_ATTRIBUTES &attr,
53 RtlCopyUnicodeString (path, pc.get_nt_native_path ());
54 RtlAppendUnicodeStringToString (path, &installation_key);
55 InitializeObjectAttributes (&attr, path,
57 | (flags & O_CLOEXEC ? 0 : OBJ_INHERIT),
63 fhandler_mailslot::open (int flags, mode_t mode)
68 OBJECT_ATTRIBUTES attr;
70 LARGE_INTEGER timeout;
76 switch (flags & O_ACCMODE)
78 case O_RDONLY: /* Server */
79 timeout.QuadPart = (flags & O_NONBLOCK) ? 0LL : 0x8000000000000000LL;
80 status = NtCreateMailslotFile (&x, GENERIC_READ | SYNCHRONIZE,
81 get_object_attr (attr, &path, flags),
82 &io, FILE_SYNCHRONOUS_IO_NONALERT,
84 if (!NT_SUCCESS (status))
86 /* FIXME: It's not possible to open the read side of an existing
87 mailslot again. You'll get a handle, but using it in ReadFile
88 returns ERROR_INVALID_PARAMETER. On the other hand,
89 NtCreateMailslotFile returns with STATUS_OBJECT_NAME_EXISTS if
90 the mailslot has been created already.
91 So this is an exclusive open for now. *Duplicating* read side
92 handles works, though, so it might be an option to duplicate
93 the handle from the first process to the current process for
94 opening the mailslot. */
96 if (status != STATUS_OBJECT_NAME_COLLISION)
98 __seterrno_from_nt_status (status);
101 status = NtOpenFile (&x, GENERIC_READ | SYNCHRONIZE,
102 get_object_attr (attr, &path, flags), &io,
103 FILE_SHARE_VALID_FLAGS,
104 FILE_SYNCHRONOUS_IO_NONALERT);
106 if (!NT_SUCCESS (status))
108 __seterrno_from_nt_status (status);
113 set_flags (flags, O_BINARY);
117 case O_WRONLY: /* Client */
118 /* The client is the DLL exclusively. Don't allow opening from
120 extern fhandler_mailslot *dev_kmsg;
121 if (this != dev_kmsg)
123 set_errno (EPERM); /* As on Linux. */
126 status = NtOpenFile (&x, GENERIC_WRITE | SYNCHRONIZE,
127 get_object_attr (attr, &path, flags), &io,
128 FILE_SHARE_VALID_FLAGS, 0);
129 if (!NT_SUCCESS (status))
131 __seterrno_from_nt_status (status);
135 set_flags (flags, O_BINARY);
147 fhandler_mailslot::raw_write (const void *ptr, size_t len)
149 /* Check for 425/426 byte weirdness */
150 if (len == 425 || len == 426)
153 buf[425] = buf[426] = '\0';
154 memcpy (buf, ptr, len);
155 return raw_write (buf, 427);
157 return fhandler_base_overlapped::raw_write (ptr, len);
161 fhandler_mailslot::ioctl (unsigned int cmd, void *buf)
171 FILE_MAILSLOT_SET_INFORMATION fmsi;
172 fmsi.ReadTimeout.QuadPart = buf ? 0LL : 0x8000000000000000LL;
173 status = NtSetInformationFile (get_handle (), &io, &fmsi, sizeof fmsi,
174 FileMailslotSetInformation);
175 if (!NT_SUCCESS (status))
177 debug_printf ("NtSetInformationFile (%X): %08x",
178 fmsi.ReadTimeout.QuadPart, status);
179 __seterrno_from_nt_status (status);
185 res = fhandler_base_overlapped::ioctl (cmd, buf);