]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/fhandler_fifo.cc
Remove unneeded header files from source files throughout.
[newlib-cygwin.git] / winsup / cygwin / fhandler_fifo.cc
CommitLineData
06e18175 1/* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes.
d1fb625d 2
a7d2cc16 3 Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
d1fb625d
CF
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"
ade47a34 12#include "miscfuncs.h"
d1fb625d
CF
13
14#include "cygerrno.h"
d1fb625d
CF
15#include "security.h"
16#include "path.h"
17#include "fhandler.h"
18#include "dtable.h"
19#include "cygheap.h"
d9c0e3ec
CF
20#include "sigproc.h"
21#include "cygtls.h"
d1fb625d 22
d9c0e3ec
CF
23fhandler_fifo::fhandler_fifo ():
24 wait_state (fifo_unknown)
d1fb625d 25{
d9c0e3ec
CF
26 get_overlapped ()->hEvent = NULL;
27 need_fork_fixup (true);
d1fb625d
CF
28}
29
d9c0e3ec
CF
30HANDLE
31fhandler_fifo::open_nonserver (const char *npname, unsigned low_flags,
32 LPSECURITY_ATTRIBUTES sa_buf)
d1fb625d 33{
d9c0e3ec
CF
34 DWORD mode = 0;
35 if (low_flags == O_RDONLY)
36 mode = GENERIC_READ;
37 else if (low_flags = O_WRONLY)
38 mode = GENERIC_WRITE;
d1fb625d 39 else
d9c0e3ec
CF
40 mode = GENERIC_READ | GENERIC_WRITE;
41 while (1)
d1fb625d 42 {
d9c0e3ec
CF
43 HANDLE h = CreateFile (npname, mode, 0, sa_buf, OPEN_EXISTING,
44 FILE_FLAG_OVERLAPPED, NULL);
45 if (h != INVALID_HANDLE_VALUE || GetLastError () != ERROR_PIPE_NOT_CONNECTED)
46 return h;
47 if (&_my_tls != _main_tls)
48 low_priority_sleep (0);
49 else if (WaitForSingleObject (signal_arrived, 0) == WAIT_OBJECT_0)
d1fb625d 50 {
d9c0e3ec
CF
51 set_errno (EINTR);
52 return NULL;
d1fb625d 53 }
d1fb625d
CF
54 }
55}
56
d9c0e3ec 57#define FIFO_PIPE_MODE (PIPE_TYPE_BYTE | PIPE_READMODE_BYTE)
fb201f92 58
d1fb625d 59int
d9c0e3ec 60fhandler_fifo::open (int flags, mode_t)
d1fb625d 61{
d9c0e3ec 62 int res;
86a1bb43 63 char npname[MAX_PATH];
d9c0e3ec
CF
64 DWORD mode = 0;
65
636c94d8
CV
66 /* Generate a semi-unique name to associate with this fifo. */
67 __small_sprintf (npname, "\\\\.\\pipe\\__cygfifo__%08x_%016X",
68 get_dev (), get_ino ());
d9c0e3ec
CF
69
70 unsigned low_flags = flags & O_ACCMODE;
71 if (low_flags == O_RDONLY)
72 mode = PIPE_ACCESS_INBOUND;
73 else if (low_flags == O_WRONLY)
74 mode = PIPE_ACCESS_OUTBOUND;
75 else if (low_flags == O_RDWR)
76 mode = PIPE_ACCESS_DUPLEX;
77
78 if (!mode)
d1fb625d 79 {
d9c0e3ec
CF
80 set_errno (EINVAL);
81 res = 0;
82 }
83 else
84 {
85 char char_sa_buf[1024];
86 LPSECURITY_ATTRIBUTES sa_buf =
87 sec_user ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid());
88 mode |= FILE_FLAG_OVERLAPPED;
89 HANDLE h = CreateNamedPipe(npname, mode, FIFO_PIPE_MODE,
90 PIPE_UNLIMITED_INSTANCES, 0, 0,
91 NMPWAIT_WAIT_FOREVER, sa_buf);
92 if (h != INVALID_HANDLE_VALUE)
93 wait_state = fifo_wait_for_client;
beffbc5e 94 else
d9c0e3ec 95 switch (GetLastError ())
d1fb625d 96 {
d9c0e3ec
CF
97 case ERROR_ACCESS_DENIED:
98 h = open_nonserver (npname, low_flags, sa_buf);
99 if (h != INVALID_HANDLE_VALUE)
100 {
101 wait_state = fifo_wait_for_server;
102 break;
103 }
104 /* fall through intentionally */
105 default:
beffbc5e 106 __seterrno ();
d9c0e3ec 107 break;
d1fb625d 108 }
d9c0e3ec
CF
109 if (!h || h == INVALID_HANDLE_VALUE)
110 res = 0;
111 else if (!setup_overlapped ())
112 {
113 __seterrno ();
114 res = 0;
115 }
116 else
117 {
118 set_io_handle (h);
119 set_flags (flags);
120 res = 1;
d1fb625d 121 }
d1fb625d
CF
122 }
123
d9c0e3ec 124 debug_printf ("returning %d, errno %d", res, get_errno ());
d1fb625d
CF
125 return res;
126}
127
d9c0e3ec
CF
128bool
129fhandler_fifo::wait (bool iswrite)
d1fb625d 130{
d9c0e3ec 131 switch (wait_state)
4470d66d 132 {
d9c0e3ec
CF
133 case fifo_wait_for_client:
134 bool res = ConnectNamedPipe (get_handle (), get_overlapped ());
135 if (res || GetLastError () == ERROR_PIPE_CONNECTED)
136 return true;
ee298432 137 return wait_overlapped (res, iswrite, NULL);
d9c0e3ec
CF
138 default:
139 break;
4470d66d 140 }
d9c0e3ec
CF
141 return true;
142}
4470d66d 143
d9c0e3ec
CF
144void
145fhandler_fifo::read (void *in_ptr, size_t& len)
146{
147 if (!wait (false))
148 len = 0;
beffbc5e 149 else
d9c0e3ec 150 read_overlapped (in_ptr, len);
d1fb625d
CF
151}
152
153int
d9c0e3ec 154fhandler_fifo::write (const void *ptr, size_t len)
d1fb625d 155{
d9c0e3ec 156 return wait (true) ? write_overlapped (ptr, len) : -1;
d1fb625d 157}
3323df7e
CV
158
159int __stdcall
160fhandler_fifo::fstatvfs (struct statvfs *sfs)
161{
86a1bb43
CV
162 fhandler_disk_file fh (pc);
163 fh.get_device () = FH_FS;
164 return fh.fstatvfs (sfs);
3323df7e 165}
This page took 0.158908 seconds and 5 git commands to generate.