OSDN Git Service

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