OSDN Git Service

0a73af82f65ef5c14bf394ffb052a199c4e13496
[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, 2010, 2011 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 #include "tty.h"
16 /* fcntl flags used only internaly. */
17 #define O_NOSYMLINK 0x080000
18 #define O_DIROPEN   0x100000
19
20 /* newlib used to define O_NDELAY differently from O_NONBLOCK.  Now it
21    properly defines both to be the same.  Unfortunately, we have to
22    behave properly the old version, too, to accommodate older executables. */
23 #define OLD_O_NDELAY    (CYGWIN_VERSION_CHECK_FOR_OLD_O_NONBLOCK ? 4 : 0)
24
25 /* Care for the old O_NDELAY flag. If one of the flags is set,
26    both flags are set. */
27 #define O_NONBLOCK_MASK (O_NONBLOCK | OLD_O_NDELAY)
28
29 /* It appears that 64K is the block size used for buffered I/O on NT.
30    Using this blocksize in read/write calls in the application results
31    in a much better performance than using smaller values. */
32 #define PREFERRED_IO_BLKSIZE ((blksize_t) 65536)
33
34 /* It also appears that this may be the only acceptable block size for
35    atomic writes to a pipe.  It is a shame that we have to make this
36    so small.  http://cygwin.com/ml/cygwin/2011-03/msg00541.html  */
37 #define DEFAULT_PIPEBUFSIZE PREFERRED_IO_BLKSIZE
38
39 extern const char *windows_device_names[];
40 extern struct __cygwin_perfile *perfile_table;
41 #define __fmode (*(user_data->fmode_ptr))
42 extern const char proc[];
43 extern const size_t proc_len;
44 extern const char procsys[];
45 extern const size_t procsys_len;
46
47 class select_record;
48 class select_stuff;
49 class fhandler_disk_file;
50 class inode_t;
51 typedef struct __DIR DIR;
52 struct dirent;
53 struct iovec;
54 struct __acl32;
55
56 enum dirent_states
57 {
58   dirent_ok             = 0x0000,
59   dirent_saw_dot        = 0x0001,
60   dirent_saw_dot_dot    = 0x0002,
61   dirent_saw_eof        = 0x0004,
62   dirent_isroot         = 0x0008,
63   dirent_set_d_ino      = 0x0010,
64   dirent_get_d_ino      = 0x0020,
65   dirent_nfs_d_ino      = 0x0040,
66
67   /* Global flags which must not be deleted on rewinddir or seekdir. */
68   dirent_info_mask      = 0x0078
69 };
70
71 enum conn_state
72 {
73   unconnected = 0,
74   connect_pending = 1,
75   connected = 2,
76   connect_failed = 3
77 };
78
79 enum line_edit_status
80 {
81   line_edit_ok = 0,
82   line_edit_input_done = 1,
83   line_edit_signalled = 2,
84   line_edit_error = 3,
85   line_edit_pipe_full = 4
86 };
87
88 enum bg_check_types
89 {
90   bg_error = -1,
91   bg_eof = 0,
92   bg_ok = 1,
93   bg_signalled = 2
94 };
95
96 enum query_state {
97   no_query = 0,
98   query_read_control = 1,
99   query_read_attributes = 2,
100   query_write_control = 3,
101   query_write_dac = 4,
102   query_write_attributes = 5
103 };
104
105 enum del_lock_called_from {
106   on_close,
107   after_fork,
108   after_exec
109 };
110
111 enum virtual_ftype_t {
112   virt_blk = -7,        /* Block special */
113   virt_chr = -6,        /* Character special */
114   virt_fsfile = -5,     /* FS-based file via /proc/sys */
115   virt_socket = -4,     /* Socket */
116   virt_pipe = -3,       /* Pipe */
117   virt_symlink = -2,    /* Symlink */
118   virt_file = -1,       /* Regular file */
119   virt_none = 0,        /* Invalid, Error */
120   virt_directory = 1,   /* Directory */
121   virt_rootdir = 2,     /* Root directory of virtual FS */
122   virt_fsdir = 3,       /* FS-based directory via /proc/sys */
123 };
124
125 class fhandler_base
126 {
127   friend class dtable;
128   friend void close_all_files (bool);
129
130   struct status_flags
131   {
132     unsigned rbinary            : 1; /* binary read mode */
133     unsigned rbinset            : 1; /* binary read mode explicitly set */
134     unsigned wbinary            : 1; /* binary write mode */
135     unsigned wbinset            : 1; /* binary write mode explicitly set */
136     unsigned nohandle           : 1; /* No handle associated with fhandler. */
137     unsigned did_lseek          : 1; /* set when lseek is called as a flag that
138                                         _write should check if we've moved
139                                         beyond EOF, zero filling or making
140                                         file sparse if so. */
141     unsigned query_open         : 3; /* open file without requesting either
142                                         read or write access */
143     unsigned close_on_exec      : 1; /* close-on-exec */
144     unsigned need_fork_fixup    : 1; /* Set if need to fixup after fork. */
145     unsigned isclosed           : 1; /* Set when fhandler is closed. */
146
147    public:
148     status_flags () :
149       rbinary (0), rbinset (0), wbinary (0), wbinset (0), nohandle (0),
150       did_lseek (0), query_open (no_query), close_on_exec (0),
151       need_fork_fixup (0), isclosed (0)
152       {}
153   } status, open_status;
154
155  private:
156   ACCESS_MASK access;
157   ULONG options;
158
159   HANDLE io_handle;
160
161   __ino64_t ino;        /* file ID or hashed filename, depends on FS. */
162   long _refcnt;
163
164  protected:
165   /* File open flags from open () and fcntl () calls */
166   int openflags;
167
168   char *rabuf;          /* used for crlf conversion in text files */
169   size_t ralen;
170   size_t raixget;
171   size_t raixput;
172   size_t rabuflen;
173
174   /* Used for advisory file locking.  See flock.cc.  */
175   long long unique_id;
176   void del_my_locks (del_lock_called_from);
177
178   HANDLE read_state;
179
180  public:
181   long refcnt(long i = 0) {return _refcnt += i;}
182   class fhandler_base *archetype;
183   int usecount;
184
185   path_conv pc;
186
187   void reset (const fhandler_base *);
188   virtual bool use_archetype () const {return false;}
189   virtual void set_name (path_conv &pc);
190   virtual void set_name (const char *s)
191   {
192     pc.set_normalized_path (s);
193     pc.set_path (s);
194   }
195   int error () const {return pc.error;}
196   void set_error (int error) {pc.error = error;}
197   bool exists () const {return pc.exists ();}
198   int pc_binmode () const {return pc.binmode ();}
199   device& dev () {return pc.dev;}
200   operator DWORD& () {return (DWORD&) pc;}
201   fhandler_base ();
202   virtual ~fhandler_base ();
203
204   /* Non-virtual simple accessor functions. */
205   void set_io_handle (HANDLE x) { io_handle = x; }
206
207   DWORD& get_device () { return dev (); }
208   DWORD get_major () { return dev ().get_major (); }
209   DWORD get_minor () { return dev ().get_minor (); }
210   virtual int get_unit () { return dev ().get_minor (); }
211
212   ACCESS_MASK get_access () const { return access; }
213   void set_access (ACCESS_MASK x) { access = x; }
214
215   ULONG get_options () const { return options; }
216   void set_options (ULONG x) { options = x; }
217
218   int get_flags () { return openflags; }
219   void set_flags (int x, int supplied_bin = 0);
220
221   bool is_nonblocking ();
222   void set_nonblocking (int);
223
224   bool wbinary () const { return status.wbinset ? status.wbinary : 1; }
225   bool rbinary () const { return status.rbinset ? status.rbinary : 1; }
226
227   void wbinary (bool b) {status.wbinary = b; status.wbinset = 1;}
228   void rbinary (bool b) {status.rbinary = b; status.rbinset = 1;}
229
230   void set_open_status () {open_status = status;}
231   void reset_to_open_binmode ()
232   {
233     set_flags ((get_flags () & ~(O_TEXT | O_BINARY))
234                | ((open_status.wbinary || open_status.rbinary)
235                    ? O_BINARY : O_TEXT));
236   }
237
238   IMPLEMENT_STATUS_FLAG (bool, wbinset)
239   IMPLEMENT_STATUS_FLAG (bool, rbinset)
240   IMPLEMENT_STATUS_FLAG (bool, nohandle)
241   IMPLEMENT_STATUS_FLAG (bool, did_lseek)
242   IMPLEMENT_STATUS_FLAG (query_state, query_open)
243   IMPLEMENT_STATUS_FLAG (bool, close_on_exec)
244   IMPLEMENT_STATUS_FLAG (bool, need_fork_fixup)
245   IMPLEMENT_STATUS_FLAG (bool, isclosed)
246
247   int get_default_fmode (int flags);
248
249   virtual void set_close_on_exec (bool val);
250
251   LPSECURITY_ATTRIBUTES get_inheritance (bool all = 0)
252   {
253     if (all)
254       return close_on_exec () ? &sec_all_nih : &sec_all;
255     else
256       return close_on_exec () ? &sec_none_nih : &sec_none;
257   }
258
259   virtual int fixup_before_fork_exec (DWORD) { return 0; }
260   virtual void fixup_after_fork (HANDLE);
261   virtual void fixup_after_exec ();
262   void create_read_state (LONG n)
263   {
264     read_state = CreateSemaphore (&sec_none_nih, 0, n, NULL);
265     ProtectHandle (read_state);
266   }
267
268   void signal_read_state (LONG n)
269   {
270     ReleaseSemaphore (read_state, n, NULL);
271   }
272
273   bool get_readahead_valid () { return raixget < ralen; }
274   int puts_readahead (const char *s, size_t len = (size_t) -1);
275   int put_readahead (char value);
276
277   int get_readahead ();
278   int peek_readahead (int queryput = 0);
279
280   int eat_readahead (int n);
281
282   void set_readahead_valid (int val, int ch = -1);
283
284   int get_readahead_into_buffer (char *buf, size_t buflen);
285
286   bool has_acls () const { return pc.has_acls (); }
287
288   bool isremote () { return pc.isremote (); }
289
290   bool has_attribute (DWORD x) const {return pc.has_attribute (x);}
291   const char *get_name () const { return pc.normalized_path; }
292   const char *get_win32_name () { return pc.get_win32 (); }
293   __dev32_t get_dev () { return pc.fs_serial_number (); }
294   __ino64_t get_ino () { return ino ?: ino = hash_path_name (0, pc.get_nt_native_path ()); }
295   long long get_unique_id () const { return unique_id; }
296   /* Returns name used for /proc/<pid>/fd in buf. */
297   virtual char *get_proc_fd_name (char *buf);
298
299   virtual void hclose (HANDLE h) {CloseHandle (h);}
300   virtual void set_no_inheritance (HANDLE &, bool);
301
302   /* fixup fd possibly non-inherited handles after fork */
303   bool fork_fixup (HANDLE, HANDLE &, const char *);
304   virtual bool need_fixup_before () const {return false;}
305
306   int open_with_arch (int, mode_t = 0);
307   virtual int open (int, mode_t);
308   virtual void open_setup (int flags) { return; }
309
310   int close_with_arch ();
311   virtual int close ();
312   virtual void cleanup () { return; }
313   int _archetype_usecount (const char *fn, int ln, int n)
314   {
315     if (!archetype)
316       return 0;
317     archetype->usecount += n;
318     if (strace.active ())
319       strace.prntf (_STRACE_ALL, fn, "line %d:  %s<%p> usecount + %d = %d", ln, get_name (), archetype, n, archetype->usecount);
320     return archetype->usecount;
321   }
322
323   int open_fs (int, mode_t = 0);
324 # define archetype_usecount(n) _archetype_usecount (__PRETTY_FUNCTION__, __LINE__, (n))
325   int close_fs () { return fhandler_base::close (); }
326   virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
327   int __stdcall fstat_fs (struct __stat64 *buf) __attribute__ ((regparm (2)));
328 private:
329   int __stdcall fstat_helper (struct __stat64 *buf,
330                               DWORD nNumberOfLinks)
331                 __attribute__ ((regparm (3)));
332   int __stdcall fstat_by_nfs_ea (struct __stat64 *buf) __attribute__ ((regparm (2)));
333   int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
334   int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
335 public:
336   virtual int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
337   int utimens_fs (const struct timespec *) __attribute__ ((regparm (2)));
338   virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
339   virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
340   virtual int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
341   virtual ssize_t __stdcall fgetxattr (const char *, void *, size_t) __attribute__ ((regparm (3)));
342   virtual int __stdcall fsetxattr (const char *, const void *, size_t, int) __attribute__ ((regparm (3)));
343   virtual int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
344   virtual int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
345   virtual int __stdcall link (const char *) __attribute__ ((regparm (2)));
346   virtual int __stdcall utimens (const struct timespec *) __attribute__ ((regparm (2)));
347   virtual int __stdcall fsync () __attribute__ ((regparm (1)));
348   virtual int ioctl (unsigned int cmd, void *);
349   virtual int fcntl (int cmd, void *);
350   virtual char const *ttyname () { return get_name (); }
351   virtual void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
352   virtual ssize_t __stdcall write (const void *ptr, size_t len);
353   virtual ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
354   virtual ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
355   virtual ssize_t __stdcall pread (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
356   virtual ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
357   virtual _off64_t lseek (_off64_t offset, int whence);
358   virtual int lock (int, struct __flock64 *);
359   virtual int dup (fhandler_base *child, int flags);
360   virtual int fpathconf (int);
361
362   virtual HANDLE mmap (caddr_t *addr, size_t len, int prot,
363                        int flags, _off64_t off);
364   virtual int munmap (HANDLE h, caddr_t addr, size_t len);
365   virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
366   virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
367                                       _off64_t offset, DWORD size,
368                                       void *address);
369
370   void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;}
371
372   virtual int init (HANDLE, DWORD, mode_t);
373
374   virtual int tcflush (int);
375   virtual int tcsendbreak (int);
376   virtual int tcdrain ();
377   virtual int tcflow (int);
378   virtual int tcsetattr (int a, const struct termios *t);
379   virtual int tcgetattr (struct termios *t);
380   virtual int tcsetpgrp (const pid_t pid);
381   virtual int tcgetpgrp ();
382   virtual int tcgetsid ();
383   virtual bool is_tty () const { return false; }
384   virtual bool ispipe () const { return false; }
385   virtual pid_t get_popen_pid () const {return 0;}
386   virtual bool isdevice () const { return true; }
387   virtual bool isfifo () const { return false; }
388   virtual int ptsname_r (char *, size_t);
389   virtual class fhandler_socket *is_socket () { return NULL; }
390   virtual class fhandler_console *is_console () { return 0; }
391   virtual int is_windows () {return 0; }
392
393   virtual void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3)));
394   virtual ssize_t __stdcall raw_write (const void *ptr, size_t ulen) __attribute__ ((regparm (3)));
395
396   /* Virtual accessor functions to hide the fact
397      that some fd's have two handles. */
398   virtual HANDLE& get_handle () { return io_handle; }
399   virtual HANDLE& get_io_handle () { return io_handle; }
400   virtual HANDLE& get_output_handle () { return io_handle; }
401   virtual HANDLE get_stat_handle () { return pc.handle () ?: io_handle; }
402   virtual bool hit_eof () {return false;}
403   virtual select_record *select_read (select_stuff *);
404   virtual select_record *select_write (select_stuff *);
405   virtual select_record *select_except (select_stuff *);
406   virtual const char *get_native_name ()
407   {
408     return dev ().native;
409   }
410   virtual bg_check_types bg_check (int) {return bg_ok;}
411   void clear_readahead ()
412   {
413     raixput = raixget = ralen = rabuflen = 0;
414     rabuf = NULL;
415   }
416   void operator delete (void *p) {cfree (p);}
417   virtual void set_eof () {}
418   virtual int mkdir (mode_t mode);
419   virtual int rmdir ();
420   virtual DIR *opendir (int fd) __attribute__ ((regparm (2)));
421   virtual int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
422   virtual long telldir (DIR *);
423   virtual void seekdir (DIR *, long);
424   virtual void rewinddir (DIR *);
425   virtual int closedir (DIR *);
426   bool is_auto_device () {return isdevice () && !dev ().isfs ();}
427   bool is_fs_special () {return pc.is_fs_special ();}
428   bool issymlink () {return pc.issymlink ();}
429   bool device_access_denied (int) __attribute__ ((regparm (2)));
430   int fhaccess (int flags, bool) __attribute__ ((regparm (3)));
431   virtual bool __stdcall has_ongoing_io () __attribute__ ((regparm (1))) {return false;}
432
433   fhandler_base (void *) {}
434
435   virtual void copyto (fhandler_base *x)
436   {
437     x->pc.free_strings ();
438     *reinterpret_cast<fhandler_base *> (x) = *this;
439     x->reset (this);
440   }
441
442   virtual fhandler_base *clone (cygheap_types malloc_type = HEAP_FHANDLER)
443   {
444     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_base));
445     fhandler_base *fh = new (ptr) fhandler_base (ptr);
446     copyto (fh);
447     return fh;
448   }
449 };
450
451 struct wsa_event
452 {
453   LONG serial_number;
454   long events;
455   int  connect_errorcode;
456   pid_t owner;
457 };
458
459 class fhandler_socket: public fhandler_base
460 {
461  private:
462   int addr_family;
463   int type;
464   int connect_secret[4];
465
466   wsa_event *wsock_events;
467   HANDLE wsock_mtx;
468   HANDLE wsock_evt;
469  public:
470   bool init_events ();
471   int evaluate_events (const long event_mask, long &events, const bool erase);
472   const HANDLE wsock_event () const { return wsock_evt; }
473   const LONG serial_number () const { return wsock_events->serial_number; }
474  private:
475   int wait_for_events (const long event_mask, const DWORD flags);
476   void release_events ();
477
478   pid_t     sec_pid;
479   __uid32_t sec_uid;
480   __gid32_t sec_gid;
481   pid_t     sec_peer_pid;
482   __uid32_t sec_peer_uid;
483   __gid32_t sec_peer_gid;
484   void af_local_set_secret (char *);
485   void af_local_setblocking (bool &, bool &);
486   void af_local_unsetblocking (bool, bool);
487   void af_local_set_cred ();
488   void af_local_copy (fhandler_socket *);
489   bool af_local_recv_secret ();
490   bool af_local_send_secret ();
491   bool af_local_recv_cred ();
492   bool af_local_send_cred ();
493   int af_local_accept ();
494  public:
495   int af_local_connect ();
496   void af_local_set_sockpair_cred ();
497
498  private:
499   int       _rmem;
500   int       _wmem;
501  public:
502   int &rmem () { return _rmem; }
503   int &wmem () { return _wmem; }
504   void rmem (int nrmem) { _rmem = nrmem; }
505   void wmem (int nwmem) { _wmem = nwmem; }
506
507  private:
508   struct _WSAPROTOCOL_INFOW *prot_info_ptr;
509  public:
510   void init_fixup_before ();
511   bool need_fixup_before () const {return prot_info_ptr != NULL;}
512
513  private:
514   char *sun_path;
515   char *peer_sun_path;
516   struct status_flags
517   {
518     unsigned async_io              : 1; /* async I/O */
519     unsigned saw_shutdown_read     : 1; /* Socket saw a SHUT_RD */
520     unsigned saw_shutdown_write    : 1; /* Socket saw a SHUT_WR */
521     unsigned saw_reuseaddr         : 1; /* Socket saw SO_REUSEADDR call */
522     unsigned listener              : 1; /* listen called */
523     unsigned connect_state         : 2;
524    public:
525     status_flags () :
526       async_io (0), saw_shutdown_read (0), saw_shutdown_write (0),
527       listener (0), connect_state (unconnected)
528       {}
529   } status;
530
531  public:
532   fhandler_socket ();
533   ~fhandler_socket ();
534   int get_socket () { return (int) get_handle(); }
535   fhandler_socket *is_socket () { return this; }
536
537   IMPLEMENT_STATUS_FLAG (bool, async_io)
538   IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_read)
539   IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write)
540   IMPLEMENT_STATUS_FLAG (bool, saw_reuseaddr)
541   IMPLEMENT_STATUS_FLAG (bool, listener)
542   IMPLEMENT_STATUS_FLAG (conn_state, connect_state)
543
544   int bind (const struct sockaddr *name, int namelen);
545   int connect (const struct sockaddr *name, int namelen);
546   int listen (int backlog);
547   int accept4 (struct sockaddr *peer, int *len, int flags);
548   int getsockname (struct sockaddr *name, int *namelen);
549   int getpeername (struct sockaddr *name, int *namelen);
550   int getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid);
551
552   int open (int flags, mode_t mode = 0);
553   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
554   ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
555   inline ssize_t recv_internal (struct _WSAMSG *wsamsg);
556   ssize_t recvfrom (void *ptr, size_t len, int flags,
557                     struct sockaddr *from, int *fromlen);
558   ssize_t recvmsg (struct msghdr *msg, int flags);
559
560   ssize_t __stdcall write (const void *ptr, size_t len);
561   ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
562   inline ssize_t send_internal (struct _WSAMSG *wsamsg, int flags);
563   ssize_t sendto (const void *ptr, size_t len, int flags,
564               const struct sockaddr *to, int tolen);
565   ssize_t sendmsg (const struct msghdr *msg, int flags);
566
567   int ioctl (unsigned int cmd, void *);
568   int fcntl (int cmd, void *);
569   _off64_t lseek (_off64_t, int) { return 0; }
570   int shutdown (int how);
571   int close ();
572   void hclose (HANDLE) {close ();}
573   int dup (fhandler_base *child, int);
574
575   void set_close_on_exec (bool val);
576   int fixup_before_fork_exec (DWORD);
577   void fixup_after_fork (HANDLE);
578   void fixup_after_exec ();
579   char *get_proc_fd_name (char *buf);
580
581   select_record *select_read (select_stuff *);
582   select_record *select_write (select_stuff *);
583   select_record *select_except (select_stuff *);
584   void set_addr_family (int af) {addr_family = af;}
585   int get_addr_family () {return addr_family;}
586   void set_socket_type (int st) { type = st;}
587   int get_socket_type () {return type;}
588   void set_sun_path (const char *path);
589   char *get_sun_path () {return sun_path;}
590   void set_peer_sun_path (const char *path);
591   char *get_peer_sun_path () {return peer_sun_path;}
592
593   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
594   int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
595   int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
596   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
597   int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
598   int __stdcall link (const char *) __attribute__ ((regparm (2)));
599
600   fhandler_socket (void *) {}
601
602   void copyto (fhandler_base *x)
603   {
604     x->pc.free_strings ();
605     *reinterpret_cast<fhandler_socket *> (x) = *this;
606     x->reset (this);
607   }
608
609   fhandler_socket *clone (cygheap_types malloc_type = HEAP_FHANDLER)
610   {
611     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_socket));
612     fhandler_socket *fh = new (ptr) fhandler_socket (ptr);
613     copyto (fh);
614     return fh;
615   }
616 };
617
618 class fhandler_base_overlapped: public fhandler_base
619 {
620   static HANDLE asio_done;
621   static LONG asio_close_counter;
622 protected:
623   enum wait_return
624   {
625     overlapped_unknown = 0,
626     overlapped_success,
627     overlapped_nonblocking_no_data,
628     overlapped_error
629   };
630   bool io_pending;
631   OVERLAPPED io_status;
632   OVERLAPPED *overlapped;
633   size_t max_atomic_write;
634 public:
635   wait_return __stdcall wait_overlapped (bool, bool, DWORD *, bool, DWORD = 0) __attribute__ ((regparm (3)));
636   int __stdcall setup_overlapped () __attribute__ ((regparm (1)));
637   void __stdcall destroy_overlapped () __attribute__ ((regparm (1)));
638   virtual void __stdcall raw_read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
639   virtual ssize_t __stdcall raw_write (const void *ptr, size_t len) __attribute__ ((regparm (3)));
640   OVERLAPPED *&get_overlapped () {return overlapped;}
641   OVERLAPPED *get_overlapped_buffer () {return &io_status;}
642   void set_overlapped (OVERLAPPED *ov) {overlapped = ov;}
643   fhandler_base_overlapped (): io_pending (false), overlapped (NULL), max_atomic_write (0)
644   {
645     memset (&io_status, 0, sizeof io_status);
646   }
647   bool __stdcall has_ongoing_io () __attribute__ ((regparm (1)));
648
649   void fixup_after_fork (HANDLE);
650   void fixup_after_exec ();
651
652   int close ();
653   int dup (fhandler_base *child, int);
654
655   void check_later ();
656   static void flush_all_async_io () __attribute__ ((regparm (1)));;
657
658   fhandler_base_overlapped (void *) {}
659
660   virtual void copyto (fhandler_base *x)
661   {
662     x->pc.free_strings ();
663     *reinterpret_cast<fhandler_base_overlapped *> (x) = *this;
664     x->reset (this);
665   }
666
667   virtual fhandler_base_overlapped *clone (cygheap_types malloc_type = HEAP_FHANDLER)
668   {
669     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_base_overlapped));
670     fhandler_base_overlapped *fh = new (ptr) fhandler_base_overlapped (ptr);
671     copyto (fh);
672     return fh;
673   }
674
675   friend DWORD WINAPI flush_async_io (void *);
676 };
677
678 class fhandler_pipe: public fhandler_base_overlapped
679 {
680 private:
681   pid_t popen_pid;
682 public:
683   fhandler_pipe ();
684
685
686   bool ispipe() const { return true; }
687
688   void set_popen_pid (pid_t pid) {popen_pid = pid;}
689   pid_t get_popen_pid () const {return popen_pid;}
690   _off64_t lseek (_off64_t offset, int whence);
691   select_record *select_read (select_stuff *);
692   select_record *select_write (select_stuff *);
693   select_record *select_except (select_stuff *);
694   char *get_proc_fd_name (char *buf);
695   int open (int flags, mode_t mode = 0);
696   int dup (fhandler_base *child, int);
697   int ioctl (unsigned int cmd, void *);
698   int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
699   int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
700   int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
701   int init (HANDLE, DWORD, mode_t);
702   static int create (fhandler_pipe *[2], unsigned, int);
703   static DWORD create (LPSECURITY_ATTRIBUTES, HANDLE *, HANDLE *, DWORD,
704                        const char *, DWORD);
705   fhandler_pipe (void *) {}
706
707   void copyto (fhandler_base *x)
708   {
709     x->pc.free_strings ();
710     *reinterpret_cast<fhandler_pipe *> (x) = *this;
711     x->reset (this);
712   }
713
714   fhandler_pipe *clone (cygheap_types malloc_type = HEAP_FHANDLER)
715   {
716     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_pipe));
717     fhandler_pipe *fh = new (ptr) fhandler_pipe (ptr);
718     copyto (fh);
719     return fh;
720   }
721 };
722
723 class fhandler_fifo: public fhandler_base_overlapped
724 {
725   HANDLE read_ready;
726   HANDLE write_ready;
727   bool wait (HANDLE) __attribute__ ((regparm (2)));
728   char *fifo_name (char *, const char *) __attribute__ ((regparm (2)));
729 public:
730   fhandler_fifo ();
731   int open (int, mode_t);
732   int close ();
733   int dup (fhandler_base *child, int);
734   bool isfifo () const { return true; }
735   void set_close_on_exec (bool val);
736   void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3)));
737   void fixup_after_fork (HANDLE);
738   int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
739   select_record *select_read (select_stuff *);
740   select_record *select_write (select_stuff *);
741   select_record *select_except (select_stuff *);
742
743   fhandler_fifo (void *) {}
744
745   void copyto (fhandler_base *x)
746   {
747     x->pc.free_strings ();
748     *reinterpret_cast<fhandler_fifo *> (x) = *this;
749     x->reset (this);
750   }
751
752   fhandler_fifo *clone (cygheap_types malloc_type = HEAP_FHANDLER)
753   {
754     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_fifo));
755     fhandler_fifo *fh = new (ptr) fhandler_fifo (ptr);
756     copyto (fh);
757     return fh;
758   }
759 };
760
761 class fhandler_mailslot : public fhandler_base_overlapped
762 {
763   POBJECT_ATTRIBUTES get_object_attr (OBJECT_ATTRIBUTES &, PUNICODE_STRING, int);
764  public:
765   fhandler_mailslot ();
766   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
767   int open (int flags, mode_t mode = 0);
768   ssize_t __stdcall raw_write (const void *, size_t) __attribute__ ((regparm (3)));
769   int ioctl (unsigned int cmd, void *);
770   select_record *select_read (select_stuff *);
771
772   fhandler_mailslot (void *) {}
773
774   void copyto (fhandler_base *x)
775   {
776     x->pc.free_strings ();
777     *reinterpret_cast<fhandler_mailslot *> (x) = *this;
778     x->reset (this);
779   }
780
781   fhandler_mailslot *clone (cygheap_types malloc_type = HEAP_FHANDLER)
782   {
783     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_mailslot));
784     fhandler_mailslot *fh = new (ptr) fhandler_mailslot (ptr);
785     copyto (fh);
786     return fh;
787   }
788 };
789
790 class fhandler_dev_raw: public fhandler_base
791 {
792  protected:
793   char *devbuf;
794   size_t devbufsiz;
795   size_t devbufstart;
796   size_t devbufend;
797   struct status_flags
798   {
799     unsigned lastblk_to_read : 1;
800    public:
801     status_flags () : lastblk_to_read (0) {}
802   } status;
803
804   IMPLEMENT_STATUS_FLAG (bool, lastblk_to_read)
805
806   fhandler_dev_raw ();
807
808  public:
809   ~fhandler_dev_raw ();
810
811   int open (int flags, mode_t mode = 0);
812
813   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
814
815   int dup (fhandler_base *child, int);
816   int ioctl (unsigned int cmd, void *buf);
817
818   void fixup_after_fork (HANDLE);
819   void fixup_after_exec ();
820
821   fhandler_dev_raw (void *) {}
822
823   void copyto (fhandler_base *x)
824   {
825     x->pc.free_strings ();
826     *reinterpret_cast<fhandler_dev_raw *> (x) = *this;
827     x->reset (this);
828   }
829
830   fhandler_dev_raw *clone (cygheap_types malloc_type = HEAP_FHANDLER)
831   {
832     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_raw));
833     fhandler_dev_raw *fh = new (ptr) fhandler_dev_raw (ptr);
834     copyto (fh);
835     return fh;
836   }
837 };
838
839 #define MAX_PARTITIONS 15
840
841 struct part_t
842 {
843   LONG refcnt;
844   HANDLE hdl[MAX_PARTITIONS];
845 };
846
847 class fhandler_dev_floppy: public fhandler_dev_raw
848 {
849  private:
850   _off64_t drive_size;
851   unsigned long bytes_per_sector;
852   part_t *partitions;
853   struct status_flags
854   {
855     unsigned eom_detected    : 1;
856    public:
857     status_flags () : eom_detected (0) {}
858   } status;
859
860   IMPLEMENT_STATUS_FLAG (bool, eom_detected)
861
862   inline _off64_t get_current_position ();
863   int get_drive_info (struct hd_geometry *geo);
864
865   int lock_partition (DWORD to_write);
866
867   BOOL write_file (const void *buf, DWORD to_write, DWORD *written, int *err);
868   BOOL read_file (void *buf, DWORD to_read, DWORD *read, int *err);
869
870  public:
871   fhandler_dev_floppy ();
872
873   int open (int flags, mode_t mode = 0);
874   int close ();
875   int dup (fhandler_base *child, int);
876   void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3)));
877   ssize_t __stdcall raw_write (const void *ptr, size_t ulen) __attribute__ ((regparm (3)));
878   _off64_t lseek (_off64_t offset, int whence);
879   int ioctl (unsigned int cmd, void *buf);
880
881   fhandler_dev_floppy (void *) {}
882
883   void copyto (fhandler_base *x)
884   {
885     x->pc.free_strings ();
886     *reinterpret_cast<fhandler_dev_floppy *> (x) = *this;
887     x->reset (this);
888   }
889
890   fhandler_dev_floppy *clone (cygheap_types malloc_type = HEAP_FHANDLER)
891   {
892     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_floppy));
893     fhandler_dev_floppy *fh = new (ptr) fhandler_dev_floppy (ptr);
894     copyto (fh);
895     return fh;
896   }
897 };
898
899 class fhandler_dev_tape: public fhandler_dev_raw
900 {
901   HANDLE mt_mtx;
902   HANDLE mt_evt;
903
904   bool is_rewind_device () { return get_minor () < 128; }
905   unsigned int driveno () { return (unsigned int) get_minor () & 0x7f; }
906   void drive_init ();
907
908   inline bool _lock (bool);
909   inline int unlock (int ret = 0);
910
911  public:
912   fhandler_dev_tape ();
913
914   int open (int flags, mode_t mode = 0);
915   virtual int close ();
916
917   void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3)));
918   ssize_t __stdcall raw_write (const void *ptr, size_t ulen) __attribute__ ((regparm (3)));
919
920   virtual _off64_t lseek (_off64_t offset, int whence);
921
922   virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
923
924   virtual int dup (fhandler_base *child, int);
925   virtual void fixup_after_fork (HANDLE parent);
926   virtual void set_close_on_exec (bool val);
927   virtual int ioctl (unsigned int cmd, void *buf);
928
929   fhandler_dev_tape (void *) {}
930
931   void copyto (fhandler_base *x)
932   {
933     x->pc.free_strings ();
934     *reinterpret_cast<fhandler_dev_tape *> (x) = *this;
935     x->reset (this);
936   }
937
938   fhandler_dev_tape *clone (cygheap_types malloc_type = HEAP_FHANDLER)
939   {
940     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_tape));
941     fhandler_dev_tape *fh = new (ptr) fhandler_dev_tape (ptr);
942     copyto (fh);
943     return fh;
944   }
945 };
946
947 /* Standard disk file */
948
949 class fhandler_disk_file: public fhandler_base
950 {
951   HANDLE prw_handle;
952   int readdir_helper (DIR *, dirent *, DWORD, DWORD, PUNICODE_STRING fname) __attribute__ ((regparm (3)));
953
954   int prw_open (bool);
955
956  public:
957   fhandler_disk_file ();
958   fhandler_disk_file (path_conv &pc);
959
960   int open (int flags, mode_t mode);
961   int close ();
962   int dup (fhandler_base *child, int);
963   void fixup_after_fork (HANDLE parent);
964   int lock (int, struct __flock64 *);
965   bool isdevice () const { return false; }
966   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
967   int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
968   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
969   int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
970   ssize_t __stdcall fgetxattr (const char *, void *, size_t) __attribute__ ((regparm (3)));
971   int __stdcall fsetxattr (const char *, const void *, size_t, int) __attribute__ ((regparm (3)));
972   int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
973   int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
974   int __stdcall link (const char *) __attribute__ ((regparm (2)));
975   int __stdcall utimens (const struct timespec *) __attribute__ ((regparm (2)));
976   int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
977
978   HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off);
979   int munmap (HANDLE h, caddr_t addr, size_t len);
980   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
981   bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
982                               _off64_t offset, DWORD size, void *address);
983   int mkdir (mode_t mode);
984   int rmdir ();
985   DIR *opendir (int fd) __attribute__ ((regparm (2)));
986   int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
987   long telldir (DIR *);
988   void seekdir (DIR *, long);
989   void rewinddir (DIR *);
990   int closedir (DIR *);
991
992   ssize_t __stdcall pread (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
993   ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
994
995   fhandler_disk_file (void *) {}
996
997   void copyto (fhandler_base *x)
998   {
999     x->pc.free_strings ();
1000     *reinterpret_cast<fhandler_disk_file *> (x) = *this;
1001     x->reset (this);
1002   }
1003
1004   fhandler_disk_file *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1005   {
1006     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_disk_file));
1007     fhandler_disk_file *fh = new (ptr) fhandler_disk_file (ptr);
1008     copyto (fh);
1009     return fh;
1010   }
1011 };
1012
1013 class fhandler_cygdrive: public fhandler_disk_file
1014 {
1015   enum
1016   {
1017     DRVSZ = sizeof ("x:\\")
1018   };
1019   int ndrives;
1020   const char *pdrive;
1021   char pdrive_buf[1 + (2 * 26 * DRVSZ)];
1022   void set_drives ();
1023  public:
1024   fhandler_cygdrive ();
1025   int open (int flags, mode_t mode);
1026   int close ();
1027   DIR *opendir (int fd) __attribute__ ((regparm (2)));
1028   int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
1029   void rewinddir (DIR *);
1030   int closedir (DIR *);
1031   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
1032
1033   fhandler_cygdrive (void *) {}
1034
1035   void copyto (fhandler_base *x)
1036   {
1037     x->pc.free_strings ();
1038     *reinterpret_cast<fhandler_cygdrive *> (x) = *this;
1039     x->reset (this);
1040   }
1041
1042   fhandler_cygdrive *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1043   {
1044     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_cygdrive));
1045     fhandler_cygdrive *fh = new (ptr) fhandler_cygdrive (ptr);
1046     copyto (fh);
1047     return fh;
1048   }
1049 };
1050
1051 class fhandler_serial: public fhandler_base
1052 {
1053  private:
1054   size_t vmin_;                         /* from termios */
1055   unsigned int vtime_;                  /* from termios */
1056   pid_t pgrp_;
1057   int rts;                              /* for Windows 9x purposes only */
1058   int dtr;                              /* for Windows 9x purposes only */
1059
1060  public:
1061   int overlapped_armed;
1062   OVERLAPPED io_status;
1063   DWORD ev;
1064
1065   /* Constructor */
1066   fhandler_serial ();
1067
1068   int open (int flags, mode_t mode);
1069   int close ();
1070   int init (HANDLE h, DWORD a, mode_t flags);
1071   void overlapped_setup ();
1072   int dup (fhandler_base *child, int);
1073   void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3)));
1074   ssize_t __stdcall raw_write (const void *ptr, size_t ulen) __attribute__ ((regparm (3)));
1075   int tcsendbreak (int);
1076   int tcdrain ();
1077   int tcflow (int);
1078   int ioctl (unsigned int cmd, void *);
1079   int switch_modem_lines (int set, int clr);
1080   int tcsetattr (int a, const struct termios *t);
1081   int tcgetattr (struct termios *t);
1082   _off64_t lseek (_off64_t, int) { return 0; }
1083   int tcflush (int);
1084   bool is_tty () const { return true; }
1085   void fixup_after_fork (HANDLE parent);
1086   void fixup_after_exec ();
1087
1088   /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
1089      don't use it for permissions checking.  fhandler_pty_slave does
1090      permission checking on pgrps.  */
1091   virtual int tcgetpgrp () { return pgrp_; }
1092   virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
1093   select_record *select_read (select_stuff *);
1094   select_record *select_write (select_stuff *);
1095   select_record *select_except (select_stuff *);
1096
1097   fhandler_serial (void *) {}
1098
1099   void copyto (fhandler_base *x)
1100   {
1101     x->pc.free_strings ();
1102     *reinterpret_cast<fhandler_serial *> (x) = *this;
1103     x->reset (this);
1104   }
1105
1106   fhandler_serial *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1107   {
1108     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_serial));
1109     fhandler_serial *fh = new (ptr) fhandler_serial (ptr);
1110     copyto (fh);
1111     return fh;
1112   }
1113 };
1114
1115 #define acquire_output_mutex(ms) \
1116   __acquire_output_mutex (__PRETTY_FUNCTION__, __LINE__, ms)
1117
1118 #define release_output_mutex() \
1119   __release_output_mutex (__PRETTY_FUNCTION__, __LINE__)
1120
1121 class tty;
1122 class tty_min;
1123 class fhandler_termios: public fhandler_base
1124 {
1125  private:
1126   HANDLE output_handle;
1127  protected:
1128   virtual void doecho (const void *, DWORD) {};
1129   virtual int accept_input () {return 1;};
1130   int ioctl (int, void *);
1131   tty_min *_tc;
1132   tty *get_ttyp () {return (tty *) tc ();}
1133  public:
1134   tty_min*& tc () {return _tc;}
1135   fhandler_termios () :
1136   fhandler_base ()
1137   {
1138     need_fork_fixup (true);
1139   }
1140   HANDLE& get_output_handle () { return output_handle; }
1141   line_edit_status line_edit (const char *rptr, int nread, termios&);
1142   void set_output_handle (HANDLE h) { output_handle = h; }
1143   void tcinit (bool force);
1144   bool is_tty () const { return true; }
1145   void sigflush ();
1146   int tcgetpgrp ();
1147   int tcsetpgrp (int pid);
1148   bg_check_types bg_check (int sig);
1149   virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
1150   virtual void __release_output_mutex (const char *fn, int ln) {}
1151   void echo_erase (int force = 0);
1152   virtual _off64_t lseek (_off64_t, int);
1153   int tcgetsid ();
1154
1155   fhandler_termios (void *) {}
1156
1157   virtual void copyto (fhandler_base *x)
1158   {
1159     x->pc.free_strings ();
1160     *reinterpret_cast<fhandler_termios *> (x) = *this;
1161     x->reset (this);
1162   }
1163
1164   virtual fhandler_termios *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1165   {
1166     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_termios));
1167     fhandler_termios *fh = new (ptr) fhandler_termios (ptr);
1168     copyto (fh);
1169     return fh;
1170   }
1171 };
1172
1173 enum ansi_intensity
1174 {
1175   INTENSITY_INVISIBLE,
1176   INTENSITY_DIM,
1177   INTENSITY_NORMAL,
1178   INTENSITY_BOLD
1179 };
1180
1181 #define normal 0
1182 #define gotesc 1
1183 #define gotsquare 2
1184 #define gotarg1 3
1185 #define gotrsquare 4
1186 #define gotcommand 5
1187 #define gettitle 6
1188 #define eattitle 7
1189 #define gotparen 8
1190 #define gotrparen 9
1191 #define MAXARGS 10
1192
1193 class dev_console
1194 {
1195   WORD default_color, underline_color, dim_color;
1196
1197   /* Used to determine if an input keystroke should be modified with META. */
1198   int meta_mask;
1199
1200 /* Output state */
1201   int state_;
1202   int args_[MAXARGS];
1203   int nargs_;
1204   unsigned rarg;
1205   bool saw_question_mark;
1206   bool saw_greater_than_sign;
1207   bool vt100_graphics_mode_G0;
1208   bool vt100_graphics_mode_G1;
1209   bool iso_2022_G1;
1210   bool alternate_charset_active;
1211   bool metabit;
1212   char backspace_keycode;
1213
1214   char my_title_buf [TITLESIZE + 1];
1215
1216   WORD current_win32_attr;
1217   ansi_intensity intensity;
1218   bool underline, blink, reverse;
1219   WORD fg, bg;
1220
1221   /* saved cursor coordinates */
1222   int savex, savey;
1223
1224   /* saved screen */
1225   COORD savebufsiz;
1226   PCHAR_INFO savebuf;
1227
1228   struct
1229     {
1230       short Top, Bottom;
1231     } scroll_region;
1232   struct
1233     {
1234       SHORT winTop;
1235       SHORT winBottom;
1236       COORD dwWinSize;
1237       COORD dwBufferSize;
1238       COORD dwCursorPosition;
1239       WORD wAttributes;
1240     } info;
1241
1242   COORD dwLastCursorPosition;
1243   COORD dwMousePosition;        /* scroll-adjusted coord of mouse event */
1244   COORD dwLastMousePosition;    /* scroll-adjusted coord of previous mouse event */
1245   DWORD dwLastButtonState;      /* (not noting mouse wheel events) */
1246   int last_button_code;         /* transformed mouse report button code */
1247   int nModifiers;
1248
1249   bool insert_mode;
1250   int use_mouse;
1251   bool use_focus;
1252   bool raw_win32_keyboard_mode;
1253
1254   inline UINT get_console_cp ();
1255   DWORD con_to_str (char *d, int dlen, WCHAR w);
1256   DWORD str_to_con (mbtowc_p, const char *, PWCHAR d, const char *s, DWORD sz);
1257   void set_color (HANDLE);
1258   bool fillin_info (HANDLE);
1259   void set_default_attr ();
1260
1261   friend class fhandler_console;
1262 };
1263
1264 /* This is a input and output console handle */
1265 class fhandler_console: public fhandler_termios
1266 {
1267 public:
1268   struct console_state
1269   {
1270     tty_min tty_min_state;
1271     dev_console dev_state;
1272   };
1273 private:
1274   static const unsigned MAX_WRITE_CHARS;
1275   static console_state *shared_console_info;
1276   static bool invisible_console;
1277
1278   /* Used when we encounter a truncated multi-byte sequence.  The
1279      lead bytes are stored here and revisited in the next write call. */
1280   struct {
1281     int len;
1282     unsigned char buf[4]; /* Max len of valid UTF-8 sequence. */
1283   } trunc_buf;
1284   PWCHAR write_buf;
1285
1286 /* Output calls */
1287   void set_default_attr ();
1288
1289   void clear_screen (int, int, int, int);
1290   void scroll_screen (int, int, int, int, int, int);
1291   void cursor_set (bool, int, int);
1292   void cursor_get (int *, int *);
1293   void cursor_rel (int, int);
1294   inline void write_replacement_char ();
1295   inline bool write_console (PWCHAR, DWORD, DWORD&);
1296   const unsigned char *write_normal (unsigned const char*, unsigned const char *);
1297   void char_command (char);
1298   bool set_raw_win32_keyboard_mode (bool);
1299   int output_tcsetattr (int a, const struct termios *t);
1300
1301 /* Input calls */
1302   int igncr_enabled ();
1303   int input_tcsetattr (int a, const struct termios *t);
1304   void set_cursor_maybe ();
1305   static bool create_invisible_console (HWINSTA);
1306   static bool create_invisible_console_workaround ();
1307   static console_state *open_shared_console (HWND, HANDLE&, bool&);
1308
1309  public:
1310   static pid_t tc_getpgid () {return shared_console_info->tty_min_state.getpgid ();}
1311   fhandler_console (fh_devices);
1312   static console_state *open_shared_console (HWND hw, HANDLE& h)
1313   {
1314     bool createit = false;
1315     return open_shared_console (hw, h, createit);
1316   }
1317
1318   fhandler_console* is_console () { return this; }
1319
1320   bool use_archetype () const {return true;}
1321
1322   int open (int flags, mode_t mode);
1323   void open_setup (int flags);
1324   int dup (fhandler_base *, int);
1325
1326   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1327   ssize_t __stdcall write (const void *ptr, size_t len);
1328   void doecho (const void *str, DWORD len) { (void) write (str, len); }
1329   int close ();
1330
1331   int tcflush (int);
1332   int tcsetattr (int a, const struct termios *t);
1333   int tcgetattr (struct termios *t);
1334
1335   int ioctl (unsigned int cmd, void *);
1336   int init (HANDLE, DWORD, mode_t);
1337   bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event);
1338   bool focus_aware () {return shared_console_info->dev_state.use_focus;}
1339
1340   select_record *select_read (select_stuff *);
1341   select_record *select_write (select_stuff *);
1342   select_record *select_except (select_stuff *);
1343   void fixup_after_fork_exec (bool);
1344   void fixup_after_exec () {fixup_after_fork_exec (true);}
1345   void fixup_after_fork (HANDLE) {fixup_after_fork_exec (false);}
1346   void set_close_on_exec (bool val);
1347   void set_input_state ();
1348   void send_winch_maybe ();
1349   void setup ();
1350   bool set_unit ();
1351   static bool need_invisible ();
1352   static bool has_a () {return !invisible_console;}
1353
1354   fhandler_console (void *) {}
1355
1356   void copyto (fhandler_base *x)
1357   {
1358     x->pc.free_strings ();
1359     *reinterpret_cast<fhandler_console *> (x) = *this;
1360     x->reset (this);
1361   }
1362
1363   fhandler_console *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1364   {
1365     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_console));
1366     fhandler_console *fh = new (ptr) fhandler_console (ptr);
1367     copyto (fh);
1368     return fh;
1369   }
1370   friend tty_min * tty_list::get_cttyp ();
1371 };
1372
1373 class fhandler_pty_common: public fhandler_termios
1374 {
1375  public:
1376   fhandler_pty_common ()
1377     : fhandler_termios (),
1378       output_mutex (NULL),
1379     input_mutex (NULL), input_available_event (NULL)
1380   {
1381     pc.file_attributes (FILE_ATTRIBUTE_NORMAL);
1382   }
1383   static const unsigned pipesize = 128 * 1024;
1384   HANDLE output_mutex, input_mutex;
1385   HANDLE input_available_event;
1386
1387   bool use_archetype () const {return true;}
1388   DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
1389   void __release_output_mutex (const char *fn, int ln);
1390
1391   int close ();
1392   _off64_t lseek (_off64_t, int);
1393   void set_close_on_exec (bool val);
1394   select_record *select_read (select_stuff *);
1395   select_record *select_write (select_stuff *);
1396   select_record *select_except (select_stuff *);
1397
1398   fhandler_pty_common (void *) {}
1399
1400   virtual void copyto (fhandler_base *x)
1401   {
1402     x->pc.free_strings ();
1403     *reinterpret_cast<fhandler_pty_common *> (x) = *this;
1404     x->reset (this);
1405   }
1406
1407   virtual fhandler_pty_common *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1408   {
1409     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_pty_common));
1410     fhandler_pty_common *fh = new (ptr) fhandler_pty_common (ptr);
1411     copyto (fh);
1412     return fh;
1413   }
1414 };
1415
1416 class fhandler_pty_slave: public fhandler_pty_common
1417 {
1418   HANDLE inuse;                 // used to indicate that a tty is in use
1419
1420   /* Helper functions for fchmod and fchown. */
1421   bool fch_open_handles ();
1422   int fch_set_sd (security_descriptor &sd, bool chown);
1423   void fch_close_handles ();
1424
1425  public:
1426   /* Constructor */
1427   fhandler_pty_slave (int);
1428
1429   int open (int flags, mode_t mode = 0);
1430   void open_setup (int flags);
1431   ssize_t __stdcall write (const void *ptr, size_t len);
1432   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1433   int init (HANDLE, DWORD, mode_t);
1434
1435   int tcsetattr (int a, const struct termios *t);
1436   int tcgetattr (struct termios *t);
1437   int tcflush (int);
1438   int ioctl (unsigned int cmd, void *);
1439   int close ();
1440   void cleanup ();
1441   int dup (fhandler_base *child, int);
1442   void fixup_after_fork (HANDLE parent);
1443   void fixup_after_exec ();
1444
1445   select_record *select_read (select_stuff *);
1446   int get_unit ();
1447   virtual char const *ttyname () { return pc.dev.name; }
1448   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
1449   int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
1450   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
1451
1452   fhandler_pty_slave (void *) {}
1453
1454   void copyto (fhandler_base *x)
1455   {
1456     x->pc.free_strings ();
1457     *reinterpret_cast<fhandler_pty_slave *> (x) = *this;
1458     x->reset (this);
1459   }
1460
1461   fhandler_pty_slave *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1462   {
1463     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_pty_slave));
1464     fhandler_pty_slave *fh = new (ptr) fhandler_pty_slave (ptr);
1465     copyto (fh);
1466     return fh;
1467   }
1468 };
1469
1470 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
1471 class fhandler_pty_master: public fhandler_pty_common
1472 {
1473   int pktmode;                  // non-zero if pty in a packet mode.
1474   HANDLE master_ctl;            // Control socket for handle duplication
1475   cygthread *master_thread;     // Master control thread
1476   HANDLE from_master, to_master;
1477   DWORD dwProcessId;            // Owner of master handles
1478
1479 public:
1480   int need_nl;                  // Next read should start with \n
1481
1482   /* Constructor */
1483   fhandler_pty_master (int);
1484
1485   DWORD pty_master_thread ();
1486   int process_slave_output (char *buf, size_t len, int pktmode_on);
1487   void doecho (const void *str, DWORD len);
1488   int accept_input ();
1489   int open (int flags, mode_t mode = 0);
1490   void open_setup (int flags);
1491   ssize_t __stdcall write (const void *ptr, size_t len);
1492   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1493   int close ();
1494   void cleanup ();
1495
1496   int tcsetattr (int a, const struct termios *t);
1497   int tcgetattr (struct termios *t);
1498   int tcflush (int);
1499   int ioctl (unsigned int cmd, void *);
1500
1501   int ptsname_r (char *, size_t);
1502
1503   bool hit_eof ();
1504   bool setup ();
1505   int dup (fhandler_base *, int);
1506   void fixup_after_fork (HANDLE parent);
1507   void fixup_after_exec ();
1508   int tcgetpgrp ();
1509
1510   fhandler_pty_master (void *) {}
1511   ~fhandler_pty_master ();
1512
1513   void copyto (fhandler_base *x)
1514   {
1515     x->pc.free_strings ();
1516     *reinterpret_cast<fhandler_pty_master *> (x) = *this;
1517     x->reset (this);
1518   }
1519
1520   fhandler_pty_master *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1521   {
1522     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_pty_master));
1523     fhandler_pty_master *fh = new (ptr) fhandler_pty_master (ptr);
1524     copyto (fh);
1525     return fh;
1526   }
1527 };
1528
1529 class fhandler_dev_null: public fhandler_base
1530 {
1531  public:
1532   fhandler_dev_null ();
1533
1534   select_record *select_read (select_stuff *);
1535   select_record *select_write (select_stuff *);
1536   select_record *select_except (select_stuff *);
1537
1538   fhandler_dev_null (void *) {}
1539
1540   void copyto (fhandler_base *x)
1541   {
1542     x->pc.free_strings ();
1543     *reinterpret_cast<fhandler_dev_null *> (x) = *this;
1544     x->reset (this);
1545   }
1546
1547   fhandler_dev_null *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1548   {
1549     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_null));
1550     fhandler_dev_null *fh = new (ptr) fhandler_dev_null (ptr);
1551     copyto (fh);
1552     return fh;
1553   }
1554 };
1555
1556 class fhandler_dev_zero: public fhandler_base
1557 {
1558  public:
1559   fhandler_dev_zero ();
1560   int open (int flags, mode_t mode = 0);
1561   ssize_t __stdcall write (const void *ptr, size_t len);
1562   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1563   _off64_t lseek (_off64_t offset, int whence);
1564
1565   virtual HANDLE mmap (caddr_t *addr, size_t len, int prot,
1566                        int flags, _off64_t off);
1567   virtual int munmap (HANDLE h, caddr_t addr, size_t len);
1568   virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
1569   virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
1570                                       _off64_t offset, DWORD size,
1571                                       void *address);
1572
1573   fhandler_dev_zero (void *) {}
1574
1575   void copyto (fhandler_base *x)
1576   {
1577     x->pc.free_strings ();
1578     *reinterpret_cast<fhandler_dev_zero *> (x) = *this;
1579     x->reset (this);
1580   }
1581
1582   fhandler_dev_zero *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1583   {
1584     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_zero));
1585     fhandler_dev_zero *fh = new (ptr) fhandler_dev_zero (ptr);
1586     copyto (fh);
1587     return fh;
1588   }
1589 };
1590
1591 class fhandler_dev_random: public fhandler_base
1592 {
1593  protected:
1594   HCRYPTPROV crypt_prov;
1595   long pseudo;
1596   _off64_t dummy_offset;
1597
1598   bool crypt_gen_random (void *ptr, size_t len);
1599   int pseudo_write (const void *ptr, size_t len);
1600   int pseudo_read (void *ptr, size_t len);
1601
1602  public:
1603   fhandler_dev_random ();
1604   int open (int flags, mode_t mode = 0);
1605   ssize_t __stdcall write (const void *ptr, size_t len);
1606   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1607   _off64_t lseek (_off64_t offset, int whence);
1608   int close ();
1609   int dup (fhandler_base *child, int);
1610
1611   fhandler_dev_random (void *) {}
1612
1613   void copyto (fhandler_base *x)
1614   {
1615     x->pc.free_strings ();
1616     *reinterpret_cast<fhandler_dev_random *> (x) = *this;
1617     x->reset (this);
1618   }
1619
1620   fhandler_dev_random *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1621   {
1622     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_random));
1623     fhandler_dev_random *fh = new (ptr) fhandler_dev_random (ptr);
1624     copyto (fh);
1625     return fh;
1626   }
1627 };
1628
1629 class fhandler_dev_mem: public fhandler_base
1630 {
1631  protected:
1632   DWORD mem_size;
1633   _off64_t pos;
1634
1635  public:
1636   fhandler_dev_mem ();
1637   ~fhandler_dev_mem ();
1638
1639   int open (int flags, mode_t mode = 0);
1640   ssize_t __stdcall write (const void *ptr, size_t ulen);
1641   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1642   _off64_t lseek (_off64_t offset, int whence);
1643   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
1644
1645   HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off);
1646   int munmap (HANDLE h, caddr_t addr, size_t len);
1647   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
1648   bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
1649                               _off64_t offset, DWORD size, void *address);
1650
1651   fhandler_dev_mem (void *) {}
1652
1653   void copyto (fhandler_base *x)
1654   {
1655     x->pc.free_strings ();
1656     *reinterpret_cast<fhandler_dev_mem *> (x) = *this;
1657     x->reset (this);
1658   }
1659
1660   fhandler_dev_mem *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1661   {
1662     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_mem));
1663     fhandler_dev_mem *fh = new (ptr) fhandler_dev_mem (ptr);
1664     copyto (fh);
1665     return fh;
1666   }
1667 };
1668
1669 class fhandler_dev_clipboard: public fhandler_base
1670 {
1671   _off64_t pos;
1672   void *membuffer;
1673   size_t msize;
1674   bool eof;
1675  public:
1676   fhandler_dev_clipboard ();
1677   int is_windows () { return 1; }
1678   int open (int flags, mode_t mode = 0);
1679   ssize_t __stdcall write (const void *ptr, size_t len);
1680   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1681   _off64_t lseek (_off64_t offset, int whence);
1682   int close ();
1683
1684   int dup (fhandler_base *child, int);
1685   void fixup_after_exec ();
1686
1687   fhandler_dev_clipboard (void *) {}
1688
1689   void copyto (fhandler_base *x)
1690   {
1691     x->pc.free_strings ();
1692     *reinterpret_cast<fhandler_dev_clipboard *> (x) = *this;
1693     x->reset (this);
1694   }
1695
1696   fhandler_dev_clipboard *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1697   {
1698     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_clipboard));
1699     fhandler_dev_clipboard *fh = new (ptr) fhandler_dev_clipboard (ptr);
1700     copyto (fh);
1701     return fh;
1702   }
1703 };
1704
1705 class fhandler_windows: public fhandler_base
1706 {
1707  private:
1708   HWND hWnd_;   // the window whose messages are to be retrieved by read() call
1709   int method_;  // write method (Post or Send)
1710  public:
1711   fhandler_windows ();
1712   int is_windows () { return 1; }
1713   int open (int flags, mode_t mode = 0);
1714   ssize_t __stdcall write (const void *ptr, size_t len);
1715   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1716   int ioctl (unsigned int cmd, void *);
1717   _off64_t lseek (_off64_t, int) { return 0; }
1718   int close () { return 0; }
1719
1720   void set_close_on_exec (bool val);
1721   void fixup_after_fork (HANDLE parent);
1722   select_record *select_read (select_stuff *);
1723   select_record *select_write (select_stuff *);
1724   select_record *select_except (select_stuff *);
1725
1726   fhandler_windows (void *) {}
1727
1728   void copyto (fhandler_base *x)
1729   {
1730     x->pc.free_strings ();
1731     *reinterpret_cast<fhandler_windows *> (x) = *this;
1732     x->reset (this);
1733   }
1734
1735   fhandler_windows *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1736   {
1737     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_windows));
1738     fhandler_windows *fh = new (ptr) fhandler_windows (ptr);
1739     copyto (fh);
1740     return fh;
1741   }
1742 };
1743
1744 class fhandler_dev_dsp: public fhandler_base
1745 {
1746  public:
1747   class Audio;
1748   class Audio_out;
1749   class Audio_in;
1750  private:
1751   int audioformat_;
1752   int audiofreq_;
1753   int audiobits_;
1754   int audiochannels_;
1755   Audio_out *audio_out_;
1756   Audio_in  *audio_in_;
1757  public:
1758   fhandler_dev_dsp ();
1759
1760   int open (int flags, mode_t mode = 0);
1761   ssize_t __stdcall write (const void *ptr, size_t len);
1762   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1763   int ioctl (unsigned int cmd, void *);
1764   _off64_t lseek (_off64_t, int);
1765   int close ();
1766   void fixup_after_fork (HANDLE parent);
1767   void fixup_after_exec ();
1768  private:
1769   void close_audio_in ();
1770   void close_audio_out (bool immediately = false);
1771   bool use_archetype () const {return true;}
1772
1773   fhandler_dev_dsp (void *) {}
1774
1775   void copyto (fhandler_base *x)
1776   {
1777     x->pc.free_strings ();
1778     *reinterpret_cast<fhandler_dev_dsp *> (x) = *this;
1779     x->reset (this);
1780   }
1781
1782   fhandler_dev_dsp *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1783   {
1784     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_dsp));
1785     fhandler_dev_dsp *fh = new (ptr) fhandler_dev_dsp (ptr);
1786     copyto (fh);
1787     return fh;
1788   }
1789 };
1790
1791 class fhandler_virtual : public fhandler_base
1792 {
1793  protected:
1794   char *filebuf;
1795   _off64_t filesize;
1796   _off64_t position;
1797   int fileid; // unique within each class
1798  public:
1799
1800   fhandler_virtual ();
1801   virtual ~fhandler_virtual();
1802
1803   virtual virtual_ftype_t exists();
1804   DIR *opendir (int fd) __attribute__ ((regparm (2)));
1805   long telldir (DIR *);
1806   void seekdir (DIR *, long);
1807   void rewinddir (DIR *);
1808   int closedir (DIR *);
1809   ssize_t __stdcall write (const void *ptr, size_t len);
1810   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1811   _off64_t lseek (_off64_t, int);
1812   int dup (fhandler_base *child, int);
1813   int open (int flags, mode_t mode = 0);
1814   int close ();
1815   int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2)));
1816   int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
1817   int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
1818   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
1819   int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
1820   virtual bool fill_filebuf ();
1821   char *get_filebuf () { return filebuf; }
1822   void fixup_after_exec ();
1823
1824   fhandler_virtual (void *) {}
1825
1826   virtual void copyto (fhandler_base *x)
1827   {
1828     x->pc.free_strings ();
1829     *reinterpret_cast<fhandler_virtual *> (x) = *this;
1830     x->reset (this);
1831   }
1832
1833   virtual fhandler_virtual *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1834   {
1835     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_virtual));
1836     fhandler_virtual *fh = new (ptr) fhandler_virtual (ptr);
1837     copyto (fh);
1838     return fh;
1839   }
1840 };
1841
1842 class fhandler_proc: public fhandler_virtual
1843 {
1844  public:
1845   fhandler_proc ();
1846   virtual_ftype_t exists();
1847   DIR *opendir (int fd) __attribute__ ((regparm (2)));
1848   int closedir (DIR *);
1849   int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
1850   static fh_devices get_proc_fhandler (const char *path);
1851
1852   int open (int flags, mode_t mode = 0);
1853   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
1854   bool fill_filebuf ();
1855
1856   fhandler_proc (void *) {}
1857
1858   virtual void copyto (fhandler_base *x)
1859   {
1860     x->pc.free_strings ();
1861     *reinterpret_cast<fhandler_proc *> (x) = *this;
1862     x->reset (this);
1863   }
1864
1865   virtual fhandler_proc *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1866   {
1867     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_proc));
1868     fhandler_proc *fh = new (ptr) fhandler_proc (ptr);
1869     copyto (fh);
1870     return fh;
1871   }
1872 };
1873
1874 class fhandler_procsys: public fhandler_virtual
1875 {
1876  public:
1877   fhandler_procsys ();
1878   virtual_ftype_t exists(struct __stat64 *buf) __attribute__ ((regparm (2)));
1879   virtual_ftype_t exists();
1880   DIR *opendir (int fd) __attribute__ ((regparm (2)));
1881   int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
1882   long telldir (DIR *);
1883   void seekdir (DIR *, long);
1884   int closedir (DIR *);
1885   int open (int flags, mode_t mode = 0);
1886   int close ();
1887   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
1888   ssize_t __stdcall write (const void *ptr, size_t len);
1889   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
1890   bool fill_filebuf ();
1891
1892   fhandler_procsys (void *) {}
1893
1894   void copyto (fhandler_base *x)
1895   {
1896     x->pc.free_strings ();
1897     *reinterpret_cast<fhandler_procsys *> (x) = *this;
1898     x->reset (this);
1899   }
1900
1901   fhandler_procsys *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1902   {
1903     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_procsys));
1904     fhandler_procsys *fh = new (ptr) fhandler_procsys (ptr);
1905     copyto (fh);
1906     return fh;
1907   }
1908 };
1909
1910 class fhandler_procsysvipc: public fhandler_proc
1911 {
1912   pid_t pid;
1913  public:
1914   fhandler_procsysvipc ();
1915   virtual_ftype_t exists();
1916   int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
1917   int open (int flags, mode_t mode = 0);
1918   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
1919   bool fill_filebuf ();
1920
1921   fhandler_procsysvipc (void *) {}
1922
1923   void copyto (fhandler_base *x)
1924   {
1925     x->pc.free_strings ();
1926     *reinterpret_cast<fhandler_procsysvipc *> (x) = *this;
1927     x->reset (this);
1928   }
1929
1930   fhandler_procsysvipc *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1931   {
1932     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_procsysvipc));
1933     fhandler_procsysvipc *fh = new (ptr) fhandler_procsysvipc (ptr);
1934     copyto (fh);
1935     return fh;
1936   }
1937 };
1938
1939 class fhandler_netdrive: public fhandler_virtual
1940 {
1941  public:
1942   fhandler_netdrive ();
1943   virtual_ftype_t exists();
1944   int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
1945   void seekdir (DIR *, long);
1946   void rewinddir (DIR *);
1947   int closedir (DIR *);
1948   int open (int flags, mode_t mode = 0);
1949   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
1950
1951   fhandler_netdrive (void *) {}
1952
1953   void copyto (fhandler_base *x)
1954   {
1955     x->pc.free_strings ();
1956     *reinterpret_cast<fhandler_netdrive *> (x) = *this;
1957     x->reset (this);
1958   }
1959
1960   fhandler_netdrive *clone (cygheap_types malloc_type = HEAP_FHANDLER)
1961   {
1962     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_netdrive));
1963     fhandler_netdrive *fh = new (ptr) fhandler_netdrive (ptr);
1964     copyto (fh);
1965     return fh;
1966   }
1967 };
1968
1969 class fhandler_registry: public fhandler_proc
1970 {
1971  private:
1972   wchar_t *value_name;
1973   DWORD wow64;
1974   int prefix_len;
1975  public:
1976   fhandler_registry ();
1977   void set_name (path_conv &pc);
1978   virtual_ftype_t exists();
1979   int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
1980   long telldir (DIR *);
1981   void seekdir (DIR *, long);
1982   void rewinddir (DIR *);
1983   int closedir (DIR *);
1984
1985   int open (int flags, mode_t mode = 0);
1986   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
1987   bool fill_filebuf ();
1988   int close ();
1989   int dup (fhandler_base *child, int);
1990
1991   fhandler_registry (void *) {}
1992
1993   void copyto (fhandler_base *x)
1994   {
1995     x->pc.free_strings ();
1996     *reinterpret_cast<fhandler_registry *> (x) = *this;
1997     x->reset (this);
1998   }
1999
2000   fhandler_registry *clone (cygheap_types malloc_type = HEAP_FHANDLER)
2001   {
2002     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_registry));
2003     fhandler_registry *fh = new (ptr) fhandler_registry (ptr);
2004     copyto (fh);
2005     return fh;
2006   }
2007 };
2008
2009 class pinfo;
2010 class fhandler_process: public fhandler_proc
2011 {
2012   pid_t pid;
2013  public:
2014   fhandler_process ();
2015   virtual_ftype_t exists();
2016   DIR *opendir (int fd) __attribute__ ((regparm (2)));
2017   int closedir (DIR *);
2018   int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
2019   int open (int flags, mode_t mode = 0);
2020   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
2021   bool fill_filebuf ();
2022
2023   fhandler_process (void *) {}
2024
2025   void copyto (fhandler_base *x)
2026   {
2027     x->pc.free_strings ();
2028     *reinterpret_cast<fhandler_process *> (x) = *this;
2029     x->reset (this);
2030   }
2031
2032   fhandler_process *clone (cygheap_types malloc_type = HEAP_FHANDLER)
2033   {
2034     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_process));
2035     fhandler_process *fh = new (ptr) fhandler_process (ptr);
2036     copyto (fh);
2037     return fh;
2038   }
2039 };
2040
2041 class fhandler_procnet: public fhandler_proc
2042 {
2043   pid_t pid;
2044  public:
2045   fhandler_procnet ();
2046   virtual_ftype_t exists();
2047   int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
2048   int open (int flags, mode_t mode = 0);
2049   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
2050   bool fill_filebuf ();
2051
2052   fhandler_procnet (void *) {}
2053
2054   void copyto (fhandler_base *x)
2055   {
2056     x->pc.free_strings ();
2057     *reinterpret_cast<fhandler_procnet *> (x) = *this;
2058     x->reset (this);
2059   }
2060
2061   fhandler_procnet *clone (cygheap_types malloc_type = HEAP_FHANDLER)
2062   {
2063     void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_procnet));
2064     fhandler_procnet *fh = new (ptr) fhandler_procnet (ptr);
2065     copyto (fh);
2066     return fh;
2067   }
2068 };
2069
2070 struct fhandler_nodevice: public fhandler_base
2071 {
2072   fhandler_nodevice ();
2073   int open (int flags, mode_t mode = 0);
2074 };
2075
2076 #define report_tty_counts(fh, call, use_op) \
2077   termios_printf ("%s %s, %susecount %d",\
2078                   fh->ttyname (), call,\
2079                   use_op, ((fhandler_pty_slave *) (fh->archetype ?: fh))->usecount);
2080
2081 typedef union
2082 {
2083   char __base[sizeof (fhandler_base)];
2084   char __console[sizeof (fhandler_console)];
2085   char __cygdrive[sizeof (fhandler_cygdrive)];
2086   char __dev_clipboard[sizeof (fhandler_dev_clipboard)];
2087   char __dev_dsp[sizeof (fhandler_dev_dsp)];
2088   char __dev_floppy[sizeof (fhandler_dev_floppy)];
2089   char __dev_mem[sizeof (fhandler_dev_mem)];
2090   char __dev_null[sizeof (fhandler_dev_null)];
2091   char __dev_random[sizeof (fhandler_dev_random)];
2092   char __dev_raw[sizeof (fhandler_dev_raw)];
2093   char __dev_tape[sizeof (fhandler_dev_tape)];
2094   char __dev_zero[sizeof (fhandler_dev_zero)];
2095   char __disk_file[sizeof (fhandler_disk_file)];
2096   char __fifo[sizeof (fhandler_fifo)];
2097   char __mailslot[sizeof (fhandler_mailslot)];
2098   char __netdrive[sizeof (fhandler_netdrive)];
2099   char __nodevice[sizeof (fhandler_nodevice)];
2100   char __pipe[sizeof (fhandler_pipe)];
2101   char __proc[sizeof (fhandler_proc)];
2102   char __process[sizeof (fhandler_process)];
2103   char __procnet[sizeof (fhandler_procnet)];
2104   char __procsys[sizeof (fhandler_procsys)];
2105   char __procsysvipc[sizeof (fhandler_procsysvipc)];
2106   char __pty_master[sizeof (fhandler_pty_master)];
2107   char __registry[sizeof (fhandler_registry)];
2108   char __serial[sizeof (fhandler_serial)];
2109   char __socket[sizeof (fhandler_socket)];
2110   char __termios[sizeof (fhandler_termios)];
2111   char __pty_common[sizeof (fhandler_pty_common)];
2112   char __pty_slave[sizeof (fhandler_pty_slave)];
2113   char __virtual[sizeof (fhandler_virtual)];
2114   char __windows[sizeof (fhandler_windows)];
2115 } fhandler_union;
2116 #endif /* _FHANDLER_H_ */