OSDN Git Service

* fhandler.h (fhandler_termios::echo_erase): Declare new method.
[pf3gnuchains/pf3gnuchains3x.git] / winsup / cygwin / fhandler.h
1 /* fhandler.h
2
3    Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #ifndef _FHANDLER_H_
12 #define _FHANDLER_H_
13
14 #include <sys/ioctl.h>
15
16 /* Classes
17
18   Code is located in fhandler.cc unless another file name is given.
19
20   fhandler_base           normal I/O
21
22      fhandler_disk_file
23      fhandler_serial      Adds vmin and vtime.
24      fhandler_dev_null    Not really I/O
25      fhandler_dev_zero    Faked
26
27      fhandler_dev_raw     (fhandler_raw.cc)
28      fhandler_dev_floppy  (fhandler_floppy.cc)
29      fhandler_dev_tape    (fhandler_tape.cc)
30
31      fhandler_pipe
32      fhandler_socket      (fhandler_socket.cc)
33
34      fhandler_tty_slave   (tty.cc)
35      fhandler_pty_master  (tty.cc)
36      fhandler_tty_master  (tty.cc)
37
38      fhandler_console     Out with ansi control. (console.cc)
39
40      fhandler_windows     Windows messages I/O (fhandler_windows.cc)
41
42      fhandler_dev_random  /dev/[u]random implementation (fhandler_random.cc)
43
44      fhandler_dev_mem     /dev/mem implementation (fhandler_mem.cc)
45
46      fhandler_dev_clipboard     /dev/clipboard implementation (fhandler_clipboard.cc)
47
48      fhandler_proc        Interesting possibility, not implemented yet
49 */
50
51 enum
52 {
53   FH_RBINARY = 0x00001000,      /* binary read mode */
54   FH_WBINARY = 0x00002000,      /* binary write mode */
55   FH_CLOEXEC = 0x00004000,      /* close-on-exec */
56   FH_RBINSET = 0x00008000,      /* binary read mode has been explicitly set */
57   FH_WBINSET = 0x00010000,      /* binary write mode has been explicitly set */
58   FH_APPEND  = 0x00020000,      /* always append */
59   FH_ASYNC   = 0x00040000,      /* async I/O */
60   FH_HADEOF  = 0x00080000,      /* EOF seen */
61
62   FH_SYMLINK = 0x00100000,      /* is a symlink */
63   FH_EXECABL = 0x00200000,      /* file looked like it would run:
64                                  * ends in .exe or .bat or begins with #! */
65   FH_W95LSBUG= 0x00400000,      /* set when lseek is called as a flag that
66                                  * _write should check if we've moved beyond
67                                  * EOF, zero filling if so. */
68   FH_NOFRNAME= 0x00800000,      /* Set if shouldn't free unix_path_name and
69                                    windows_path_name_ on destruction. */
70   FH_NOEINTR = 0x01000000,      /* Set if I/O should be uninterruptible. */
71   FH_FFIXUP  = 0x02000000,      /* Set if need to fixup after fork. */
72   FH_LOCAL   = 0x04000000,      /* File is unix domain socket */
73   FH_FIFO    = 0x08000000,      /* File is FIFO */
74   FH_HASACLS = 0x40000000,      /* True if fs of file has ACLS */
75
76   /* Device flags */
77
78   /* Slow devices */
79   FH_CONSOLE = 0x00000001,      /* is a console */
80   FH_CONIN   = 0x00000002,      /* console input */
81   FH_CONOUT  = 0x00000003,      /* console output */
82   FH_TTYM    = 0x00000004,      /* is a tty master */
83   FH_TTYS    = 0x00000005,      /* is a tty slave */
84   FH_PTYM    = 0x00000006,      /* is a pty master */
85   FH_SERIAL  = 0x00000007,      /* is a serial port */
86   FH_PIPE    = 0x00000008,      /* is a pipe */
87   FH_PIPER   = 0x00000009,      /* read end of a pipe */
88   FH_PIPEW   = 0x0000000a,      /* write end of a pipe */
89   FH_SOCKET  = 0x0000000b,      /* is a socket */
90   FH_WINDOWS = 0x0000000c,      /* is a window */
91   FH_SLOW    = 0x00000010,      /* "slow" device if below this */
92
93   /* Fast devices */
94   FH_DISK    = 0x00000010,      /* is a disk */
95   FH_FLOPPY  = 0x00000011,      /* is a floppy */
96   FH_TAPE    = 0x00000012,      /* is a tape */
97   FH_NULL    = 0x00000013,      /* is the null device */
98   FH_ZERO    = 0x00000014,      /* is the zero device */
99   FH_RANDOM  = 0x00000015,      /* is a random device */
100   FH_MEM     = 0x00000016,      /* is a mem device */
101   FH_CLIPBOARD = 0x00000017, /* is a clipbaord device */
102   FH_OSS_DSP = 0x00000018,      /* is a dsp audio device */
103
104   FH_NDEV    = 0x00000019,      /* Maximum number of devices */
105   FH_DEVMASK = 0x00000fff,      /* devices live here */
106   FH_BAD     = 0xffffffff
107 };
108
109 #define FHDEVN(n)       ((n) & FH_DEVMASK)
110 #define FHISSETF(x)     __ISSETF (this, x, FH)
111 #define FHSETF(x)       __SETF (this, x, FH)
112 #define FHCLEARF(x)     __CLEARF (this, x, FH)
113 #define FHCONDSETF(n, x) __CONDSETF(n, this, x, FH)
114
115 #define FHSTATOFF       0
116
117 extern const char *windows_device_names[];
118 extern struct __cygwin_perfile *perfile_table;
119 #define __fmode (*(user_data->fmode_ptr))
120
121 class select_record;
122 class path_conv;
123 class fhandler_disk_file;
124
125 enum bg_check_types
126 {
127   bg_error = -1,
128   bg_eof = 0,
129   bg_ok = 1,
130   bg_signalled = 2
131 };
132
133 enum executable_states
134 {
135   is_executable,
136   not_executable,
137   dont_care_if_executable,
138   dont_know_if_executable
139 };
140
141 class fhandler_base
142 {
143 private:
144   DWORD status;
145 public:
146   int cb;
147 private:
148   int access;
149   HANDLE io_handle;
150
151   unsigned long namehash;       /* hashed filename, used as inode num */
152
153 protected:
154   /* Full unix path name of this file */
155   /* File open flags from open () and fcntl () calls */
156   int openflags;
157
158   char *rabuf;          /* used for crlf conversion in text files */
159   size_t ralen;
160   size_t raixget;
161   size_t raixput;
162   size_t rabuflen;
163
164   char *unix_path_name;
165   char *win32_path_name;
166   DWORD open_status;
167
168 public:
169   void set_name (const char * unix_path, const char * win32_path = NULL,
170                  int unit = 0);
171
172   virtual fhandler_base& operator =(fhandler_base &x);
173   fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
174   virtual ~fhandler_base ();
175
176   /* Non-virtual simple accessor functions. */
177   void set_io_handle (HANDLE x) { io_handle = x; }
178
179   void set_cb (size_t size) { cb = size; }
180   DWORD get_device () { return status & FH_DEVMASK; }
181   virtual int get_unit () { return 0; }
182   virtual BOOL is_slow () { return get_device () < FH_SLOW; }
183
184   int get_access () { return access; }
185   void set_access (int x) { access = x; }
186
187   int get_async () { return FHISSETF (ASYNC); }
188   void set_async (int x) { FHCONDSETF (x, ASYNC); }
189
190   int get_flags () { return openflags; }
191   void set_flags (int x) { openflags = x; }
192
193   int get_w_binary () { return FHISSETF (WBINARY); }
194   int get_r_binary () { return FHISSETF (RBINARY); }
195
196   int get_w_binset () { return FHISSETF (WBINSET); }
197   int get_r_binset () { return FHISSETF (RBINSET); }
198
199   void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
200   void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
201   void clear_w_binary () {FHCLEARF (WBINARY); FHCLEARF (WBINSET); }
202   void clear_r_binary () {FHCLEARF (RBINARY); FHCLEARF (RBINSET); }
203   void set_open_status () {open_status = status;}
204   DWORD get_open_status () {return open_status;}
205   void reset_to_open_binmode ()
206   {
207     status = status & ~(FH_WBINARY | FH_WBINSET | FH_RBINARY | FH_RBINSET);
208     status = status | ((FH_WBINARY | FH_WBINSET | FH_RBINARY | FH_RBINSET)
209                        & open_status);
210   }
211
212   int get_default_fmode (int flags);
213
214   int get_r_no_interrupt () { return FHISSETF (NOEINTR); }
215   void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); }
216
217   int get_close_on_exec () { return FHISSETF (CLOEXEC); }
218   int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); }
219
220   void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); }
221   int get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); }
222
223   int get_need_fork_fixup () { return FHISSETF (FFIXUP); }
224   void set_need_fork_fixup () { FHSETF (FFIXUP); }
225
226   virtual void set_close_on_exec (int val);
227
228   virtual void fixup_before_fork_exec (DWORD) {}
229   virtual void fixup_after_fork (HANDLE);
230   virtual void fixup_after_exec (HANDLE) {}
231
232   int get_symlink_p () { return FHISSETF (SYMLINK); }
233   void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); }
234   void set_symlink_p () { FHSETF (SYMLINK); }
235
236   int get_socket_p () { return FHISSETF (LOCAL); }
237   void set_socket_p (int val) { FHCONDSETF (val, LOCAL); }
238   void set_socket_p () { FHSETF (LOCAL); }
239
240   int get_execable_p () { return FHISSETF (EXECABL); }
241   void set_execable_p (executable_states val)
242   {
243     FHCONDSETF (val == is_executable, EXECABL);
244   }
245   void set_execable_p () { FHSETF (EXECABL); }
246
247   int get_append_p () { return FHISSETF (APPEND); }
248   void set_append_p (int val) { FHCONDSETF (val, APPEND); }
249   void set_append_p () { FHSETF (APPEND); }
250
251   int get_readahead_valid () { return raixget < ralen; }
252   int puts_readahead (const char *s, size_t len = (size_t) -1);
253   int put_readahead (char value);
254
255   int get_readahead ();
256   int peek_readahead (int queryput = 0);
257
258   int eat_readahead (int n);
259
260   void set_readahead_valid (int val, int ch = -1);
261
262   int get_readahead_into_buffer (char *buf, size_t buflen);
263
264   int has_acls () { return FHISSETF (HASACLS); }
265   void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
266
267   int no_free_names () { return FHISSETF (NOFRNAME); }
268   void set_no_free_names (int val) { FHCONDSETF (val, NOFRNAME); }
269   void set_no_free_names () { FHSETF (NOFRNAME); }
270
271   const char *get_name () { return unix_path_name; }
272   const char *get_win32_name () { return win32_path_name; }
273   unsigned long get_namehash () { return namehash; }
274
275   virtual void hclose (HANDLE h) {CloseHandle (h);}
276   virtual void set_inheritance (HANDLE &h, int not_inheriting,
277                                 const char *name = NULL);
278
279   /* fixup fd possibly non-inherited handles after fork */
280   void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
281
282   /* Potentially overridden virtual functions. */
283   virtual int open (const char *, int flags, mode_t mode = 0)
284   {
285     return open (flags, mode);
286   }
287   virtual int open (int flags, mode_t mode = 0);
288   virtual int close ();
289   virtual int fstat (struct stat *buf) { return stat_dev (get_device (), get_unit (), get_namehash (), buf); }
290   virtual int ioctl (unsigned int cmd, void *);
291   virtual int fcntl (int cmd, void *);
292   virtual char const * ttyname () { return get_name(); }
293   virtual int read (void *ptr, size_t len);
294   virtual int write (const void *ptr, size_t len);
295   virtual off_t lseek (off_t offset, int whence);
296   virtual int lock (int, struct flock *);
297   virtual void dump ();
298   virtual int dup (fhandler_base *child);
299
300   virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access,
301                        int flags, off_t off);
302   virtual int munmap (HANDLE h, caddr_t addr, size_t len);
303   virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
304   virtual BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
305                                       DWORD size, void *address);
306
307   void *operator new (size_t, void *p) {return p;}
308
309   virtual void init (HANDLE, DWORD, mode_t);
310
311   virtual int tcflush (int);
312   virtual int tcsendbreak (int);
313   virtual int tcdrain ();
314   virtual int tcflow (int);
315   virtual int tcsetattr (int a, const struct termios *t);
316   virtual int tcgetattr (struct termios *t);
317   virtual int tcsetpgrp (const pid_t pid);
318   virtual int tcgetpgrp ();
319   virtual int is_tty () { return 0; }
320   virtual BOOL is_device () { return TRUE; }
321   virtual char *ptsname () { return NULL;}
322   virtual class fhandler_socket *is_socket () { return 0; }
323   virtual class fhandler_console *is_console () { return 0; }
324   virtual int is_windows () {return 0; }
325
326   virtual int raw_read (void *ptr, size_t ulen);
327   virtual int raw_write (const void *ptr, size_t ulen);
328
329   /* Virtual accessor functions to hide the fact
330      that some fd's have two handles. */
331   virtual HANDLE& get_handle () { return io_handle; }
332   virtual HANDLE& get_io_handle () { return io_handle; }
333   virtual HANDLE& get_output_handle () { return io_handle; }
334   virtual BOOL hit_eof () {return FALSE;}
335   virtual select_record *select_read (select_record *s);
336   virtual select_record *select_write (select_record *s);
337   virtual select_record *select_except (select_record *s);
338   virtual int ready_for_read (int fd, DWORD howlong, int ignra);
339   virtual const char * get_native_name ()
340   {
341     return windows_device_names[FHDEVN (status)];
342   }
343   virtual bg_check_types bg_check (int) {return bg_ok;}
344   void clear_readahead ()
345   {
346     raixput = raixget = ralen = rabuflen = 0;
347     rabuf = NULL;
348   }
349   void operator delete (void *);
350 };
351
352 class fhandler_socket: public fhandler_base
353 {
354 private:
355   int addr_family;
356   int connect_secret [4];
357   HANDLE secret_event;
358   struct _WSAPROTOCOL_INFOA *prot_info_ptr;
359
360 public:
361   fhandler_socket (const char *name = 0);
362   ~fhandler_socket ();
363   int get_socket () { return (int) get_handle(); }
364   fhandler_socket * is_socket () { return this; }
365   int write (const void *ptr, size_t len);
366   int read (void *ptr, size_t len);
367   int ioctl (unsigned int cmd, void *);
368   int fcntl (int cmd, void *);
369   off_t lseek (off_t, int) { return 0; }
370   int close ();
371   void hclose (HANDLE) {close ();}
372   int dup (fhandler_base *child);
373
374   virtual void fixup_before_fork_exec (DWORD);
375   void fixup_after_fork (HANDLE);
376   void fixup_after_exec (HANDLE parent) { fixup_after_fork (parent); }
377
378   select_record *select_read (select_record *s);
379   select_record *select_write (select_record *s);
380   select_record *select_except (select_record *s);
381   int ready_for_read (int fd, DWORD howlong, int ignra);
382   int get_addr_family () {return addr_family;}
383   void set_addr_family (int af) {addr_family = af;}
384   void set_connect_secret ();
385   void get_connect_secret (char*);
386   HANDLE create_secret_event (int *secret = NULL);
387   int check_peer_secret_event (struct sockaddr_in *peer, int *secret = NULL);
388   void close_secret_event ();
389 };
390
391 class fhandler_pipe: public fhandler_base
392 {
393 public:
394   fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
395   off_t lseek (off_t offset, int whence);
396   /* This strange test is due to the fact that we can't rely on
397      Windows shells to "do the right thing" with pipes.  Apparently
398      the can keep one end of the pipe open when it shouldn't be. */
399   BOOL is_slow () {return os_being_run == winNT;}
400   select_record *select_read (select_record *s);
401   select_record *select_write (select_record *s);
402   select_record *select_except (select_record *s);
403   int ready_for_read (int fd, DWORD howlong, int ignra);
404 };
405
406 class fhandler_dev_raw: public fhandler_base
407 {
408 protected:
409   char *devbuf;
410   size_t devbufsiz;
411   size_t devbufstart;
412   size_t devbufend;
413   int eom_detected    : 1;
414   int eof_detected    : 1;
415   int lastblk_to_read : 1;
416   int is_writing      : 1;
417   int has_written     : 1;
418   int varblkop        : 1;
419   int unit;
420
421   virtual void clear (void);
422   virtual int writebuf (void);
423
424   /* returns not null, if `win_error' determines an end of media condition */
425   virtual int is_eom(int win_error) = 0;
426   /* returns not null, if `win_error' determines an end of file condition */
427   virtual int is_eof(int win_error) = 0;
428
429   fhandler_dev_raw (DWORD dev, const char *name, int unit);
430
431 public:
432   ~fhandler_dev_raw (void);
433
434   int open (const char *path, int flags, mode_t mode = 0);
435   int close (void);
436
437   int raw_read (void *ptr, size_t ulen);
438   int raw_write (const void *ptr, size_t ulen);
439
440   int fstat (struct stat *buf);
441
442   int dup (fhandler_base *child);
443
444   int ioctl (unsigned int cmd, void *buf);
445
446   void fixup_after_fork (HANDLE);
447   void fixup_after_exec (HANDLE parent) { fixup_after_fork (parent); }
448 };
449
450 class fhandler_dev_floppy: public fhandler_dev_raw
451 {
452 protected:
453   virtual int is_eom (int win_error);
454   virtual int is_eof (int win_error);
455
456 public:
457   fhandler_dev_floppy (const char *name, int unit);
458
459   virtual int open (const char *path, int flags, mode_t mode = 0);
460   virtual int close (void);
461
462   virtual off_t lseek (off_t offset, int whence);
463
464   virtual int ioctl (unsigned int cmd, void *buf);
465 };
466
467 class fhandler_dev_tape: public fhandler_dev_raw
468 {
469   int norewind;
470   int lasterr;
471
472 protected:
473   virtual void clear (void);
474
475   virtual int is_eom (int win_error);
476   virtual int is_eof (int win_error);
477
478 public:
479   fhandler_dev_tape (const char *name, int unit);
480
481   virtual int open (const char *path, int flags, mode_t mode = 0);
482   virtual int close (void);
483
484   virtual off_t lseek (off_t offset, int whence);
485
486   virtual int fstat (struct stat *buf);
487
488   virtual int dup (fhandler_base *child);
489
490   virtual int ioctl (unsigned int cmd, void *buf);
491
492 private:
493   int tape_write_marks (int marktype, DWORD len);
494   int tape_get_pos (unsigned long *ret);
495   int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
496   int tape_erase (int mode);
497   int tape_prepare (int action);
498   BOOLEAN tape_get_feature (DWORD parm);
499   int tape_get_blocksize (long *min, long *def, long *max, long *cur);
500   int tape_set_blocksize (long count);
501   int tape_status (struct mtget *get);
502   int tape_compression (long count);
503 };
504
505 /* Standard disk file */
506
507 class fhandler_disk_file: public fhandler_base
508 {
509 public:
510   fhandler_disk_file (const char *name);
511
512   int open (const char *path, int flags, mode_t mode = 0);
513   int open (path_conv& real_path, int flags, mode_t mode);
514   int close ();
515   int lock (int, struct flock *);
516   BOOL is_device () { return FALSE; }
517   int fstat (struct stat *buf);
518
519   HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
520   int munmap (HANDLE h, caddr_t addr, size_t len);
521   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
522   BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
523                               DWORD size, void *address);
524 };
525
526 class fhandler_serial: public fhandler_base
527 {
528 private:
529   unsigned int vmin_;                   /* from termios */
530   unsigned int vtime_;                  /* from termios */
531   pid_t pgrp_;
532
533 public:
534   int overlapped_armed;
535   OVERLAPPED io_status;
536
537   /* Constructor */
538   fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
539
540   int open (const char *path, int flags, mode_t mode);
541   int close ();
542   void init (HANDLE h, DWORD a, mode_t flags);
543   void overlapped_setup ();
544   int dup (fhandler_base *child);
545   int raw_read (void *ptr, size_t ulen);
546   int raw_write (const void *ptr, size_t ulen);
547   int tcsendbreak (int);
548   int tcdrain ();
549   int tcflow (int);
550   int tcsetattr (int a, const struct termios *t);
551   int tcgetattr (struct termios *t);
552   off_t lseek (off_t, int) { return 0; }
553   int tcflush (int);
554   void dump ();
555   int is_tty () { return 1; }
556   void fixup_after_fork (HANDLE parent);
557   void fixup_after_exec (HANDLE);
558
559   /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
560      don't use it for permissions checking.  fhandler_tty_slave does
561      permission checking on pgrps.  */
562   virtual int tcgetpgrp () { return pgrp_; }
563   virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
564   select_record *select_read (select_record *s);
565   select_record *select_write (select_record *s);
566   select_record *select_except (select_record *s);
567   int ready_for_read (int fd, DWORD howlong, int ignra);
568 };
569
570 #define acquire_output_mutex(ms) \
571   __acquire_output_mutex (__PRETTY_FUNCTION__, __LINE__, ms);
572
573 #define release_output_mutex() \
574   __release_output_mutex (__PRETTY_FUNCTION__, __LINE__);
575
576 class tty;
577 class tty_min;
578 class fhandler_termios: public fhandler_base
579 {
580 protected:
581   HANDLE output_handle;
582   virtual void doecho (const void *, DWORD) {};
583   virtual int accept_input () {return 1;};
584 public:
585   tty_min *tc;
586   fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
587   fhandler_base (dev, name, unit)
588   {
589     set_need_fork_fixup ();
590   }
591   HANDLE& get_output_handle () { return output_handle; }
592   int line_edit (const char *rptr, int nread, int always_accept = 0);
593   void set_output_handle (HANDLE h) { output_handle = h; }
594   void tcinit (tty_min *this_tc, int force = FALSE);
595   virtual int is_tty () { return 1; }
596   int tcgetpgrp ();
597   int tcsetpgrp (int pid);
598   bg_check_types bg_check (int sig);
599   virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
600   virtual void __release_output_mutex (const char *fn, int ln) {}
601   void fixup_after_fork (HANDLE);
602   void fixup_after_exec (HANDLE parent) { fixup_after_fork (parent); }
603   void echo_erase (int force = 0);
604 };
605
606 enum ansi_intensity
607 {
608   INTENSITY_INVISIBLE,
609   INTENSITY_DIM,
610   INTENSITY_NORMAL,
611   INTENSITY_BOLD
612 };
613
614 #define normal 1
615 #define gotesc 2
616 #define gotsquare 3
617 #define gotarg1 4
618 #define gotrsquare 5
619 #define gotcommand 6
620 #define gettitle 7
621 #define eattitle 8
622 #define MAXARGS 10
623
624 /* This is a input and output console handle */
625 class fhandler_console: public fhandler_termios
626 {
627 private:
628
629   WORD default_color, underline_color, dim_color;
630
631   /* Used to determine if an input keystroke should be modified with META. */
632   int meta_mask;
633
634 /* Output state */
635   int state_;
636   int args_[MAXARGS];
637   int nargs_;
638   unsigned rarg;
639   BOOL saw_question_mark;
640
641   char my_title_buf [TITLESIZE + 1];
642
643   WORD current_win32_attr;
644   ansi_intensity intensity;
645   BOOL underline, blink, reverse;
646   WORD fg, bg;
647
648   /* saved cursor coordinates */
649   int savex, savey;
650
651   /* saved screen */
652   COORD savebufsiz;
653   PCHAR_INFO savebuf;
654
655   struct
656     {
657       short Top, Bottom;
658     } scroll_region;
659   struct
660     {
661       SHORT winTop;
662       SHORT winBottom;
663       COORD dwWinSize;
664       COORD dwBufferSize;
665       COORD dwCursorPosition;
666       WORD wAttributes;
667     } info;
668
669   COORD dwLastCursorPosition;
670   DWORD dwLastButtonState;
671   int nModifiers;
672
673   BOOL insert_mode;
674   BOOL use_mouse;
675   BOOL raw_win32_keyboard_mode;
676
677 /* Output calls */
678   void set_default_attr ();
679   WORD get_win32_attr ();
680
681   BOOL fillin_info ();
682   void clear_screen (int, int, int, int);
683   void scroll_screen (int, int, int, int, int, int);
684   void cursor_set (BOOL, int, int);
685   void cursor_get (int *, int *);
686   void cursor_rel (int, int);
687   const unsigned char * write_normal (unsigned const char*, unsigned const char *);
688   void char_command (char);
689   BOOL set_raw_win32_keyboard_mode (BOOL);
690   int output_tcsetattr (int a, const struct termios *t);
691
692 /* Input calls */
693   int igncr_enabled ();
694   int input_tcsetattr (int a, const struct termios *t);
695   void set_cursor_maybe ();
696
697 public:
698
699   fhandler_console (const char *name);
700
701   fhandler_console* is_console () { return this; }
702
703   int open (const char *path, int flags, mode_t mode = 0);
704
705   int write (const void *ptr, size_t len);
706   void doecho (const void *str, DWORD len) { (void) write (str, len); }
707   int read (void *ptr, size_t len);
708   int close ();
709
710   int tcflush (int);
711   int tcsetattr (int a, const struct termios *t);
712   int tcgetattr (struct termios *t);
713
714   /* Special dup as we must dup two handles */
715   int dup (fhandler_base *child);
716
717   int ioctl (unsigned int cmd, void *);
718   void init (HANDLE, DWORD, mode_t);
719   bool mouse_aware () {return use_mouse;}
720
721   select_record *select_read (select_record *s);
722   select_record *select_write (select_record *s);
723   select_record *select_except (select_record *s);
724   int ready_for_read (int fd, DWORD howlong, int ignra);
725   void fixup_after_exec (HANDLE);
726   void set_close_on_exec (int val);
727   void fixup_after_fork (HANDLE parent);
728   void set_input_state ();
729 };
730
731 class fhandler_tty_common: public fhandler_termios
732 {
733 public:
734   fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
735     fhandler_termios (dev, name, unit),
736     ttynum (unit)
737   {
738     // nothing to do
739   }
740   HANDLE output_done_event;     // Raised by master when tty's output buffer
741                                 // written. Write status in tty::write_retval.
742   HANDLE ioctl_request_event;   // Raised by slave to perform ioctl() request.
743                                 // Ioctl() request in tty::cmd/arg.
744   HANDLE ioctl_done_event;      // Raised by master on ioctl() completion.
745                                 // Ioctl() status in tty::ioctl_retval.
746   HANDLE output_mutex, input_mutex;
747   HANDLE input_available_event;
748   HANDLE inuse;                 // used to indicate that a tty is in use
749
750
751   DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
752   void __release_output_mutex (const char *fn, int ln);
753
754   int ttynum;                   // Master tty num.
755   virtual int dup (fhandler_base *child);
756
757   tty *get_ttyp () { return (tty *)tc; }
758   int get_unit () { return ttynum; }
759
760   int close ();
761   void set_close_on_exec (int val);
762   void fixup_after_fork (HANDLE parent);
763   select_record *select_read (select_record *s);
764   select_record *select_write (select_record *s);
765   select_record *select_except (select_record *s);
766   int ready_for_read (int fd, DWORD howlong, int ignra);
767 };
768
769 class fhandler_tty_slave: public fhandler_tty_common
770 {
771 public:
772   /* Constructor */
773   fhandler_tty_slave (const char *name);
774   fhandler_tty_slave (int, const char *name);
775
776   int open (const char *path, int flags, mode_t mode = 0);
777   int write (const void *ptr, size_t len);
778   int read (void *ptr, size_t len);
779   void init (HANDLE, DWORD, mode_t);
780
781   int tcsetattr (int a, const struct termios *t);
782   int tcgetattr (struct termios *t);
783   int tcflush (int);
784   int ioctl (unsigned int cmd, void *);
785
786   off_t lseek (off_t, int) { return 0; }
787   select_record *select_read (select_record *s);
788   int ready_for_read (int fd, DWORD howlong, int ignra);
789 };
790
791 class fhandler_pty_master: public fhandler_tty_common
792 {
793   int pktmode;                  // non-zero if pty in a packet mode.
794 public:
795   int need_nl;                  // Next read should start with \n
796
797   /* Constructor */
798   fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
799
800   int process_slave_output (char *buf, size_t len, int pktmode_on);
801   void doecho (const void *str, DWORD len);
802   int accept_input ();
803   int open (const char *path, int flags, mode_t mode = 0);
804   int write (const void *ptr, size_t len);
805   int read (void *ptr, size_t len);
806   int close ();
807
808   int tcsetattr (int a, const struct termios *t);
809   int tcgetattr (struct termios *t);
810   int tcflush (int);
811   int ioctl (unsigned int cmd, void *);
812
813   off_t lseek (off_t, int) { return 0; }
814   char *ptsname ();
815
816   void set_close_on_exec (int val);
817   BOOL hit_eof ();
818 };
819
820 class fhandler_tty_master: public fhandler_pty_master
821 {
822 public:
823   /* Constructor */
824   fhandler_tty_master (const char *name, int unit);
825   fhandler_console *console;    // device handler to perform real i/o.
826   HANDLE hThread;               // process_output thread handle.
827
828   int init (int);
829   int init_console ();
830   void fixup_after_fork (HANDLE parent);
831   void fixup_after_exec (HANDLE);
832 };
833
834 class fhandler_dev_null: public fhandler_base
835 {
836 public:
837   fhandler_dev_null (const char *name);
838
839   void dump ();
840   select_record *select_read (select_record *s);
841   select_record *select_write (select_record *s);
842   select_record *select_except (select_record *s);
843 };
844
845 class fhandler_dev_zero: public fhandler_base
846 {
847 public:
848   fhandler_dev_zero (const char *name);
849   int open (const char *path, int flags, mode_t mode = 0);
850   int write (const void *ptr, size_t len);
851   int read (void *ptr, size_t len);
852   off_t lseek (off_t offset, int whence);
853   int close (void);
854
855   void dump ();
856 };
857
858 class fhandler_dev_random: public fhandler_base
859 {
860 protected:
861   int unit;
862   HCRYPTPROV crypt_prov;
863   long pseudo;
864
865   BOOL crypt_gen_random (void *ptr, size_t len);
866   int pseudo_write (const void *ptr, size_t len);
867   int pseudo_read (void *ptr, size_t len);
868
869 public:
870   fhandler_dev_random (const char *name, int unit);
871   int get_unit () { return unit; }
872   int open (const char *path, int flags, mode_t mode = 0);
873   int write (const void *ptr, size_t len);
874   int read (void *ptr, size_t len);
875   off_t lseek (off_t offset, int whence);
876   int close (void);
877   int dup (fhandler_base *child);
878
879   void dump ();
880 };
881
882 class fhandler_dev_mem: public fhandler_base
883 {
884 protected:
885   int unit;
886   DWORD mem_size;
887   DWORD pos;
888
889 public:
890   fhandler_dev_mem (const char *name, int unit);
891   ~fhandler_dev_mem (void);
892
893   int open (const char *path, int flags, mode_t mode = 0);
894   int write (const void *ptr, size_t ulen);
895   int read (void *ptr, size_t ulen);
896   off_t lseek (off_t offset, int whence);
897   int close (void);
898   int fstat (struct stat *buf);
899   int dup (fhandler_base *child);
900
901   HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
902   int munmap (HANDLE h, caddr_t addr, size_t len);
903   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
904   BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
905                               DWORD size, void *address);
906
907   void dump ();
908 } ;
909
910 class fhandler_dev_clipboard: public fhandler_base
911 {
912 public:
913   fhandler_dev_clipboard (const char *name);
914   int is_windows (void) { return 1; }
915   int open (const char *path, int flags, mode_t mode = 0);
916   int write (const void *ptr, size_t len);
917   int read (void *ptr, size_t len);
918   off_t lseek (off_t offset, int whence);
919   int close (void);
920
921   int dup (fhandler_base *child);
922
923   void dump ();
924
925 private:
926   off_t pos;
927   void *membuffer;
928   size_t msize;
929   BOOL eof;
930 };
931
932 class fhandler_windows: public fhandler_base
933 {
934 private:
935   HWND hWnd_;   // the window whose messages are to be retrieved by read() call
936   int method_;  // write method (Post or Send)
937 public:
938   fhandler_windows (const char *name = 0);
939   int is_windows (void) { return 1; }
940   int open (const char *path, int flags, mode_t mode = 0);
941   int write (const void *ptr, size_t len);
942   int read (void *ptr, size_t len);
943   int ioctl (unsigned int cmd, void *);
944   off_t lseek (off_t, int) { return 0; }
945   int close (void) { return 0; }
946
947   void set_close_on_exec (int val);
948   void fixup_after_fork (HANDLE parent);
949   select_record *select_read (select_record *s);
950   select_record *select_write (select_record *s);
951   select_record *select_except (select_record *s);
952   int ready_for_read (int fd, DWORD howlong, int ignra);
953 };
954
955 class fhandler_dev_dsp : public fhandler_base
956 {
957 private:
958   int audioformat_;
959   int audiofreq_;
960   int audiobits_;
961   int audiochannels_;
962   bool setupwav(const char *pData, int nBytes);
963   
964 public:
965   fhandler_dev_dsp (const char *name = 0);
966   ~fhandler_dev_dsp();
967
968   int open (const char *path, int flags, mode_t mode = 0);
969   int write (const void *ptr, size_t len);
970   int read (void *ptr, size_t len);
971   int ioctl (unsigned int cmd, void *);
972   off_t lseek (off_t, int);
973   int close (void);
974   int dup (fhandler_base * child);
975   void dump (void);
976 };
977
978 #if 0
979 /* You can't do this */
980 typedef union
981 {
982   fhandler_normal normal;
983   fhandler_dev_null dev_null;
984   fhandler bare;
985   fhandler_serial tty;
986 } fhandler_union;
987 #else
988 #define fhandler_union fhandler_console
989 #endif
990 struct select_record
991 {
992   int fd;
993   HANDLE h;
994   fhandler_base *fh;
995   BOOL saw_error;
996   BOOL windows_handle;
997   BOOL read_ready, write_ready, except_ready;
998   BOOL read_selected, write_selected, except_selected;
999   int (*startup) (select_record *me, class select_stuff *stuff);
1000   int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
1001                fd_set *exceptfds);
1002   int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
1003                  fd_set *exceptfds);
1004   void (*cleanup) (select_record *me, class select_stuff *stuff);
1005   struct select_record *next;
1006
1007   select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
1008                  fh (in_fh), saw_error (0), windows_handle (0),
1009                  read_ready (0), write_ready (0), except_ready (0),
1010                  read_selected (0), write_selected (0), except_selected (0),
1011                  startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
1012                  next (NULL) {}
1013 };
1014
1015 class select_stuff
1016 {
1017 public:
1018   ~select_stuff ();
1019   select_stuff (): always_ready (0), windows_used (0), start (0)
1020   {
1021     memset (device_specific, 0, sizeof (device_specific));
1022   }
1023   BOOL always_ready, windows_used;
1024   select_record start;
1025   void *device_specific[FH_NDEV];
1026
1027   int test_and_set (int i, fd_set *readfds, fd_set *writefds,
1028                      fd_set *exceptfds);
1029   int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
1030   int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
1031 };
1032
1033 int __stdcall set_console_state_for_spawn ();
1034
1035 #endif /* _FHANDLER_H_ */