OSDN Git Service

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