OSDN Git Service

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