OSDN Git Service

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