]>
Commit | Line | Data |
---|---|---|
1fd5e000 CF |
1 | /* fhandler.h |
2 | ||
3fd68a6a | 3 | Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
f1817d36 | 4 | 2005, 2006, 2007, 2008, 2009, 2010 Red Hat, Inc. |
1fd5e000 CF |
5 | |
6 | This file is part of Cygwin. | |
7 | ||
8 | This software is a copyrighted work licensed under the terms of the | |
9 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
10 | details. */ | |
11 | ||
12 | #ifndef _FHANDLER_H_ | |
13 | #define _FHANDLER_H_ | |
14 | ||
6a574f1a CV |
15 | /* fcntl flags used only internaly. */ |
16 | #define O_NOSYMLINK 0x080000 | |
17 | #define O_DIROPEN 0x100000 | |
18 | ||
19 | /* newlib used to define O_NDELAY differently from O_NONBLOCK. Now it | |
20 | properly defines both to be the same. Unfortunately, we have to | |
aa9d50a1 | 21 | behave properly the old version, too, to accommodate older executables. */ |
6a574f1a CV |
22 | #define OLD_O_NDELAY (CYGWIN_VERSION_CHECK_FOR_OLD_O_NONBLOCK ? 4 : 0) |
23 | ||
24 | /* Care for the old O_NDELAY flag. If one of the flags is set, | |
25 | both flags are set. */ | |
26 | #define O_NONBLOCK_MASK (O_NONBLOCK | OLD_O_NDELAY) | |
27 | ||
7bef7db5 CV |
28 | /* It appears that 64K is the block size used for buffered I/O on NT. |
29 | Using this blocksize in read/write calls in the application results | |
30 | in a much better performance than using smaller values. */ | |
31 | #define PREFERRED_IO_BLKSIZE ((blksize_t) 65536) | |
32 | ||
1fd5e000 | 33 | extern const char *windows_device_names[]; |
bd4ec496 | 34 | extern struct __cygwin_perfile *perfile_table; |
1fd5e000 | 35 | #define __fmode (*(user_data->fmode_ptr)) |
291be307 CF |
36 | extern const char proc[]; |
37 | extern const int proc_len; | |
1fd5e000 CF |
38 | |
39 | class select_record; | |
b4fa8164 | 40 | class select_stuff; |
1fd5e000 | 41 | class fhandler_disk_file; |
a998dd70 | 42 | class inode_t; |
7903ee69 CF |
43 | typedef struct __DIR DIR; |
44 | struct dirent; | |
ab7f9b93 | 45 | struct iovec; |
e3d1d515 | 46 | struct __acl32; |
1fd5e000 | 47 | |
2693c1ac CF |
48 | enum dirent_states |
49 | { | |
358063ac CF |
50 | dirent_ok = 0x0000, |
51 | dirent_saw_dot = 0x0001, | |
52 | dirent_saw_dot_dot = 0x0002, | |
53 | dirent_saw_eof = 0x0004, | |
54 | dirent_isroot = 0x0008, | |
c115f31f | 55 | dirent_set_d_ino = 0x0010, |
40570a82 | 56 | dirent_get_d_ino = 0x0020, |
0d3f3658 | 57 | dirent_nfs_d_ino = 0x0040, |
40570a82 CV |
58 | |
59 | /* Global flags which must not be deleted on rewinddir or seekdir. */ | |
0d3f3658 | 60 | dirent_info_mask = 0x0078 |
2693c1ac CF |
61 | }; |
62 | ||
56551a9b | 63 | enum conn_state |
b79f85c2 CV |
64 | { |
65 | unconnected = 0, | |
66 | connect_pending = 1, | |
04843bf4 CV |
67 | connected = 2, |
68 | connect_failed = 3 | |
b79f85c2 CV |
69 | }; |
70 | ||
49dd6fc6 CF |
71 | enum line_edit_status |
72 | { | |
49dd6fc6 CF |
73 | line_edit_ok = 0, |
74 | line_edit_input_done = 1, | |
b18962e2 CF |
75 | line_edit_signalled = 2, |
76 | line_edit_error = 3, | |
77 | line_edit_pipe_full = 4 | |
49dd6fc6 CF |
78 | }; |
79 | ||
a7cde2b9 CF |
80 | enum bg_check_types |
81 | { | |
82 | bg_error = -1, | |
83 | bg_eof = 0, | |
84 | bg_ok = 1, | |
85 | bg_signalled = 2 | |
86 | }; | |
87 | ||
a9a5b2ea CV |
88 | enum query_state { |
89 | no_query = 0, | |
e8597065 | 90 | query_read_control = 1, |
3323df7e | 91 | query_read_attributes = 2, |
fe7bbe15 CV |
92 | query_write_control = 3, |
93 | query_write_attributes = 4 | |
a9a5b2ea CV |
94 | }; |
95 | ||
4a77aea0 CV |
96 | enum del_lock_called_from { |
97 | on_close, | |
98 | after_fork, | |
99 | after_exec | |
100 | }; | |
101 | ||
1fd5e000 CF |
102 | class fhandler_base |
103 | { | |
7ac61736 | 104 | friend class dtable; |
26edeb6a | 105 | friend void close_all_files (bool); |
b79f85c2 | 106 | |
b79f85c2 CV |
107 | struct status_flags |
108 | { | |
109 | unsigned rbinary : 1; /* binary read mode */ | |
110 | unsigned rbinset : 1; /* binary read mode explicitly set */ | |
111 | unsigned wbinary : 1; /* binary write mode */ | |
112 | unsigned wbinset : 1; /* binary write mode explicitly set */ | |
56551a9b | 113 | unsigned nohandle : 1; /* No handle associated with fhandler. */ |
b79f85c2 | 114 | unsigned uninterruptible_io : 1; /* Set if I/O should be uninterruptible. */ |
56551a9b | 115 | unsigned did_lseek : 1; /* set when lseek is called as a flag that |
b79f85c2 CV |
116 | _write should check if we've moved |
117 | beyond EOF, zero filling or making | |
118 | file sparse if so. */ | |
2b09be25 | 119 | unsigned query_open : 3; /* open file without requesting either |
264f41f0 | 120 | read or write access */ |
b79f85c2 CV |
121 | unsigned close_on_exec : 1; /* close-on-exec */ |
122 | unsigned need_fork_fixup : 1; /* Set if need to fixup after fork. */ | |
123 | ||
7aa88267 | 124 | public: |
b79f85c2 | 125 | status_flags () : |
56551a9b | 126 | rbinary (0), rbinset (0), wbinary (0), wbinset (0), nohandle (0), |
ad4e943f | 127 | uninterruptible_io (0), did_lseek (0), |
570858c3 | 128 | query_open (no_query), close_on_exec (0), need_fork_fixup (0) |
b79f85c2 CV |
129 | {} |
130 | } status, open_status; | |
131 | ||
1229d4f4 | 132 | private: |
f3ea62a8 | 133 | int access; |
1fd5e000 CF |
134 | HANDLE io_handle; |
135 | ||
636c94d8 | 136 | __ino64_t ino; /* file ID or hashed filename, depends on FS. */ |
1fd5e000 | 137 | |
1229d4f4 | 138 | protected: |
1fd5e000 | 139 | /* File open flags from open () and fcntl () calls */ |
f3ea62a8 | 140 | int openflags; |
1fd5e000 | 141 | |
1fd5e000 CF |
142 | char *rabuf; /* used for crlf conversion in text files */ |
143 | size_t ralen; | |
144 | size_t raixget; | |
145 | size_t raixput; | |
146 | size_t rabuflen; | |
147 | ||
636c94d8 CV |
148 | /* Used for advisory file locking. See flock.cc. */ |
149 | long long unique_id; | |
4a77aea0 | 150 | void del_my_locks (del_lock_called_from); |
a998dd70 | 151 | |
8bce0d72 | 152 | HANDLE read_state; |
fee56469 | 153 | int wait_overlapped (bool, bool, DWORD *, DWORD = 0) __attribute__ ((regparm (3))); |
9a8597c1 | 154 | bool setup_overlapped (bool doit = true) __attribute__ ((regparm (2))); |
d9c0e3ec | 155 | void destroy_overlapped () __attribute__ ((regparm (1))); |
1fd5e000 | 156 | |
1229d4f4 | 157 | public: |
e9737793 | 158 | class fhandler_base *archetype; |
8e10c431 CF |
159 | int usecount; |
160 | ||
4a971ce4 CV |
161 | path_conv pc; |
162 | ||
20f9af53 | 163 | virtual void set_name (path_conv &pc); |
a9e9da89 | 164 | virtual void set_name (const char *s) {pc.set_normalized_path (s);} |
7ac61736 | 165 | int error () const {return pc.error;} |
e00700cd | 166 | void set_error (int error) {pc.error = error;} |
7ac61736 CF |
167 | bool exists () const {return pc.exists ();} |
168 | int pc_binmode () const {return pc.binmode ();} | |
169 | device& dev () {return pc.dev;} | |
f5808137 | 170 | operator DWORD& () {return (DWORD&) pc;} |
8e10c431 | 171 | virtual size_t size () const {return sizeof (*this);} |
1fd5e000 | 172 | |
b0e82b74 | 173 | virtual fhandler_base& operator =(fhandler_base &x); |
7ac61736 | 174 | fhandler_base (); |
1fd5e000 CF |
175 | virtual ~fhandler_base (); |
176 | ||
177 | /* Non-virtual simple accessor functions. */ | |
ec300c99 | 178 | void set_io_handle (HANDLE x) { io_handle = x; } |
1fd5e000 | 179 | |
8e10c431 | 180 | DWORD& get_device () { return dev ().devn; } |
7ac61736 CF |
181 | DWORD get_major () { return dev ().major; } |
182 | DWORD get_minor () { return dev ().minor; } | |
183 | virtual int get_unit () { return dev ().minor; } | |
1fd5e000 | 184 | |
7ac61736 | 185 | int get_access () const { return access; } |
f3ea62a8 | 186 | void set_access (int x) { access = x; } |
1fd5e000 | 187 | |
f3ea62a8 | 188 | int get_flags () { return openflags; } |
e35f391f | 189 | void set_flags (int x, int supplied_bin = 0); |
1fd5e000 | 190 | |
5a64d869 | 191 | bool is_nonblocking (); |
c16548b2 | 192 | void set_nonblocking (int); |
5fd12fb0 | 193 | |
56551a9b CV |
194 | bool wbinary () const { return status.wbinset ? status.wbinary : 1; } |
195 | bool rbinary () const { return status.rbinset ? status.rbinary : 1; } | |
1fd5e000 | 196 | |
56551a9b CV |
197 | void wbinary (bool b) {status.wbinary = b; status.wbinset = 1;} |
198 | void rbinary (bool b) {status.rbinary = b; status.rbinset = 1;} | |
5a64d869 | 199 | |
f3ea62a8 | 200 | void set_open_status () {open_status = status;} |
f3ea62a8 CF |
201 | void reset_to_open_binmode () |
202 | { | |
e35f391f | 203 | set_flags ((get_flags () & ~(O_TEXT | O_BINARY)) |
b79f85c2 CV |
204 | | ((open_status.wbinary || open_status.rbinary) |
205 | ? O_BINARY : O_TEXT)); | |
f3ea62a8 | 206 | } |
1fd5e000 | 207 | |
825b3882 CV |
208 | IMPLEMENT_STATUS_FLAG (bool, wbinset) |
209 | IMPLEMENT_STATUS_FLAG (bool, rbinset) | |
210 | IMPLEMENT_STATUS_FLAG (bool, nohandle) | |
211 | IMPLEMENT_STATUS_FLAG (bool, uninterruptible_io) | |
825b3882 CV |
212 | IMPLEMENT_STATUS_FLAG (bool, did_lseek) |
213 | IMPLEMENT_STATUS_FLAG (query_state, query_open) | |
214 | IMPLEMENT_STATUS_FLAG (bool, close_on_exec) | |
215 | IMPLEMENT_STATUS_FLAG (bool, need_fork_fixup) | |
56551a9b CV |
216 | |
217 | int get_default_fmode (int flags); | |
1fd5e000 | 218 | |
56551a9b | 219 | virtual void set_close_on_exec (bool val); |
1fd5e000 | 220 | |
6b91b8d5 CF |
221 | LPSECURITY_ATTRIBUTES get_inheritance (bool all = 0) |
222 | { | |
223 | if (all) | |
56551a9b | 224 | return close_on_exec () ? &sec_all_nih : &sec_all; |
6b91b8d5 | 225 | else |
56551a9b | 226 | return close_on_exec () ? &sec_none_nih : &sec_none; |
6b91b8d5 CF |
227 | } |
228 | ||
b14f53a8 | 229 | virtual int fixup_before_fork_exec (DWORD) { return 0; } |
dd4f0b23 | 230 | virtual void fixup_after_fork (HANDLE); |
3378bdfc | 231 | virtual void fixup_after_exec (); |
85a798d6 CF |
232 | void create_read_state (LONG n) |
233 | { | |
234 | read_state = CreateSemaphore (&sec_none_nih, 0, n, NULL); | |
b040009e | 235 | ProtectHandle (read_state); |
85a798d6 CF |
236 | } |
237 | ||
238 | void signal_read_state (LONG n) | |
239 | { | |
0c55f6ed | 240 | ReleaseSemaphore (read_state, n, NULL); |
85a798d6 | 241 | } |
1fd5e000 | 242 | |
5a64d869 | 243 | bool get_readahead_valid () { return raixget < ralen; } |
1fd5e000 CF |
244 | int puts_readahead (const char *s, size_t len = (size_t) -1); |
245 | int put_readahead (char value); | |
246 | ||
247 | int get_readahead (); | |
248 | int peek_readahead (int queryput = 0); | |
249 | ||
250 | int eat_readahead (int n); | |
251 | ||
252 | void set_readahead_valid (int val, int ch = -1); | |
253 | ||
3f0b4935 CF |
254 | int get_readahead_into_buffer (char *buf, size_t buflen); |
255 | ||
f4e815bc | 256 | bool has_acls () const { return pc.has_acls (); } |
1fd5e000 | 257 | |
f4e815bc | 258 | bool isremote () { return pc.isremote (); } |
ecfb6f11 | 259 | |
f4e815bc | 260 | bool has_attribute (DWORD x) const {return pc.has_attribute (x);} |
7ac61736 CF |
261 | const char *get_name () const { return pc.normalized_path; } |
262 | const char *get_win32_name () { return pc.get_win32 (); } | |
636c94d8 CV |
263 | __dev32_t get_dev () { return pc.fs_serial_number (); } |
264 | __ino64_t get_ino () { return ino ?: ino = hash_path_name (0, pc.get_nt_native_path ()); } | |
265 | long long get_unique_id () const { return unique_id; } | |
4f27e288 CV |
266 | /* Returns name used for /proc/<pid>/fd in buf. */ |
267 | virtual char *get_proc_fd_name (char *buf); | |
1fd5e000 | 268 | |
d7aac2ac | 269 | virtual void hclose (HANDLE h) {CloseHandle (h);} |
c16548b2 | 270 | virtual void set_no_inheritance (HANDLE &, bool); |
1fd5e000 CF |
271 | |
272 | /* fixup fd possibly non-inherited handles after fork */ | |
c16548b2 | 273 | bool fork_fixup (HANDLE, HANDLE &, const char *); |
b14f53a8 | 274 | virtual bool need_fixup_before () const {return false;} |
1fd5e000 | 275 | |
c16548b2 CF |
276 | virtual int open (int, mode_t = 0); |
277 | int open_fs (int, mode_t = 0); | |
1fd5e000 | 278 | virtual int close (); |
deafd19c | 279 | int close_fs () { return fhandler_base::close (); } |
7ac61736 CF |
280 | virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); |
281 | int __stdcall fstat_fs (struct __stat64 *buf) __attribute__ ((regparm (2))); | |
282 | int __stdcall fstat_helper (struct __stat64 *buf, | |
f1817d36 CV |
283 | PLARGE_INTEGER ChangeTime, |
284 | PLARGE_INTEGER LastAccessTime, | |
285 | PLARGE_INTEGER LastWriteTime, | |
286 | PLARGE_INTEGER CreationTime, | |
4e5a3fa5 | 287 | DWORD dwVolumeSerialNumber, |
330a2fae | 288 | ULONGLONG nFileSize, |
2a24463d | 289 | LONGLONG nAllocSize, |
330a2fae | 290 | ULONGLONG nFileIndex, |
f3810c72 CV |
291 | DWORD nNumberOfLinks, |
292 | DWORD dwFileAttributes) | |
7ac61736 | 293 | __attribute__ ((regparm (3))); |
fe6934da | 294 | int __stdcall fstat_by_nfs_ea (struct __stat64 *buf) __attribute__ ((regparm (2))); |
7ac61736 CF |
295 | int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2))); |
296 | int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2))); | |
3323df7e | 297 | virtual int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); |
eba32ec8 | 298 | int utimens_fs (const struct timespec *) __attribute__ ((regparm (2))); |
854c8700 | 299 | virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1))); |
ddf9c4a7 | 300 | virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2))); |
e3d1d515 | 301 | virtual int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3))); |
50450dcc CV |
302 | virtual ssize_t __stdcall fgetxattr (const char *, void *, size_t) __attribute__ ((regparm (3))); |
303 | virtual int __stdcall fsetxattr (const char *, const void *, size_t, int) __attribute__ ((regparm (3))); | |
7636b585 CV |
304 | virtual int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3))); |
305 | virtual int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3))); | |
0d75ce96 | 306 | virtual int __stdcall link (const char *) __attribute__ ((regparm (2))); |
eba32ec8 | 307 | virtual int __stdcall utimens (const struct timespec *) __attribute__ ((regparm (2))); |
2f9ae2ed | 308 | virtual int __stdcall fsync () __attribute__ ((regparm (1))); |
1fd5e000 | 309 | virtual int ioctl (unsigned int cmd, void *); |
1eb14bae | 310 | virtual int fcntl (int cmd, void *); |
3c1e8187 | 311 | virtual char const *ttyname () { return get_name (); } |
8bce0d72 | 312 | virtual void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
d9c0e3ec | 313 | virtual void __stdcall read_overlapped (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
840bb397 | 314 | virtual bool __stdcall has_ongoing_io (bool) __attribute__ ((regparm (2))); |
43c23d4b CF |
315 | virtual ssize_t __stdcall write (const void *ptr, size_t len); |
316 | virtual ssize_t __stdcall write_overlapped (const void *ptr, size_t len); | |
317 | virtual ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1); | |
318 | virtual ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1); | |
7d7d09ae CF |
319 | virtual ssize_t __stdcall pread (void *, size_t, _off64_t) __attribute__ ((regparm (3))); |
320 | virtual ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3))); | |
1727fba0 | 321 | virtual _off64_t lseek (_off64_t offset, int whence); |
dc399868 | 322 | virtual int lock (int, struct __flock64 *); |
dcb091ca | 323 | virtual int dup (fhandler_base *child); |
86bc8fad | 324 | virtual int fpathconf (int); |
1fd5e000 | 325 | |
f90e23f2 | 326 | virtual HANDLE mmap (caddr_t *addr, size_t len, int prot, |
1727fba0 | 327 | int flags, _off64_t off); |
d12eba25 CV |
328 | virtual int munmap (HANDLE h, caddr_t addr, size_t len); |
329 | virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags); | |
f90e23f2 | 330 | virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags, |
6d11044c CV |
331 | _off64_t offset, DWORD size, |
332 | void *address); | |
d12eba25 | 333 | |
6a7bea70 | 334 | void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} |
1fd5e000 | 335 | |
3c4f2024 | 336 | virtual int init (HANDLE, DWORD, mode_t); |
1fd5e000 CF |
337 | |
338 | virtual int tcflush (int); | |
339 | virtual int tcsendbreak (int); | |
340 | virtual int tcdrain (); | |
341 | virtual int tcflow (int); | |
342 | virtual int tcsetattr (int a, const struct termios *t); | |
343 | virtual int tcgetattr (struct termios *t); | |
344 | virtual int tcsetpgrp (const pid_t pid); | |
345 | virtual int tcgetpgrp (); | |
43fb5c93 | 346 | virtual bool is_tty () const { return false; } |
421ba492 CF |
347 | virtual bool ispipe () const { return false; } |
348 | virtual pid_t get_popen_pid () const {return 0;} | |
349 | virtual bool isdevice () const { return true; } | |
350 | virtual bool isfifo () const { return false; } | |
1fd5e000 | 351 | virtual char *ptsname () { return NULL;} |
7ac61736 | 352 | virtual class fhandler_socket *is_socket () { return NULL; } |
1fd5e000 CF |
353 | virtual class fhandler_console *is_console () { return 0; } |
354 | virtual int is_windows () {return 0; } | |
355 | ||
43c23d4b CF |
356 | virtual void __stdcall raw_read (void *ptr, size_t& ulen); |
357 | virtual ssize_t __stdcall raw_write (const void *ptr, size_t ulen); | |
d9c0e3ec | 358 | virtual OVERLAPPED *get_overlapped () {return NULL;} |
9a8597c1 CF |
359 | virtual OVERLAPPED *get_overlapped_buffer () {return NULL;} |
360 | virtual void set_overlapped (OVERLAPPED *) {} | |
1fd5e000 | 361 | |
1fd5e000 CF |
362 | /* Virtual accessor functions to hide the fact |
363 | that some fd's have two handles. */ | |
2116a175 CF |
364 | virtual HANDLE& get_handle () { return io_handle; } |
365 | virtual HANDLE& get_io_handle () { return io_handle; } | |
366 | virtual HANDLE& get_output_handle () { return io_handle; } | |
2e008fb9 | 367 | virtual bool hit_eof () {return false;} |
b4fa8164 CF |
368 | virtual select_record *select_read (select_stuff *); |
369 | virtual select_record *select_write (select_stuff *); | |
370 | virtual select_record *select_except (select_stuff *); | |
476dfb65 | 371 | virtual int ready_for_read (int fd, DWORD howlong); |
7ac61736 | 372 | virtual const char *get_native_name () |
1fd5e000 | 373 | { |
0e1ba888 | 374 | return dev ().native; |
1fd5e000 | 375 | } |
a7cde2b9 | 376 | virtual bg_check_types bg_check (int) {return bg_ok;} |
b0e82b74 CF |
377 | void clear_readahead () |
378 | { | |
379 | raixput = raixget = ralen = rabuflen = 0; | |
380 | rabuf = NULL; | |
381 | } | |
382 | void operator delete (void *); | |
c4157069 | 383 | virtual void set_eof () {} |
125b724d CF |
384 | virtual int mkdir (mode_t mode); |
385 | virtual int rmdir (); | |
40570a82 | 386 | virtual DIR *opendir (int fd) __attribute__ ((regparm (2))); |
d9a22764 | 387 | virtual int readdir (DIR *, dirent *) __attribute__ ((regparm (3))); |
1727fba0 CV |
388 | virtual _off64_t telldir (DIR *); |
389 | virtual void seekdir (DIR *, _off64_t); | |
7903ee69 CF |
390 | virtual void rewinddir (DIR *); |
391 | virtual int closedir (DIR *); | |
43fb5c93 | 392 | virtual bool is_slow () {return false;} |
7ac61736 | 393 | bool is_auto_device () {return isdevice () && !dev ().isfs ();} |
f4e815bc | 394 | bool is_fs_special () {return pc.is_fs_special ();} |
52792a77 | 395 | bool issymlink () {return pc.issymlink ();} |
f4e815bc | 396 | bool device_access_denied (int) __attribute__ ((regparm (2))); |
3dbe243a | 397 | int fhaccess (int flags, bool) __attribute__ ((regparm (3))); |
1fd5e000 CF |
398 | }; |
399 | ||
13505ca8 CV |
400 | class fhandler_mailslot : public fhandler_base |
401 | { | |
e70fdfb9 | 402 | POBJECT_ATTRIBUTES get_object_attr (OBJECT_ATTRIBUTES &, PUNICODE_STRING, int); |
13505ca8 CV |
403 | public: |
404 | fhandler_mailslot (); | |
405 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); | |
406 | int open (int flags, mode_t mode = 0); | |
43c23d4b | 407 | ssize_t __stdcall write (const void *ptr, size_t len); |
13505ca8 | 408 | int ioctl (unsigned int cmd, void *); |
b4fa8164 | 409 | select_record *select_read (select_stuff *); |
13505ca8 CV |
410 | }; |
411 | ||
025c1fac | 412 | struct wsa_event |
70fab4ec CV |
413 | { |
414 | LONG serial_number; | |
415 | long events; | |
416 | int connect_errorcode; | |
417 | pid_t owner; | |
025c1fac | 418 | }; |
70e476d2 | 419 | |
1fd5e000 CF |
420 | class fhandler_socket: public fhandler_base |
421 | { | |
1229d4f4 | 422 | private: |
1fd5e000 | 423 | int addr_family; |
4deace13 | 424 | int type; |
b832c4cf | 425 | int connect_secret[4]; |
c8b404bf | 426 | |
70e476d2 CV |
427 | wsa_event *wsock_events; |
428 | HANDLE wsock_mtx; | |
70e476d2 | 429 | HANDLE wsock_evt; |
8f713b6b | 430 | public: |
70e476d2 | 431 | bool init_events (); |
8f713b6b CV |
432 | int evaluate_events (const long event_mask, long &events, const bool erase); |
433 | const HANDLE wsock_event () const { return wsock_evt; } | |
434 | const LONG serial_number () const { return wsock_events->serial_number; } | |
70e476d2 | 435 | private: |
935d37f1 | 436 | int wait_for_events (const long event_mask, bool dontwait); |
70e476d2 CV |
437 | void release_events (); |
438 | ||
c8b404bf CV |
439 | pid_t sec_pid; |
440 | __uid32_t sec_uid; | |
441 | __gid32_t sec_gid; | |
442 | pid_t sec_peer_pid; | |
443 | __uid32_t sec_peer_uid; | |
444 | __gid32_t sec_peer_gid; | |
b832c4cf CV |
445 | void af_local_set_secret (char *); |
446 | void af_local_setblocking (bool &, bool &); | |
447 | void af_local_unsetblocking (bool, bool); | |
2f9ae2ed | 448 | void af_local_set_cred (); |
b832c4cf | 449 | void af_local_copy (fhandler_socket *); |
2f9ae2ed CF |
450 | bool af_local_recv_secret (); |
451 | bool af_local_send_secret (); | |
452 | bool af_local_recv_cred (); | |
453 | bool af_local_send_cred (); | |
454 | int af_local_accept (); | |
a6099ff8 | 455 | public: |
2f9ae2ed CF |
456 | int af_local_connect (); |
457 | void af_local_set_sockpair_cred (); | |
c8b404bf | 458 | |
975a6301 CV |
459 | private: |
460 | int _rmem; | |
461 | int _wmem; | |
462 | public: | |
463 | int &rmem () { return _rmem; } | |
464 | int &wmem () { return _wmem; } | |
465 | void rmem (int nrmem) { _rmem = nrmem; } | |
466 | void wmem (int nwmem) { _wmem = nwmem; } | |
467 | ||
b14f53a8 CV |
468 | private: |
469 | struct _WSAPROTOCOL_INFOW *prot_info_ptr; | |
470 | public: | |
471 | void init_fixup_before (); | |
472 | bool need_fixup_before () const {return prot_info_ptr != NULL;} | |
473 | ||
496337c9 | 474 | private: |
2fe27909 | 475 | char *sun_path; |
d3d4aa96 | 476 | char *peer_sun_path; |
7aa88267 CV |
477 | struct status_flags |
478 | { | |
56551a9b CV |
479 | unsigned async_io : 1; /* async I/O */ |
480 | unsigned saw_shutdown_read : 1; /* Socket saw a SHUT_RD */ | |
481 | unsigned saw_shutdown_write : 1; /* Socket saw a SHUT_WR */ | |
5369605f | 482 | unsigned saw_reuseaddr : 1; /* Socket saw SO_REUSEADDR call */ |
70e476d2 | 483 | unsigned listener : 1; /* listen called */ |
56551a9b | 484 | unsigned connect_state : 2; |
7aa88267 CV |
485 | public: |
486 | status_flags () : | |
56551a9b | 487 | async_io (0), saw_shutdown_read (0), saw_shutdown_write (0), |
70e476d2 | 488 | listener (0), connect_state (unconnected) |
7aa88267 CV |
489 | {} |
490 | } status; | |
dd4f0b23 | 491 | |
1229d4f4 | 492 | public: |
7ac61736 | 493 | fhandler_socket (); |
dd4f0b23 | 494 | ~fhandler_socket (); |
2116a175 | 495 | int get_socket () { return (int) get_handle(); } |
7ac61736 | 496 | fhandler_socket *is_socket () { return this; } |
5835f2cf | 497 | |
825b3882 CV |
498 | IMPLEMENT_STATUS_FLAG (bool, async_io) |
499 | IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_read) | |
500 | IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write) | |
5369605f | 501 | IMPLEMENT_STATUS_FLAG (bool, saw_reuseaddr) |
70e476d2 | 502 | IMPLEMENT_STATUS_FLAG (bool, listener) |
825b3882 | 503 | IMPLEMENT_STATUS_FLAG (conn_state, connect_state) |
d5591d9d | 504 | |
be5007aa CV |
505 | int bind (const struct sockaddr *name, int namelen); |
506 | int connect (const struct sockaddr *name, int namelen); | |
507 | int listen (int backlog); | |
508 | int accept (struct sockaddr *peer, int *len); | |
509 | int getsockname (struct sockaddr *name, int *namelen); | |
510 | int getpeername (struct sockaddr *name, int *namelen); | |
c8b404bf | 511 | int getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid); |
be5007aa | 512 | |
e8309efd | 513 | int open (int flags, mode_t mode = 0); |
43c23d4b | 514 | ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1); |
3787b37e | 515 | inline ssize_t recv_internal (struct _WSAMSG *wsamsg); |
70e476d2 CV |
516 | ssize_t recvfrom (void *ptr, size_t len, int flags, |
517 | struct sockaddr *from, int *fromlen); | |
88386154 | 518 | ssize_t recvmsg (struct msghdr *msg, int flags); |
ff86860b | 519 | |
43c23d4b | 520 | ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1); |
3787b37e | 521 | inline ssize_t send_internal (struct _WSAMSG *wsamsg, int flags); |
70e476d2 | 522 | ssize_t sendto (const void *ptr, size_t len, int flags, |
be5007aa | 523 | const struct sockaddr *to, int tolen); |
88386154 | 524 | ssize_t sendmsg (const struct msghdr *msg, int flags); |
be5007aa | 525 | |
1fd5e000 | 526 | int ioctl (unsigned int cmd, void *); |
1eb14bae | 527 | int fcntl (int cmd, void *); |
1727fba0 | 528 | _off64_t lseek (_off64_t, int) { return 0; } |
be5007aa | 529 | int shutdown (int how); |
1fd5e000 | 530 | int close (); |
d7aac2ac | 531 | void hclose (HANDLE) {close ();} |
dcb091ca | 532 | int dup (fhandler_base *child); |
dd4f0b23 | 533 | |
56551a9b | 534 | void set_close_on_exec (bool val); |
b14f53a8 | 535 | int fixup_before_fork_exec (DWORD); |
dd4f0b23 | 536 | void fixup_after_fork (HANDLE); |
b14f53a8 | 537 | void fixup_after_exec (); |
4f27e288 | 538 | char *get_proc_fd_name (char *buf); |
1fd5e000 | 539 | |
b4fa8164 CF |
540 | select_record *select_read (select_stuff *); |
541 | select_record *select_write (select_stuff *); | |
542 | select_record *select_except (select_stuff *); | |
8f713b6b | 543 | int ready_for_read (int, DWORD) { return true; } |
1fd5e000 | 544 | void set_addr_family (int af) {addr_family = af;} |
fae28904 | 545 | int get_addr_family () {return addr_family;} |
4deace13 CV |
546 | void set_socket_type (int st) { type = st;} |
547 | int get_socket_type () {return type;} | |
2fe27909 CV |
548 | void set_sun_path (const char *path); |
549 | char *get_sun_path () {return sun_path;} | |
d3d4aa96 CV |
550 | void set_peer_sun_path (const char *path); |
551 | char *get_peer_sun_path () {return peer_sun_path;} | |
a6099ff8 | 552 | |
7ac61736 | 553 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); |
3323df7e | 554 | int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); |
c2d0b9d8 CV |
555 | int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1))); |
556 | int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2))); | |
557 | int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3))); | |
0d75ce96 | 558 | int __stdcall link (const char *) __attribute__ ((regparm (2))); |
43fb5c93 | 559 | bool is_slow () {return true;} |
1fd5e000 CF |
560 | }; |
561 | ||
562 | class fhandler_pipe: public fhandler_base | |
563 | { | |
c16548b2 CF |
564 | private: |
565 | pid_t popen_pid; | |
d9c0e3ec | 566 | OVERLAPPED io_status; |
9a8597c1 | 567 | OVERLAPPED *overlapped; |
7ac61736 CF |
568 | public: |
569 | fhandler_pipe (); | |
9a8597c1 CF |
570 | |
571 | OVERLAPPED *get_overlapped () {return overlapped;} | |
572 | OVERLAPPED *get_overlapped_buffer () {return &io_status;} | |
573 | void set_overlapped (OVERLAPPED *ov) {overlapped = ov;} | |
574 | ||
421ba492 CF |
575 | bool ispipe() const { return true; } |
576 | ||
c16548b2 CF |
577 | void set_popen_pid (pid_t pid) {popen_pid = pid;} |
578 | pid_t get_popen_pid () const {return popen_pid;} | |
1727fba0 | 579 | _off64_t lseek (_off64_t offset, int whence); |
b4fa8164 CF |
580 | select_record *select_read (select_stuff *); |
581 | select_record *select_write (select_stuff *); | |
582 | select_record *select_except (select_stuff *); | |
4f27e288 | 583 | char *get_proc_fd_name (char *buf); |
43c23d4b CF |
584 | void __stdcall raw_read (void *ptr, size_t& len); |
585 | ssize_t __stdcall raw_write (const void *, size_t); | |
e8309efd | 586 | int open (int flags, mode_t mode = 0); |
dcb091ca | 587 | int dup (fhandler_base *child); |
49f7ea16 | 588 | int ioctl (unsigned int cmd, void *); |
3323df7e | 589 | int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); |
7636b585 CV |
590 | int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3))); |
591 | int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3))); | |
1d380f59 | 592 | int ready_for_read (int fd, DWORD howlong); |
3c4f2024 | 593 | int init (HANDLE, DWORD, mode_t); |
be1cabba | 594 | static int create (fhandler_pipe *[2], unsigned, int); |
1ffe3e67 | 595 | static int create_selectable (LPSECURITY_ATTRIBUTES, HANDLE&, HANDLE&, DWORD, const char * = NULL); |
c7ef20e7 | 596 | friend class fhandler_fifo; |
7ac61736 CF |
597 | }; |
598 | ||
d9c0e3ec CF |
599 | class fhandler_fifo: public fhandler_base |
600 | { | |
43c23d4b CF |
601 | enum fifo_state |
602 | { | |
603 | fifo_unknown, | |
604 | fifo_wait_for_client, | |
605 | fifo_wait_for_server, | |
606 | fifo_wait_for_next_client, | |
607 | fifo_eof, | |
608 | fifo_error, | |
609 | fifo_eintr, | |
610 | fifo_ok | |
611 | }; | |
d9c0e3ec | 612 | fifo_state wait_state; |
43c23d4b | 613 | HANDLE dummy_client; |
d9c0e3ec CF |
614 | HANDLE open_nonserver (const char *, unsigned, LPSECURITY_ATTRIBUTES); |
615 | OVERLAPPED io_status; | |
616 | bool wait (bool) __attribute__ ((regparm (1))); | |
43c23d4b | 617 | char *fifo_name (char *) __attribute__ ((regparm (2))); |
7ac61736 CF |
618 | public: |
619 | fhandler_fifo (); | |
43c23d4b CF |
620 | void __stdcall raw_read (void *, size_t&); |
621 | ssize_t __stdcall raw_write (const void *, size_t); | |
d9c0e3ec | 622 | int open (int, mode_t); |
43c23d4b CF |
623 | int close (); |
624 | int dup (fhandler_base *child); | |
421ba492 | 625 | bool isfifo () const { return true; } |
43c23d4b | 626 | void set_close_on_exec (bool val); |
3323df7e | 627 | int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); |
d9c0e3ec | 628 | OVERLAPPED *get_overlapped () {return &io_status;} |
9a8597c1 | 629 | OVERLAPPED *get_overlapped_buffer () {return &io_status;} |
b4fa8164 CF |
630 | select_record *select_read (select_stuff *); |
631 | select_record *select_write (select_stuff *); | |
632 | select_record *select_except (select_stuff *); | |
1fd5e000 CF |
633 | }; |
634 | ||
635 | class fhandler_dev_raw: public fhandler_base | |
636 | { | |
1229d4f4 | 637 | protected: |
1fd5e000 CF |
638 | char *devbuf; |
639 | size_t devbufsiz; | |
640 | size_t devbufstart; | |
641 | size_t devbufend; | |
ff084343 CV |
642 | struct status_flags |
643 | { | |
ff084343 | 644 | unsigned lastblk_to_read : 1; |
ff084343 | 645 | public: |
f0987675 | 646 | status_flags () : lastblk_to_read (0) {} |
ff084343 | 647 | } status; |
264f41f0 | 648 | |
825b3882 | 649 | IMPLEMENT_STATUS_FLAG (bool, lastblk_to_read) |
1fd5e000 | 650 | |
7ac61736 | 651 | fhandler_dev_raw (); |
1fd5e000 | 652 | |
1229d4f4 | 653 | public: |
2f9ae2ed | 654 | ~fhandler_dev_raw (); |
1fd5e000 | 655 | |
7ac61736 | 656 | int open (int flags, mode_t mode = 0); |
1fd5e000 | 657 | |
a4b25e31 CV |
658 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); |
659 | ||
dcb091ca | 660 | int dup (fhandler_base *child); |
1fd5e000 | 661 | int ioctl (unsigned int cmd, void *buf); |
7cccedf8 CV |
662 | |
663 | void fixup_after_fork (HANDLE); | |
52806019 | 664 | void fixup_after_exec (); |
1fd5e000 CF |
665 | }; |
666 | ||
667 | class fhandler_dev_floppy: public fhandler_dev_raw | |
668 | { | |
b470a0e8 | 669 | private: |
f0987675 CV |
670 | _off64_t drive_size; |
671 | unsigned long bytes_per_sector; | |
672 | struct status_flags | |
673 | { | |
674 | unsigned eom_detected : 1; | |
675 | public: | |
676 | status_flags () : eom_detected (0) {} | |
677 | } status; | |
678 | ||
679 | IMPLEMENT_STATUS_FLAG (bool, eom_detected) | |
680 | ||
681 | inline _off64_t get_current_position (); | |
f62412f2 | 682 | int get_drive_info (struct hd_geometry *geo); |
b470a0e8 | 683 | |
f0987675 CV |
684 | BOOL write_file (const void *buf, DWORD to_write, DWORD *written, int *err); |
685 | BOOL read_file (void *buf, DWORD to_read, DWORD *read, int *err); | |
1fd5e000 | 686 | |
1229d4f4 | 687 | public: |
7ac61736 | 688 | fhandler_dev_floppy (); |
1fd5e000 | 689 | |
f0987675 CV |
690 | int open (int flags, mode_t mode = 0); |
691 | int dup (fhandler_base *child); | |
43c23d4b CF |
692 | void __stdcall raw_read (void *ptr, size_t& ulen); |
693 | ssize_t __stdcall raw_write (const void *ptr, size_t ulen); | |
f0987675 CV |
694 | _off64_t lseek (_off64_t offset, int whence); |
695 | int ioctl (unsigned int cmd, void *buf); | |
1fd5e000 CF |
696 | }; |
697 | ||
698 | class fhandler_dev_tape: public fhandler_dev_raw | |
699 | { | |
dee56309 | 700 | HANDLE mt_mtx; |
0c8731b8 | 701 | HANDLE mt_evt; |
1fd5e000 | 702 | |
dee56309 CV |
703 | bool is_rewind_device () { return get_minor () < 128; } |
704 | unsigned int driveno () { return (unsigned int) get_minor () & 0x7f; } | |
2f9ae2ed | 705 | void drive_init (); |
99069065 | 706 | |
dee56309 CV |
707 | inline bool _lock (); |
708 | inline int unlock (int ret = 0); | |
1fd5e000 | 709 | |
1229d4f4 | 710 | public: |
7ac61736 | 711 | fhandler_dev_tape (); |
1fd5e000 | 712 | |
7ac61736 | 713 | virtual int open (int flags, mode_t mode = 0); |
2f9ae2ed | 714 | virtual int close (); |
1fd5e000 | 715 | |
43c23d4b CF |
716 | void __stdcall raw_read (void *ptr, size_t& ulen); |
717 | ssize_t __stdcall raw_write (const void *ptr, size_t ulen); | |
dee56309 | 718 | |
1727fba0 | 719 | virtual _off64_t lseek (_off64_t offset, int whence); |
1fd5e000 | 720 | |
7ac61736 | 721 | virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); |
1fd5e000 | 722 | |
dcb091ca | 723 | virtual int dup (fhandler_base *child); |
d9c1b93d CV |
724 | virtual void fixup_after_fork (HANDLE parent); |
725 | virtual void set_close_on_exec (bool val); | |
291be307 | 726 | virtual int ioctl (unsigned int cmd, void *buf); |
1fd5e000 CF |
727 | }; |
728 | ||
729 | /* Standard disk file */ | |
730 | ||
731 | class fhandler_disk_file: public fhandler_base | |
732 | { | |
214c3a11 | 733 | int readdir_helper (DIR *, dirent *, DWORD, DWORD, PUNICODE_STRING fname) __attribute__ ((regparm (3))); |
36ca239f | 734 | |
1229d4f4 | 735 | public: |
0476bae5 | 736 | fhandler_disk_file (); |
2b09be25 | 737 | fhandler_disk_file (path_conv &pc); |
1fd5e000 | 738 | |
7ac61736 | 739 | int open (int flags, mode_t mode); |
dc399868 | 740 | int lock (int, struct __flock64 *); |
421ba492 | 741 | bool isdevice () const { return false; } |
7ac61736 | 742 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); |
854c8700 | 743 | int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1))); |
ddf9c4a7 | 744 | int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2))); |
e3d1d515 | 745 | int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3))); |
50450dcc CV |
746 | ssize_t __stdcall fgetxattr (const char *, void *, size_t) __attribute__ ((regparm (3))); |
747 | int __stdcall fsetxattr (const char *, const void *, size_t, int) __attribute__ ((regparm (3))); | |
7636b585 CV |
748 | int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3))); |
749 | int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3))); | |
0d75ce96 | 750 | int __stdcall link (const char *) __attribute__ ((regparm (2))); |
eba32ec8 | 751 | int __stdcall utimens (const struct timespec *) __attribute__ ((regparm (2))); |
3323df7e | 752 | int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); |
d12eba25 | 753 | |
f90e23f2 | 754 | HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off); |
4ea34a68 CV |
755 | int munmap (HANDLE h, caddr_t addr, size_t len); |
756 | int msync (HANDLE h, caddr_t addr, size_t len, int flags); | |
f90e23f2 | 757 | bool fixup_mmap_after_fork (HANDLE h, int prot, int flags, |
6d11044c | 758 | _off64_t offset, DWORD size, void *address); |
125b724d CF |
759 | int mkdir (mode_t mode); |
760 | int rmdir (); | |
40570a82 | 761 | DIR *opendir (int fd) __attribute__ ((regparm (2))); |
d9a22764 | 762 | int readdir (DIR *, dirent *) __attribute__ ((regparm (3))); |
1727fba0 CV |
763 | _off64_t telldir (DIR *); |
764 | void seekdir (DIR *, _off64_t); | |
7903ee69 CF |
765 | void rewinddir (DIR *); |
766 | int closedir (DIR *); | |
7d7d09ae CF |
767 | |
768 | ssize_t __stdcall pread (void *, size_t, _off64_t) __attribute__ ((regparm (3))); | |
769 | ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3))); | |
1fd5e000 CF |
770 | }; |
771 | ||
97a2e075 CF |
772 | class fhandler_cygdrive: public fhandler_disk_file |
773 | { | |
824d8518 CF |
774 | enum |
775 | { | |
776 | DRVSZ = sizeof ("x:\\") | |
777 | }; | |
97a2e075 CF |
778 | int ndrives; |
779 | const char *pdrive; | |
3b689b97 | 780 | char pdrive_buf[1 + (2 * 26 * DRVSZ)]; |
97a2e075 CF |
781 | void set_drives (); |
782 | public: | |
7ac61736 | 783 | fhandler_cygdrive (); |
c115f31f CV |
784 | int open (int flags, mode_t mode); |
785 | int close (); | |
40570a82 | 786 | DIR *opendir (int fd) __attribute__ ((regparm (2))); |
d9a22764 | 787 | int readdir (DIR *, dirent *) __attribute__ ((regparm (3))); |
97a2e075 CF |
788 | void rewinddir (DIR *); |
789 | int closedir (DIR *); | |
7ac61736 | 790 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); |
97a2e075 CF |
791 | }; |
792 | ||
1fd5e000 CF |
793 | class fhandler_serial: public fhandler_base |
794 | { | |
1229d4f4 | 795 | private: |
087a28bf | 796 | size_t vmin_; /* from termios */ |
1fd5e000 CF |
797 | unsigned int vtime_; /* from termios */ |
798 | pid_t pgrp_; | |
780c42b4 CV |
799 | int rts; /* for Windows 9x purposes only */ |
800 | int dtr; /* for Windows 9x purposes only */ | |
1fd5e000 | 801 | |
1229d4f4 | 802 | public: |
1fd5e000 CF |
803 | int overlapped_armed; |
804 | OVERLAPPED io_status; | |
40139114 | 805 | DWORD ev; |
1fd5e000 CF |
806 | |
807 | /* Constructor */ | |
7ac61736 | 808 | fhandler_serial (); |
1fd5e000 | 809 | |
7ac61736 | 810 | int open (int flags, mode_t mode); |
1fd5e000 | 811 | int close (); |
3c4f2024 | 812 | int init (HANDLE h, DWORD a, mode_t flags); |
1fd5e000 | 813 | void overlapped_setup (); |
dcb091ca | 814 | int dup (fhandler_base *child); |
43c23d4b CF |
815 | void __stdcall raw_read (void *ptr, size_t& ulen); |
816 | ssize_t __stdcall raw_write (const void *ptr, size_t ulen); | |
1fd5e000 CF |
817 | int tcsendbreak (int); |
818 | int tcdrain (); | |
819 | int tcflow (int); | |
780c42b4 | 820 | int ioctl (unsigned int cmd, void *); |
723d64e6 | 821 | int switch_modem_lines (int set, int clr); |
1fd5e000 CF |
822 | int tcsetattr (int a, const struct termios *t); |
823 | int tcgetattr (struct termios *t); | |
1727fba0 | 824 | _off64_t lseek (_off64_t, int) { return 0; } |
1fd5e000 | 825 | int tcflush (int); |
43fb5c93 | 826 | bool is_tty () const { return true; } |
1fd5e000 | 827 | void fixup_after_fork (HANDLE parent); |
52806019 | 828 | void fixup_after_exec (); |
1fd5e000 CF |
829 | |
830 | /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we | |
831 | don't use it for permissions checking. fhandler_tty_slave does | |
832 | permission checking on pgrps. */ | |
833 | virtual int tcgetpgrp () { return pgrp_; } | |
834 | virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; } | |
b4fa8164 CF |
835 | select_record *select_read (select_stuff *); |
836 | select_record *select_write (select_stuff *); | |
837 | select_record *select_except (select_stuff *); | |
43fb5c93 | 838 | bool is_slow () {return true;} |
1fd5e000 CF |
839 | }; |
840 | ||
c1644acb | 841 | #define acquire_output_mutex(ms) \ |
50b2715c | 842 | __acquire_output_mutex (__PRETTY_FUNCTION__, __LINE__, ms) |
c1644acb CF |
843 | |
844 | #define release_output_mutex() \ | |
50b2715c | 845 | __release_output_mutex (__PRETTY_FUNCTION__, __LINE__) |
c1644acb | 846 | |
29ac7f89 CF |
847 | class tty; |
848 | class tty_min; | |
1fd5e000 CF |
849 | class fhandler_termios: public fhandler_base |
850 | { | |
1229d4f4 | 851 | protected: |
1fd5e000 | 852 | HANDLE output_handle; |
9cec3d45 | 853 | virtual void doecho (const void *, DWORD) {}; |
1fd5e000 | 854 | virtual int accept_input () {return 1;}; |
1229d4f4 | 855 | public: |
1fd5e000 | 856 | tty_min *tc; |
7ac61736 CF |
857 | fhandler_termios () : |
858 | fhandler_base () | |
1fd5e000 | 859 | { |
56551a9b | 860 | need_fork_fixup (true); |
1fd5e000 | 861 | } |
2116a175 | 862 | HANDLE& get_output_handle () { return output_handle; } |
46b73ef1 | 863 | line_edit_status line_edit (const char *rptr, int nread, termios&); |
1fd5e000 | 864 | void set_output_handle (HANDLE h) { output_handle = h; } |
2e008fb9 | 865 | void tcinit (tty_min *this_tc, bool force = false); |
43fb5c93 | 866 | bool is_tty () const { return true; } |
1fd5e000 CF |
867 | int tcgetpgrp (); |
868 | int tcsetpgrp (int pid); | |
a7cde2b9 | 869 | bg_check_types bg_check (int sig); |
c1644acb CF |
870 | virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;} |
871 | virtual void __release_output_mutex (const char *fn, int ln) {} | |
cd94b71c | 872 | void echo_erase (int force = 0); |
1727fba0 | 873 | virtual _off64_t lseek (_off64_t, int); |
1fd5e000 CF |
874 | }; |
875 | ||
a53136cc | 876 | enum ansi_intensity |
1fd5e000 | 877 | { |
a53136cc ED |
878 | INTENSITY_INVISIBLE, |
879 | INTENSITY_DIM, | |
880 | INTENSITY_NORMAL, | |
881 | INTENSITY_BOLD | |
882 | }; | |
1fd5e000 | 883 | |
3c66c070 CF |
884 | #define normal 0 |
885 | #define gotesc 1 | |
886 | #define gotsquare 2 | |
887 | #define gotarg1 3 | |
888 | #define gotrsquare 4 | |
889 | #define gotcommand 5 | |
890 | #define gettitle 6 | |
891 | #define eattitle 7 | |
8fd4bd2b CV |
892 | #define gotparen 8 |
893 | #define gotrparen 9 | |
1fd5e000 | 894 | #define MAXARGS 10 |
a53136cc | 895 | |
3c66c070 | 896 | class dev_console |
a53136cc | 897 | { |
a53136cc ED |
898 | WORD default_color, underline_color, dim_color; |
899 | ||
7cdc9fee CV |
900 | /* Used to determine if an input keystroke should be modified with META. */ |
901 | int meta_mask; | |
902 | ||
a53136cc | 903 | /* Output state */ |
1fd5e000 CF |
904 | int state_; |
905 | int args_[MAXARGS]; | |
906 | int nargs_; | |
a53136cc | 907 | unsigned rarg; |
0378d00f | 908 | bool saw_question_mark; |
8fd4bd2b CV |
909 | bool saw_greater_than_sign; |
910 | bool vt100_graphics_mode_active; | |
abfc9c41 | 911 | bool alternate_charset_active; |
6258d96a | 912 | bool metabit; |
a53136cc ED |
913 | |
914 | char my_title_buf [TITLESIZE + 1]; | |
915 | ||
916 | WORD current_win32_attr; | |
917 | ansi_intensity intensity; | |
0378d00f | 918 | bool underline, blink, reverse; |
a53136cc ED |
919 | WORD fg, bg; |
920 | ||
921 | /* saved cursor coordinates */ | |
922 | int savex, savey; | |
923 | ||
f42da31a CV |
924 | /* saved screen */ |
925 | COORD savebufsiz; | |
926 | PCHAR_INFO savebuf; | |
927 | ||
a53136cc ED |
928 | struct |
929 | { | |
930 | short Top, Bottom; | |
931 | } scroll_region; | |
932 | struct | |
933 | { | |
934 | SHORT winTop; | |
935 | SHORT winBottom; | |
936 | COORD dwWinSize; | |
937 | COORD dwBufferSize; | |
938 | COORD dwCursorPosition; | |
939 | WORD wAttributes; | |
940 | } info; | |
941 | ||
942 | COORD dwLastCursorPosition; | |
beeae482 CV |
943 | COORD dwMousePosition; /* scroll-adjusted coord of mouse event */ |
944 | COORD dwLastMousePosition; /* scroll-adjusted coord of previous mouse event */ | |
945 | DWORD dwLastButtonState; /* (not noting mouse wheel events) */ | |
946 | int last_button_code; /* transformed mouse report button code */ | |
a53136cc ED |
947 | int nModifiers; |
948 | ||
0378d00f | 949 | bool insert_mode; |
beeae482 CV |
950 | int use_mouse; |
951 | bool use_focus; | |
0378d00f | 952 | bool raw_win32_keyboard_mode; |
abfc9c41 | 953 | |
a7197550 | 954 | inline UINT get_console_cp (); |
949c0ec2 | 955 | DWORD con_to_str (char *d, int dlen, WCHAR w); |
587b75f7 | 956 | DWORD str_to_con (mbtowc_p, const char *, PWCHAR d, const char *s, DWORD sz); |
098a4290 CF |
957 | void set_color (HANDLE); |
958 | bool fillin_info (HANDLE); | |
959 | void set_default_attr (); | |
abfc9c41 | 960 | |
3c66c070 CF |
961 | friend class fhandler_console; |
962 | }; | |
963 | ||
964 | /* This is a input and output console handle */ | |
965 | class fhandler_console: public fhandler_termios | |
966 | { | |
967 | private: | |
b65ec404 | 968 | static const unsigned MAX_WRITE_CHARS; |
3c66c070 | 969 | static dev_console *dev_state; |
65438ec6 | 970 | static bool invisible_console; |
1fd5e000 | 971 | |
4b65f190 CV |
972 | /* Used when we encounter a truncated multi-byte sequence. The |
973 | lead bytes are stored here and revisited in the next write call. */ | |
974 | struct { | |
975 | int len; | |
976 | unsigned char buf[4]; /* Max len of valid UTF-8 sequence. */ | |
977 | } trunc_buf; | |
949c0ec2 | 978 | PWCHAR write_buf; |
4b65f190 | 979 | |
1fd5e000 | 980 | /* Output calls */ |
a53136cc | 981 | void set_default_attr (); |
1fd5e000 | 982 | |
1fd5e000 CF |
983 | void clear_screen (int, int, int, int); |
984 | void scroll_screen (int, int, int, int, int, int); | |
2e008fb9 | 985 | void cursor_set (bool, int, int); |
1fd5e000 CF |
986 | void cursor_get (int *, int *); |
987 | void cursor_rel (int, int); | |
b65ec404 CF |
988 | inline void write_replacement_char (); |
989 | inline bool write_console (PWCHAR, DWORD, DWORD&); | |
7ac61736 | 990 | const unsigned char *write_normal (unsigned const char*, unsigned const char *); |
a53136cc | 991 | void char_command (char); |
2e008fb9 | 992 | bool set_raw_win32_keyboard_mode (bool); |
1fd5e000 CF |
993 | int output_tcsetattr (int a, const struct termios *t); |
994 | ||
995 | /* Input calls */ | |
996 | int igncr_enabled (); | |
997 | int input_tcsetattr (int a, const struct termios *t); | |
9eef1530 | 998 | void set_cursor_maybe (); |
01d8a2df CF |
999 | static bool create_invisible_console (HWINSTA); |
1000 | static bool create_invisible_console_workaround (); | |
1fd5e000 | 1001 | |
1229d4f4 | 1002 | public: |
0476bae5 | 1003 | fhandler_console (); |
1fd5e000 CF |
1004 | |
1005 | fhandler_console* is_console () { return this; } | |
1006 | ||
7ac61736 | 1007 | int open (int flags, mode_t mode = 0); |
1fd5e000 | 1008 | |
8bce0d72 | 1009 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
43c23d4b CF |
1010 | ssize_t __stdcall write (const void *ptr, size_t len); |
1011 | void doecho (const void *str, DWORD len) { (void) write (str, len); } | |
1fd5e000 CF |
1012 | int close (); |
1013 | ||
1014 | int tcflush (int); | |
1015 | int tcsetattr (int a, const struct termios *t); | |
1016 | int tcgetattr (struct termios *t); | |
1017 | ||
1fd5e000 | 1018 | /* Special dup as we must dup two handles */ |
dcb091ca | 1019 | int dup (fhandler_base *child); |
1fd5e000 CF |
1020 | |
1021 | int ioctl (unsigned int cmd, void *); | |
3c4f2024 | 1022 | int init (HANDLE, DWORD, mode_t); |
beeae482 CV |
1023 | bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event); |
1024 | bool focus_aware () {return dev_state->use_focus;} | |
1fd5e000 | 1025 | |
b4fa8164 CF |
1026 | select_record *select_read (select_stuff *); |
1027 | select_record *select_write (select_stuff *); | |
1028 | select_record *select_except (select_stuff *); | |
548d0080 CF |
1029 | void fixup_after_fork_exec (bool); |
1030 | void fixup_after_exec () {fixup_after_fork_exec (true);} | |
1031 | void fixup_after_fork (HANDLE) {fixup_after_fork_exec (false);} | |
56551a9b | 1032 | void set_close_on_exec (bool val); |
29ac7f89 | 1033 | void set_input_state (); |
c060edba | 1034 | void send_winch_maybe (); |
3c66c070 | 1035 | static tty_min *get_tty_stuff (int); |
43fb5c93 | 1036 | bool is_slow () {return true;} |
65438ec6 | 1037 | static bool need_invisible (); |
f62412f2 | 1038 | static bool has_a () {return !invisible_console;} |
1fd5e000 CF |
1039 | }; |
1040 | ||
1041 | class fhandler_tty_common: public fhandler_termios | |
1042 | { | |
1229d4f4 | 1043 | public: |
7ac61736 CF |
1044 | fhandler_tty_common () |
1045 | : fhandler_termios (), output_done_event (NULL), | |
e7e231e5 | 1046 | ioctl_request_event (NULL), ioctl_done_event (NULL), output_mutex (NULL), |
3378bdfc | 1047 | input_mutex (NULL), input_available_event (NULL) |
1fd5e000 CF |
1048 | { |
1049 | // nothing to do | |
1050 | } | |
1051 | HANDLE output_done_event; // Raised by master when tty's output buffer | |
1052 | // written. Write status in tty::write_retval. | |
1053 | HANDLE ioctl_request_event; // Raised by slave to perform ioctl() request. | |
1054 | // Ioctl() request in tty::cmd/arg. | |
1055 | HANDLE ioctl_done_event; // Raised by master on ioctl() completion. | |
1056 | // Ioctl() status in tty::ioctl_retval. | |
306c4b67 ED |
1057 | HANDLE output_mutex, input_mutex; |
1058 | HANDLE input_available_event; | |
1fd5e000 CF |
1059 | |
1060 | DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms); | |
1061 | void __release_output_mutex (const char *fn, int ln); | |
1062 | ||
1df3fbe2 | 1063 | tty *get_ttyp () { return (tty *) tc; } |
1fd5e000 CF |
1064 | |
1065 | int close (); | |
4f3e6ff1 | 1066 | _off64_t lseek (_off64_t, int); |
56551a9b | 1067 | void set_close_on_exec (bool val); |
b4fa8164 CF |
1068 | select_record *select_read (select_stuff *); |
1069 | select_record *select_write (select_stuff *); | |
1070 | select_record *select_except (select_stuff *); | |
43fb5c93 | 1071 | bool is_slow () {return true;} |
1fd5e000 CF |
1072 | }; |
1073 | ||
1074 | class fhandler_tty_slave: public fhandler_tty_common | |
1075 | { | |
3378bdfc | 1076 | HANDLE inuse; // used to indicate that a tty is in use |
1229d4f4 | 1077 | public: |
1fd5e000 | 1078 | /* Constructor */ |
0476bae5 | 1079 | fhandler_tty_slave (); |
1fd5e000 | 1080 | |
7ac61736 | 1081 | int open (int flags, mode_t mode = 0); |
43c23d4b | 1082 | ssize_t __stdcall write (const void *ptr, size_t len); |
8bce0d72 | 1083 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
3c4f2024 | 1084 | int init (HANDLE, DWORD, mode_t); |
1fd5e000 CF |
1085 | |
1086 | int tcsetattr (int a, const struct termios *t); | |
1087 | int tcgetattr (struct termios *t); | |
1088 | int tcflush (int); | |
1089 | int ioctl (unsigned int cmd, void *); | |
c418817e | 1090 | int close (); |
dcb091ca | 1091 | int dup (fhandler_base *child); |
c418817e | 1092 | void fixup_after_fork (HANDLE parent); |
3378bdfc | 1093 | void fixup_after_exec (); |
1fd5e000 | 1094 | |
b4fa8164 | 1095 | select_record *select_read (select_stuff *); |
f449bfef | 1096 | int cygserver_attach_tty (HANDLE*, HANDLE*); |
ce40c6ba | 1097 | int get_unit (); |
da915a3a | 1098 | virtual char const *ttyname () { return pc.dev.name; } |
1fd5e000 CF |
1099 | }; |
1100 | ||
1101 | class fhandler_pty_master: public fhandler_tty_common | |
1102 | { | |
1103 | int pktmode; // non-zero if pty in a packet mode. | |
7ac61736 | 1104 | public: |
3f0b4935 | 1105 | int need_nl; // Next read should start with \n |
3378bdfc | 1106 | DWORD dwProcessId; // Owner of master handles |
1fd5e000 CF |
1107 | |
1108 | /* Constructor */ | |
7ac61736 | 1109 | fhandler_pty_master (); |
1fd5e000 | 1110 | |
3f0b4935 | 1111 | int process_slave_output (char *buf, size_t len, int pktmode_on); |
1fd5e000 CF |
1112 | void doecho (const void *str, DWORD len); |
1113 | int accept_input (); | |
7ac61736 | 1114 | int open (int flags, mode_t mode = 0); |
43c23d4b | 1115 | ssize_t __stdcall write (const void *ptr, size_t len); |
8bce0d72 | 1116 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
1fd5e000 CF |
1117 | int close (); |
1118 | ||
1119 | int tcsetattr (int a, const struct termios *t); | |
1120 | int tcgetattr (struct termios *t); | |
1121 | int tcflush (int); | |
1122 | int ioctl (unsigned int cmd, void *); | |
1123 | ||
1fd5e000 CF |
1124 | char *ptsname (); |
1125 | ||
3378bdfc | 1126 | HANDLE from_master, to_master; |
35f879a6 | 1127 | bool hit_eof (); |
c76ca047 | 1128 | bool setup (bool); |
3378bdfc CF |
1129 | int dup (fhandler_base *); |
1130 | void fixup_after_fork (HANDLE parent); | |
1131 | void fixup_after_exec (); | |
b4311a90 | 1132 | int tcgetpgrp (); |
1fd5e000 CF |
1133 | }; |
1134 | ||
1135 | class fhandler_tty_master: public fhandler_pty_master | |
1136 | { | |
1229d4f4 | 1137 | public: |
1fd5e000 | 1138 | /* Constructor */ |
1fd5e000 | 1139 | fhandler_console *console; // device handler to perform real i/o. |
1fd5e000 | 1140 | |
7ac61736 CF |
1141 | fhandler_tty_master (); |
1142 | int init (); | |
1fd5e000 | 1143 | int init_console (); |
66dcfc44 | 1144 | void set_winsize (bool); |
43fb5c93 | 1145 | bool is_slow () {return true;} |
1fd5e000 CF |
1146 | }; |
1147 | ||
1148 | class fhandler_dev_null: public fhandler_base | |
1149 | { | |
1229d4f4 | 1150 | public: |
0476bae5 | 1151 | fhandler_dev_null (); |
1fd5e000 | 1152 | |
b4fa8164 CF |
1153 | select_record *select_read (select_stuff *); |
1154 | select_record *select_write (select_stuff *); | |
1155 | select_record *select_except (select_stuff *); | |
1fd5e000 CF |
1156 | }; |
1157 | ||
1158 | class fhandler_dev_zero: public fhandler_base | |
1159 | { | |
1229d4f4 | 1160 | public: |
0476bae5 | 1161 | fhandler_dev_zero (); |
7ac61736 | 1162 | int open (int flags, mode_t mode = 0); |
43c23d4b | 1163 | ssize_t __stdcall write (const void *ptr, size_t len); |
8bce0d72 | 1164 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
1727fba0 | 1165 | _off64_t lseek (_off64_t offset, int whence); |
a020c74a CV |
1166 | |
1167 | virtual HANDLE mmap (caddr_t *addr, size_t len, int prot, | |
1168 | int flags, _off64_t off); | |
1169 | virtual int munmap (HANDLE h, caddr_t addr, size_t len); | |
1170 | virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags); | |
1171 | virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags, | |
1172 | _off64_t offset, DWORD size, | |
1173 | void *address); | |
1fd5e000 CF |
1174 | }; |
1175 | ||
1c0c369b CV |
1176 | class fhandler_dev_random: public fhandler_base |
1177 | { | |
1229d4f4 | 1178 | protected: |
1c0c369b | 1179 | HCRYPTPROV crypt_prov; |
9602ffc3 | 1180 | long pseudo; |
04cb518d | 1181 | _off64_t dummy_offset; |
9602ffc3 | 1182 | |
2e008fb9 | 1183 | bool crypt_gen_random (void *ptr, size_t len); |
9602ffc3 CV |
1184 | int pseudo_write (const void *ptr, size_t len); |
1185 | int pseudo_read (void *ptr, size_t len); | |
bb7f93f8 | 1186 | |
1229d4f4 | 1187 | public: |
7ac61736 CF |
1188 | fhandler_dev_random (); |
1189 | int open (int flags, mode_t mode = 0); | |
43c23d4b | 1190 | ssize_t __stdcall write (const void *ptr, size_t len); |
8bce0d72 | 1191 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
1727fba0 | 1192 | _off64_t lseek (_off64_t offset, int whence); |
2f9ae2ed | 1193 | int close (); |
dcb091ca | 1194 | int dup (fhandler_base *child); |
1c0c369b CV |
1195 | }; |
1196 | ||
51c22a5c CV |
1197 | class fhandler_dev_mem: public fhandler_base |
1198 | { | |
1229d4f4 | 1199 | protected: |
4ea34a68 | 1200 | DWORD mem_size; |
1727fba0 | 1201 | _off64_t pos; |
51c22a5c | 1202 | |
1229d4f4 | 1203 | public: |
7ac61736 | 1204 | fhandler_dev_mem (); |
2f9ae2ed | 1205 | ~fhandler_dev_mem (); |
51c22a5c | 1206 | |
7ac61736 | 1207 | int open (int flags, mode_t mode = 0); |
43c23d4b | 1208 | ssize_t __stdcall write (const void *ptr, size_t ulen); |
8bce0d72 | 1209 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
1727fba0 | 1210 | _off64_t lseek (_off64_t offset, int whence); |
7ac61736 | 1211 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); |
dcb091ca | 1212 | int dup (fhandler_base *child); |
51c22a5c | 1213 | |
f90e23f2 | 1214 | HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off); |
4ea34a68 CV |
1215 | int munmap (HANDLE h, caddr_t addr, size_t len); |
1216 | int msync (HANDLE h, caddr_t addr, size_t len, int flags); | |
f90e23f2 | 1217 | bool fixup_mmap_after_fork (HANDLE h, int prot, int flags, |
6d11044c | 1218 | _off64_t offset, DWORD size, void *address); |
e6f5c9d5 | 1219 | } ; |
75a57bf0 | 1220 | |
e6f5c9d5 DD |
1221 | class fhandler_dev_clipboard: public fhandler_base |
1222 | { | |
2f9ae2ed CF |
1223 | _off64_t pos; |
1224 | void *membuffer; | |
1225 | size_t msize; | |
1226 | bool eof; | |
1229d4f4 | 1227 | public: |
0476bae5 | 1228 | fhandler_dev_clipboard (); |
2f9ae2ed | 1229 | int is_windows () { return 1; } |
7ac61736 | 1230 | int open (int flags, mode_t mode = 0); |
43c23d4b | 1231 | ssize_t __stdcall write (const void *ptr, size_t len); |
8bce0d72 | 1232 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
1727fba0 | 1233 | _off64_t lseek (_off64_t offset, int whence); |
2f9ae2ed | 1234 | int close (); |
e6f5c9d5 | 1235 | |
dcb091ca | 1236 | int dup (fhandler_base *child); |
2f9ae2ed | 1237 | void fixup_after_exec (); |
51c22a5c CV |
1238 | }; |
1239 | ||
1fd5e000 CF |
1240 | class fhandler_windows: public fhandler_base |
1241 | { | |
1229d4f4 | 1242 | private: |
1fd5e000 CF |
1243 | HWND hWnd_; // the window whose messages are to be retrieved by read() call |
1244 | int method_; // write method (Post or Send) | |
1229d4f4 | 1245 | public: |
0476bae5 | 1246 | fhandler_windows (); |
2f9ae2ed | 1247 | int is_windows () { return 1; } |
7ac61736 | 1248 | int open (int flags, mode_t mode = 0); |
43c23d4b | 1249 | ssize_t __stdcall write (const void *ptr, size_t len); |
8bce0d72 | 1250 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
1fd5e000 | 1251 | int ioctl (unsigned int cmd, void *); |
1727fba0 | 1252 | _off64_t lseek (_off64_t, int) { return 0; } |
2f9ae2ed | 1253 | int close () { return 0; } |
1fd5e000 | 1254 | |
56551a9b | 1255 | void set_close_on_exec (bool val); |
1fd5e000 | 1256 | void fixup_after_fork (HANDLE parent); |
b4fa8164 CF |
1257 | select_record *select_read (select_stuff *); |
1258 | select_record *select_write (select_stuff *); | |
1259 | select_record *select_except (select_stuff *); | |
43fb5c93 | 1260 | bool is_slow () {return true;} |
1fd5e000 CF |
1261 | }; |
1262 | ||
6653af6c | 1263 | class fhandler_dev_dsp: public fhandler_base |
b0a50cf3 | 1264 | { |
6653af6c CV |
1265 | public: |
1266 | class Audio; | |
1267 | class Audio_out; | |
1268 | class Audio_in; | |
1229d4f4 | 1269 | private: |
b0a50cf3 CF |
1270 | int audioformat_; |
1271 | int audiofreq_; | |
1272 | int audiobits_; | |
1273 | int audiochannels_; | |
6653af6c CV |
1274 | Audio_out *audio_out_; |
1275 | Audio_in *audio_in_; | |
1229d4f4 | 1276 | public: |
0476bae5 | 1277 | fhandler_dev_dsp (); |
b0a50cf3 | 1278 | |
7ac61736 | 1279 | int open (int flags, mode_t mode = 0); |
43c23d4b | 1280 | ssize_t __stdcall write (const void *ptr, size_t len); |
8bce0d72 | 1281 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
b0a50cf3 | 1282 | int ioctl (unsigned int cmd, void *); |
1727fba0 | 1283 | _off64_t lseek (_off64_t, int); |
2f9ae2ed | 1284 | int close (); |
dcb091ca | 1285 | int dup (fhandler_base *child); |
6653af6c | 1286 | void fixup_after_fork (HANDLE parent); |
52806019 | 1287 | void fixup_after_exec (); |
8f663bd6 CV |
1288 | private: |
1289 | void close_audio_in (); | |
1290 | void close_audio_out (bool immediately = false); | |
b0a50cf3 CF |
1291 | }; |
1292 | ||
291be307 CF |
1293 | class fhandler_virtual : public fhandler_base |
1294 | { | |
1295 | protected: | |
1296 | char *filebuf; | |
1727fba0 CV |
1297 | _off64_t filesize; |
1298 | _off64_t position; | |
9ba913a5 | 1299 | int fileid; // unique within each class |
291be307 CF |
1300 | public: |
1301 | ||
7ac61736 | 1302 | fhandler_virtual (); |
291be307 CF |
1303 | virtual ~fhandler_virtual(); |
1304 | ||
fc240f58 | 1305 | virtual int exists(); |
40570a82 | 1306 | DIR *opendir (int fd) __attribute__ ((regparm (2))); |
1727fba0 CV |
1307 | _off64_t telldir (DIR *); |
1308 | void seekdir (DIR *, _off64_t); | |
291be307 CF |
1309 | void rewinddir (DIR *); |
1310 | int closedir (DIR *); | |
43c23d4b | 1311 | ssize_t __stdcall write (const void *ptr, size_t len); |
8bce0d72 | 1312 | void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); |
1727fba0 | 1313 | _off64_t lseek (_off64_t, int); |
dcb091ca | 1314 | int dup (fhandler_base *child); |
7ac61736 | 1315 | int open (int flags, mode_t mode = 0); |
2f9ae2ed | 1316 | int close (); |
7ac61736 | 1317 | int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2))); |
3323df7e | 1318 | int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); |
854c8700 | 1319 | int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1))); |
ddf9c4a7 | 1320 | int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2))); |
e3d1d515 | 1321 | int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3))); |
74fcdaec | 1322 | virtual bool fill_filebuf (); |
faf07ace | 1323 | char *get_filebuf () { return filebuf; } |
52806019 | 1324 | void fixup_after_exec (); |
291be307 CF |
1325 | }; |
1326 | ||
1327 | class fhandler_proc: public fhandler_virtual | |
1328 | { | |
1329 | public: | |
1330 | fhandler_proc (); | |
fc240f58 | 1331 | int exists(); |
d9a22764 | 1332 | int readdir (DIR *, dirent *) __attribute__ ((regparm (3))); |
291be307 CF |
1333 | static DWORD get_proc_fhandler(const char *path); |
1334 | ||
7ac61736 CF |
1335 | int open (int flags, mode_t mode = 0); |
1336 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); | |
74fcdaec | 1337 | bool fill_filebuf (); |
291be307 CF |
1338 | }; |
1339 | ||
adef8db0 PH |
1340 | class fhandler_netdrive: public fhandler_virtual |
1341 | { | |
1342 | public: | |
1343 | fhandler_netdrive (); | |
1344 | int exists(); | |
d9a22764 | 1345 | int readdir (DIR *, dirent *) __attribute__ ((regparm (3))); |
e01eac68 | 1346 | void seekdir (DIR *, _off64_t); |
5b59a2cc | 1347 | void rewinddir (DIR *); |
e01eac68 | 1348 | int closedir (DIR *); |
adef8db0 PH |
1349 | int open (int flags, mode_t mode = 0); |
1350 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); | |
1351 | }; | |
1352 | ||
291be307 CF |
1353 | class fhandler_registry: public fhandler_proc |
1354 | { | |
74fcdaec | 1355 | private: |
333a47d3 | 1356 | wchar_t *value_name; |
20f9af53 CV |
1357 | DWORD wow64; |
1358 | int prefix_len; | |
291be307 CF |
1359 | public: |
1360 | fhandler_registry (); | |
20f9af53 | 1361 | void set_name (path_conv &pc); |
fc240f58 | 1362 | int exists(); |
d9a22764 | 1363 | int readdir (DIR *, dirent *) __attribute__ ((regparm (3))); |
1727fba0 CV |
1364 | _off64_t telldir (DIR *); |
1365 | void seekdir (DIR *, _off64_t); | |
291be307 CF |
1366 | void rewinddir (DIR *); |
1367 | int closedir (DIR *); | |
1368 | ||
7ac61736 CF |
1369 | int open (int flags, mode_t mode = 0); |
1370 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); | |
74fcdaec | 1371 | bool fill_filebuf (); |
2f9ae2ed | 1372 | int close (); |
305b19d7 | 1373 | int dup (fhandler_base *child); |
291be307 CF |
1374 | }; |
1375 | ||
fdf0b5de | 1376 | class pinfo; |
291be307 CF |
1377 | class fhandler_process: public fhandler_proc |
1378 | { | |
fdf0b5de | 1379 | pid_t pid; |
291be307 CF |
1380 | public: |
1381 | fhandler_process (); | |
fc240f58 | 1382 | int exists(); |
40570a82 | 1383 | DIR *opendir (int fd) __attribute__ ((regparm (2))); |
d9a22764 | 1384 | int readdir (DIR *, dirent *) __attribute__ ((regparm (3))); |
7ac61736 CF |
1385 | int open (int flags, mode_t mode = 0); |
1386 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); | |
74fcdaec | 1387 | bool fill_filebuf (); |
291be307 CF |
1388 | }; |
1389 | ||
96d7dee2 CV |
1390 | class fhandler_procnet: public fhandler_proc |
1391 | { | |
1392 | pid_t pid; | |
1393 | public: | |
1394 | fhandler_procnet (); | |
1395 | int exists(); | |
96d7dee2 CV |
1396 | int readdir (DIR *, dirent *) __attribute__ ((regparm (3))); |
1397 | int open (int flags, mode_t mode = 0); | |
1398 | int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); | |
1399 | bool fill_filebuf (); | |
1400 | }; | |
1401 | ||
7ac61736 CF |
1402 | struct fhandler_nodevice: public fhandler_base |
1403 | { | |
1404 | fhandler_nodevice (); | |
1405 | int open (int flags, mode_t mode = 0); | |
1406 | // int __stdcall fstat (struct __stat64 *buf, path_conv *); | |
1407 | }; | |
1408 | ||
59297e04 CF |
1409 | #define report_tty_counts(fh, call, use_op) \ |
1410 | termios_printf ("%s %s, %susecount %d",\ | |
e9737793 | 1411 | fh->ttyname (), call,\ |
e9737793 CF |
1412 | use_op, ((fhandler_tty_slave *) fh)->archetype->usecount); |
1413 | ||
1fd5e000 CF |
1414 | typedef union |
1415 | { | |
7da53596 CF |
1416 | char __base[sizeof (fhandler_base)]; |
1417 | char __console[sizeof (fhandler_console)]; | |
1418 | char __cygdrive[sizeof (fhandler_cygdrive)]; | |
1419 | char __dev_clipboard[sizeof (fhandler_dev_clipboard)]; | |
1420 | char __dev_dsp[sizeof (fhandler_dev_dsp)]; | |
1421 | char __dev_floppy[sizeof (fhandler_dev_floppy)]; | |
1422 | char __dev_mem[sizeof (fhandler_dev_mem)]; | |
1423 | char __dev_null[sizeof (fhandler_dev_null)]; | |
1424 | char __dev_random[sizeof (fhandler_dev_random)]; | |
1425 | char __dev_raw[sizeof (fhandler_dev_raw)]; | |
1426 | char __dev_tape[sizeof (fhandler_dev_tape)]; | |
1427 | char __dev_zero[sizeof (fhandler_dev_zero)]; | |
1428 | char __disk_file[sizeof (fhandler_disk_file)]; | |
29b111ce | 1429 | char __fifo[sizeof (fhandler_fifo)]; |
13505ca8 | 1430 | char __mailslot[sizeof (fhandler_mailslot)]; |
29b111ce CV |
1431 | char __netdrive[sizeof (fhandler_netdrive)]; |
1432 | char __nodevice[sizeof (fhandler_nodevice)]; | |
7da53596 CF |
1433 | char __pipe[sizeof (fhandler_pipe)]; |
1434 | char __proc[sizeof (fhandler_proc)]; | |
1435 | char __process[sizeof (fhandler_process)]; | |
1436 | char __pty_master[sizeof (fhandler_pty_master)]; | |
1437 | char __registry[sizeof (fhandler_registry)]; | |
1438 | char __serial[sizeof (fhandler_serial)]; | |
1439 | char __socket[sizeof (fhandler_socket)]; | |
1440 | char __termios[sizeof (fhandler_termios)]; | |
1441 | char __tty_common[sizeof (fhandler_tty_common)]; | |
1442 | char __tty_master[sizeof (fhandler_tty_master)]; | |
1443 | char __tty_slave[sizeof (fhandler_tty_slave)]; | |
1444 | char __virtual[sizeof (fhandler_virtual)]; | |
1445 | char __windows[sizeof (fhandler_windows)]; | |
1fd5e000 | 1446 | } fhandler_union; |
1fd5e000 | 1447 | #endif /* _FHANDLER_H_ */ |