OSDN Git Service

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