OSDN Git Service

Remove unneeded header files from source files throughout.
[pf3gnuchains/pf3gnuchains3x.git] / winsup / cygwin / fhandler_mailslot.cc
1 /* fhandler_mailslot.cc.  See fhandler.h for a description of the fhandler classes.
2
3    Copyright 2005, 2007 Red Hat, Inc.
4
5    This file is part of Cygwin.
6
7    This software is a copyrighted work licensed under the terms of the
8    Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9    details. */
10
11 #include "winsup.h"
12
13 #include "cygerrno.h"
14 #include "security.h"
15 #include "path.h"
16 #include "fhandler.h"
17 #include "ntdll.h"
18
19 /**********************************************************************/
20 /* fhandler_mailslot */
21
22 fhandler_mailslot::fhandler_mailslot ()
23   : fhandler_base ()
24 {
25 }
26
27 int __stdcall
28 fhandler_mailslot::fstat (struct __stat64 *buf)
29 {
30   debug_printf ("here");
31
32   fhandler_base::fstat (buf);
33   if (is_auto_device ())
34     {
35       buf->st_mode = S_IFCHR | S_IRUSR | S_IWUSR;
36       buf->st_uid = geteuid32 ();
37       buf->st_gid = getegid32 ();
38       buf->st_nlink = 1;
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;
42     }
43   return 0;
44 }
45
46 int
47 fhandler_mailslot::open (int flags, mode_t mode)
48 {
49   int res = 0;
50   NTSTATUS status;
51   IO_STATUS_BLOCK io;
52   OBJECT_ATTRIBUTES attr;
53   HANDLE x;
54   LARGE_INTEGER timeout;
55
56   switch (flags & O_ACCMODE)
57     {
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,
63                                      0, 0, &timeout);
64       if (!NT_SUCCESS (status))
65         {
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. */
75 #if 0
76           if (status != STATUS_OBJECT_NAME_COLLISION)
77             {
78               __seterrno_from_nt_status (status);
79               break;
80             }
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);
85 #endif
86           if (!NT_SUCCESS (status))
87             {
88               __seterrno_from_nt_status (status);
89               break;
90             }
91         }
92       set_io_handle (x);
93       set_flags (flags, O_BINARY);
94       res = 1;
95       set_open_status ();
96       break;
97     case O_WRONLY:      /* Client */
98       /* The client is the DLL exclusively.  Don't allow opening from
99          application code. */
100       extern fhandler_mailslot *dev_kmsg;
101       if (this != dev_kmsg)
102         {
103           set_errno (EPERM);    /* As on Linux. */
104           break;
105         }
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))
111         {
112           __seterrno_from_nt_status (status);
113           break;
114         }
115       set_io_handle (x);
116       set_flags (flags, O_BINARY);
117       res = 1;
118       set_open_status ();
119       break;
120     default:
121       set_errno (EINVAL);
122       break;
123     }
124   return res;
125 }
126
127 int
128 fhandler_mailslot::write (const void *ptr, size_t len)
129 {
130   /* Check for 425/426 byte weirdness */
131   if (len == 425 || len == 426)
132     {
133       char buf[427];
134       buf[425] = buf[426] = '\0';
135       memcpy (buf, ptr, len);
136       return raw_write (buf, 427);
137     }
138   return raw_write (ptr, len);
139 }
140
141 int
142 fhandler_mailslot::ioctl (unsigned int cmd, void *buf)
143 {
144   int res = -1;
145   NTSTATUS status;
146   IO_STATUS_BLOCK io;
147
148   switch (cmd)
149     {
150     case FIONBIO:
151       {
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))
157           {
158             debug_printf ("NtSetInformationFile (%X): %08x",
159                           fmsi.ReadTimeout.QuadPart, status);
160             __seterrno_from_nt_status (status);
161             break;
162           }
163       }
164       /*FALLTHRU*/
165     default:
166       res =  fhandler_base::ioctl (cmd, buf);
167       break;
168     }
169   return res;
170 }