OSDN Git Service

* fhandler.h (fhandler_tty_slave): Declare new methods.
[pf3gnuchains/pf3gnuchains4x.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
92   FH_SLOW    = 0x00000010,      /* "slow" device if below this */
93
94   /* Fast devices */
95   FH_DISK    = 0x00000010,      /* is a disk */
96   FH_FLOPPY  = 0x00000011,      /* is a floppy */
97   FH_TAPE    = 0x00000012,      /* is a tape */
98   FH_NULL    = 0x00000013,      /* is the null device */
99   FH_ZERO    = 0x00000014,      /* is the zero device */
100   FH_RANDOM  = 0x00000015,      /* is a random device */
101   FH_MEM     = 0x00000016,      /* is a mem device */
102   FH_CLIPBOARD = 0x00000017, /* is a clipbaord device */
103
104   FH_NDEV    = 0x00000018,      /* 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   /* Full unix path name of this file */
154   /* File open flags from open () and fcntl () calls */
155   int openflags_;
156
157 protected:
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
167 public:
168   void set_name (const char * unix_path, const char * win32_path = NULL,
169                  int unit = 0);
170
171   virtual fhandler_base& operator =(fhandler_base &x);
172   fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
173   virtual ~fhandler_base ();
174
175   /* Non-virtual simple accessor functions. */
176   void set_io_handle (HANDLE x) { io_handle = x; }
177
178   void set_cb (size_t size) { cb = size; }
179   DWORD get_device () { return status & FH_DEVMASK; }
180   virtual int get_unit () { return 0; }
181   virtual BOOL is_slow () { return get_device () < FH_SLOW; }
182
183   int get_access () { return access_; }
184   void set_access (int x) { access_ = x; }
185
186   int get_async () { return FHISSETF (ASYNC); }
187   void set_async (int x) { FHCONDSETF (x, ASYNC); }
188
189   int get_flags () { return openflags_; }
190   void set_flags (int x) { openflags_ = x; }
191
192   int get_w_binary () { return FHISSETF (WBINARY); }
193   int get_r_binary () { return FHISSETF (RBINARY); }
194
195   int get_w_binset () { return FHISSETF (WBINSET); }
196   int get_r_binset () { return FHISSETF (RBINSET); }
197
198   void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
199   void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
200
201   int get_default_fmode (int flags);
202
203   int get_r_no_interrupt () { return FHISSETF (NOEINTR); }
204   void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); }
205
206   int get_close_on_exec () { return FHISSETF (CLOEXEC); }
207   int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); }
208
209   void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); }
210   int get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); }
211
212   int get_need_fork_fixup () { return FHISSETF (FFIXUP); }
213   void set_need_fork_fixup () { FHSETF (FFIXUP); }
214
215   virtual void set_close_on_exec (int val);
216
217   virtual void fixup_before_fork_exec (DWORD) {}
218   virtual void fixup_after_fork (HANDLE);
219   virtual void fixup_after_exec (HANDLE) {}
220
221   int get_symlink_p () { return FHISSETF (SYMLINK); }
222   void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); }
223   void set_symlink_p () { FHSETF (SYMLINK); }
224
225   int get_socket_p () { return FHISSETF (LOCAL); }
226   void set_socket_p (int val) { FHCONDSETF (val, LOCAL); }
227   void set_socket_p () { FHSETF (LOCAL); }
228
229   int get_execable_p () { return FHISSETF (EXECABL); }
230   void set_execable_p (executable_states val)
231   {
232     FHCONDSETF (val == is_executable, EXECABL);
233   }
234   void set_execable_p () { FHSETF (EXECABL); }
235
236   int get_append_p () { return FHISSETF (APPEND); }
237   void set_append_p (int val) { FHCONDSETF (val, APPEND); }
238   void set_append_p () { FHSETF (APPEND); }
239
240   int get_readahead_valid () { return raixget < ralen; }
241   int puts_readahead (const char *s, size_t len = (size_t) -1);
242   int put_readahead (char value);
243
244   int get_readahead ();
245   int peek_readahead (int queryput = 0);
246
247   int eat_readahead (int n);
248
249   void set_readahead_valid (int val, int ch = -1);
250
251   int get_readahead_into_buffer (char *buf, size_t buflen);
252
253   int has_acls () { return FHISSETF (HASACLS); }
254   void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
255
256   int no_free_names () { return FHISSETF (NOFRNAME); }
257   void set_no_free_names (int val) { FHCONDSETF (val, NOFRNAME); }
258   void set_no_free_names () { FHSETF (NOFRNAME); }
259
260   const char *get_name () { return unix_path_name_; }
261   const char *get_win32_name () { return win32_path_name_; }
262   unsigned long get_namehash () { return namehash_; }
263
264   virtual void hclose (HANDLE h) {CloseHandle (h);}
265   virtual void set_inheritance (HANDLE &h, int not_inheriting,
266                                 const char *name = NULL);
267
268   /* fixup fd possibly non-inherited handles after fork */
269   void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
270
271   /* Potentially overridden virtual functions. */
272   virtual int open (const char *, int flags, mode_t mode = 0)
273   {
274     return open (flags, mode);
275   }
276   virtual int open (int flags, mode_t mode = 0);
277   virtual int close ();
278   virtual int fstat (struct stat *buf) { return stat_dev (get_device (), get_unit (), get_namehash (), buf); }
279   virtual int ioctl (unsigned int cmd, void *);
280   virtual int fcntl (int cmd, void *);
281   virtual char const * ttyname () { return get_name(); }
282   virtual int read (void *ptr, size_t len);
283   virtual int write (const void *ptr, size_t len);
284   virtual off_t lseek (off_t offset, int whence);
285   virtual int lock (int, struct flock *);
286   virtual void dump ();
287   virtual int dup (fhandler_base *child);
288
289   virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access,
290                        int flags, off_t off);
291   virtual int munmap (HANDLE h, caddr_t addr, size_t len);
292   virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
293   virtual BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
294                                       DWORD size, void *address);
295
296   void *operator new (size_t, void *p) {return p;}
297
298   virtual void init (HANDLE, DWORD, mode_t);
299
300   virtual int tcflush (int);
301   virtual int tcsendbreak (int);
302   virtual int tcdrain ();
303   virtual int tcflow (int);
304   virtual int tcsetattr (int a, const struct termios *t);
305   virtual int tcgetattr (struct termios *t);
306   virtual int tcsetpgrp (const pid_t pid);
307   virtual int tcgetpgrp ();
308   virtual int is_tty () { return 0; }
309   virtual BOOL is_device () { return TRUE; }
310   virtual char *ptsname () { return NULL;}
311   virtual class fhandler_socket *is_socket () { return 0; }
312   virtual class fhandler_console *is_console () { return 0; }
313   virtual int is_windows () {return 0; }
314
315   virtual int raw_read (void *ptr, size_t ulen);
316   virtual int raw_write (const void *ptr, size_t ulen);
317
318   /* Virtual accessor functions to hide the fact
319      that some fd's have two handles. */
320   virtual HANDLE& get_handle () { return io_handle; }
321   virtual HANDLE& get_io_handle () { return io_handle; }
322   virtual HANDLE& get_output_handle () { return io_handle; }
323   virtual BOOL hit_eof () {return FALSE;}
324   virtual select_record *select_read (select_record *s);
325   virtual select_record *select_write (select_record *s);
326   virtual select_record *select_except (select_record *s);
327   virtual int ready_for_read (int fd, DWORD howlong, int ignra);
328   virtual const char * get_native_name ()
329   {
330     return windows_device_names[FHDEVN (status)];
331   }
332   virtual bg_check_types bg_check (int) {return bg_ok;}
333   void clear_readahead ()
334   {
335     raixput = raixget = ralen = rabuflen = 0;
336     rabuf = NULL;
337   }
338   void operator delete (void *);
339 };
340
341 class fhandler_socket: public fhandler_base
342 {
343 private:
344   int addr_family;
345   struct _WSAPROTOCOL_INFOA *prot_info_ptr;
346
347 public:
348   fhandler_socket (const char *name = 0);
349   ~fhandler_socket ();
350   int get_socket () { return (int) get_handle(); }
351   fhandler_socket * is_socket () { return this; }
352   int write (const void *ptr, size_t len);
353   int read (void *ptr, size_t len);
354   int ioctl (unsigned int cmd, void *);
355   int fcntl (int cmd, void *);
356   off_t lseek (off_t, int) { return 0; }
357   int close ();
358   void hclose (HANDLE) {close ();}
359   int dup (fhandler_base *child);
360
361   virtual void fixup_before_fork_exec (DWORD);
362   void fixup_after_fork (HANDLE);
363   void fixup_after_exec (HANDLE parent) { fixup_after_fork (parent); }
364
365   select_record *select_read (select_record *s);
366   select_record *select_write (select_record *s);
367   select_record *select_except (select_record *s);
368   int ready_for_read (int fd, DWORD howlong, int ignra);
369   int get_addr_family () {return addr_family;}
370   void set_addr_family (int af) {addr_family = af;}
371 };
372
373 class fhandler_pipe: public fhandler_base
374 {
375 public:
376   fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
377   off_t lseek (off_t offset, int whence);
378   /* This strange test is due to the fact that we can't rely on
379      Windows shells to "do the right thing" with pipes.  Apparently
380      the can keep one end of the pipe open when it shouldn't be. */
381   BOOL is_slow () {return os_being_run == winNT;}
382   select_record *select_read (select_record *s);
383   select_record *select_write (select_record *s);
384   select_record *select_except (select_record *s);
385   int ready_for_read (int fd, DWORD howlong, int ignra);
386 };
387
388 class fhandler_dev_raw: public fhandler_base
389 {
390 protected:
391   char *devbuf;
392   size_t devbufsiz;
393   size_t devbufstart;
394   size_t devbufend;
395   int eom_detected    : 1;
396   int eof_detected    : 1;
397   int lastblk_to_read : 1;
398   int is_writing      : 1;
399   int has_written     : 1;
400   int varblkop        : 1;
401   int unit;
402
403   virtual void clear (void);
404   virtual int writebuf (void);
405
406   /* returns not null, if `win_error' determines an end of media condition */
407   virtual int is_eom(int win_error) = 0;
408   /* returns not null, if `win_error' determines an end of file condition */
409   virtual int is_eof(int win_error) = 0;
410
411   fhandler_dev_raw (DWORD dev, const char *name, int unit);
412
413 public:
414   ~fhandler_dev_raw (void);
415
416   int open (const char *path, int flags, mode_t mode = 0);
417   int close (void);
418
419   int raw_read (void *ptr, size_t ulen);
420   int raw_write (const void *ptr, size_t ulen);
421
422   int fstat (struct stat *buf);
423
424   int dup (fhandler_base *child);
425
426   int ioctl (unsigned int cmd, void *buf);
427
428   void fixup_after_fork (HANDLE);
429   void fixup_after_exec (HANDLE parent) { fixup_after_fork (parent); }
430 };
431
432 class fhandler_dev_floppy: public fhandler_dev_raw
433 {
434 protected:
435   virtual int is_eom (int win_error);
436   virtual int is_eof (int win_error);
437
438 public:
439   fhandler_dev_floppy (const char *name, int unit);
440
441   virtual int open (const char *path, int flags, mode_t mode = 0);
442   virtual int close (void);
443
444   virtual off_t lseek (off_t offset, int whence);
445
446   virtual int ioctl (unsigned int cmd, void *buf);
447 };
448
449 class fhandler_dev_tape: public fhandler_dev_raw
450 {
451   int norewind;
452   int lasterr;
453
454 protected:
455   virtual void clear (void);
456
457   virtual int is_eom (int win_error);
458   virtual int is_eof (int win_error);
459
460 public:
461   fhandler_dev_tape (const char *name, int unit);
462
463   virtual int open (const char *path, int flags, mode_t mode = 0);
464   virtual int close (void);
465
466   virtual off_t lseek (off_t offset, int whence);
467
468   virtual int fstat (struct stat *buf);
469
470   virtual int dup (fhandler_base *child);
471
472   virtual int ioctl (unsigned int cmd, void *buf);
473
474 private:
475   int tape_write_marks (int marktype, DWORD len);
476   int tape_get_pos (unsigned long *ret);
477   int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
478   int tape_erase (int mode);
479   int tape_prepare (int action);
480   BOOLEAN tape_get_feature (DWORD parm);
481   int tape_get_blocksize (long *min, long *def, long *max, long *cur);
482   int tape_set_blocksize (long count);
483   int tape_status (struct mtget *get);
484   int tape_compression (long count);
485 };
486
487 /* Standard disk file */
488
489 class fhandler_disk_file: public fhandler_base
490 {
491 public:
492   fhandler_disk_file (const char *name);
493
494   int open (const char *path, int flags, mode_t mode = 0);
495   int open (path_conv& real_path, int flags, mode_t mode);
496   int close ();
497   int lock (int, struct flock *);
498   BOOL is_device () { return FALSE; }
499   int fstat (struct stat *buf);
500
501   HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
502   int munmap (HANDLE h, caddr_t addr, size_t len);
503   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
504   BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
505                               DWORD size, void *address);
506 };
507
508 class fhandler_serial: public fhandler_base
509 {
510 private:
511   unsigned int vmin_;                   /* from termios */
512   unsigned int vtime_;                  /* from termios */
513   pid_t pgrp_;
514
515 public:
516   int overlapped_armed;
517   OVERLAPPED io_status;
518
519   /* Constructor */
520   fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
521
522   int open (const char *path, int flags, mode_t mode);
523   int close ();
524   void init (HANDLE h, DWORD a, mode_t flags);
525   void overlapped_setup ();
526   int dup (fhandler_base *child);
527   int raw_read (void *ptr, size_t ulen);
528   int raw_write (const void *ptr, size_t ulen);
529   int tcsendbreak (int);
530   int tcdrain ();
531   int tcflow (int);
532   int tcsetattr (int a, const struct termios *t);
533   int tcgetattr (struct termios *t);
534   off_t lseek (off_t, int) { return 0; }
535   int tcflush (int);
536   void dump ();
537   int is_tty () { return 1; }
538   void fixup_after_fork (HANDLE parent);
539   void fixup_after_exec (HANDLE);
540
541   /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
542      don't use it for permissions checking.  fhandler_tty_slave does
543      permission checking on pgrps.  */
544   virtual int tcgetpgrp () { return pgrp_; }
545   virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
546   select_record *select_read (select_record *s);
547   select_record *select_write (select_record *s);
548   select_record *select_except (select_record *s);
549   int ready_for_read (int fd, DWORD howlong, int ignra);
550 };
551
552 #define acquire_output_mutex(ms) \
553   __acquire_output_mutex (__PRETTY_FUNCTION__, __LINE__, ms);
554
555 #define release_output_mutex() \
556   __release_output_mutex (__PRETTY_FUNCTION__, __LINE__);
557
558 class tty;
559 class tty_min;
560 class fhandler_termios: public fhandler_base
561 {
562 protected:
563   HANDLE output_handle;
564   virtual void doecho (const void *, DWORD) {};
565   virtual int accept_input () {return 1;};
566 public:
567   tty_min *tc;
568   fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
569   fhandler_base (dev, name, unit)
570   {
571     set_need_fork_fixup ();
572   }
573   HANDLE& get_output_handle () { return output_handle; }
574   int line_edit (const char *rptr, int nread, int always_accept = 0);
575   void set_output_handle (HANDLE h) { output_handle = h; }
576   void tcinit (tty_min *this_tc, int force = FALSE);
577   virtual int is_tty () { return 1; }
578   int tcgetpgrp ();
579   int tcsetpgrp (int pid);
580   void set_ctty (int ttynum, int flags);
581   bg_check_types bg_check (int sig);
582   virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
583   virtual void __release_output_mutex (const char *fn, int ln) {}
584   void fixup_after_fork (HANDLE);
585   void fixup_after_exec (HANDLE parent) { fixup_after_fork (parent); }
586 };
587
588 enum ansi_intensity
589 {
590   INTENSITY_INVISIBLE,
591   INTENSITY_DIM,
592   INTENSITY_NORMAL,
593   INTENSITY_BOLD
594 };
595
596 #define normal 1
597 #define gotesc 2
598 #define gotsquare 3
599 #define gotarg1 4
600 #define gotrsquare 5
601 #define gotcommand 6
602 #define gettitle 7
603 #define eattitle 8
604 #define MAXARGS 10
605
606 /* This is a input and output console handle */
607 class fhandler_console: public fhandler_termios
608 {
609 private:
610
611   WORD default_color, underline_color, dim_color;
612
613   /* Used to determine if an input keystroke should be modified with META. */
614   int meta_mask;
615
616 /* Output state */
617   int state_;
618   int args_[MAXARGS];
619   int nargs_;
620   unsigned rarg;
621   BOOL saw_question_mark;
622
623   char my_title_buf [TITLESIZE + 1];
624
625   WORD current_win32_attr;
626   ansi_intensity intensity;
627   BOOL underline, blink, reverse;
628   WORD fg, bg;
629
630   /* saved cursor coordinates */
631   int savex, savey;
632
633   struct
634     {
635       short Top, Bottom;
636     } scroll_region;
637   struct
638     {
639       SHORT winTop;
640       SHORT winBottom;
641       COORD dwWinSize;
642       COORD dwBufferSize;
643       COORD dwCursorPosition;
644       WORD wAttributes;
645     } info;
646
647   COORD dwLastCursorPosition;
648   DWORD dwLastButtonState;
649   int nModifiers;
650
651   BOOL use_mouse;
652   BOOL raw_win32_keyboard_mode;
653
654 /* Output calls */
655   void set_default_attr ();
656   WORD get_win32_attr ();
657
658   BOOL fillin_info ();
659   void clear_screen (int, int, int, int);
660   void scroll_screen (int, int, int, int, int, int);
661   void cursor_set (BOOL, int, int);
662   void cursor_get (int *, int *);
663   void cursor_rel (int, int);
664   const unsigned char * write_normal (unsigned const char*, unsigned const char *);
665   void char_command (char);
666   BOOL set_raw_win32_keyboard_mode (BOOL);
667   int output_tcsetattr (int a, const struct termios *t);
668
669 /* Input calls */
670   int igncr_enabled ();
671   int input_tcsetattr (int a, const struct termios *t);
672   void set_cursor_maybe ();
673
674 public:
675
676   fhandler_console (const char *name);
677
678   fhandler_console* is_console () { return this; }
679
680   int open (const char *path, int flags, mode_t mode = 0);
681
682   int write (const void *ptr, size_t len);
683   void doecho (const void *str, DWORD len) { (void) write (str, len); }
684   int read (void *ptr, size_t len);
685   int close ();
686
687   int tcflush (int);
688   int tcsetattr (int a, const struct termios *t);
689   int tcgetattr (struct termios *t);
690
691   /* Special dup as we must dup two handles */
692   int dup (fhandler_base *child);
693
694   int ioctl (unsigned int cmd, void *);
695   void init (HANDLE, DWORD, mode_t);
696   bool mouse_aware () {return use_mouse;}
697
698   select_record *select_read (select_record *s);
699   select_record *select_write (select_record *s);
700   select_record *select_except (select_record *s);
701   int ready_for_read (int fd, DWORD howlong, int ignra);
702   void fixup_after_exec (HANDLE);
703   void set_close_on_exec (int val);
704   void fixup_after_fork (HANDLE parent);
705   void set_input_state ();
706 };
707
708 class fhandler_tty_common: public fhandler_termios
709 {
710 public:
711   fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
712     fhandler_termios (dev, name, unit),
713     ttynum (unit)
714   {
715     // nothing to do
716   }
717   HANDLE output_done_event;     // Raised by master when tty's output buffer
718                                 // written. Write status in tty::write_retval.
719   HANDLE ioctl_request_event;   // Raised by slave to perform ioctl() request.
720                                 // Ioctl() request in tty::cmd/arg.
721   HANDLE ioctl_done_event;      // Raised by master on ioctl() completion.
722                                 // Ioctl() status in tty::ioctl_retval.
723   HANDLE output_mutex, input_mutex;
724   HANDLE input_available_event;
725   HANDLE inuse;                 // used to indicate that a tty is in use
726
727
728   DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
729   void __release_output_mutex (const char *fn, int ln);
730
731   int ttynum;                   // Master tty num.
732   virtual int dup (fhandler_base *child);
733
734   tty *get_ttyp () { return (tty *)tc; }
735   int get_unit () { return ttynum; }
736
737   int close ();
738   void set_close_on_exec (int val);
739   void fixup_after_fork (HANDLE parent);
740   select_record *select_read (select_record *s);
741   select_record *select_write (select_record *s);
742   select_record *select_except (select_record *s);
743   int ready_for_read (int fd, DWORD howlong, int ignra);
744 };
745
746 class fhandler_tty_slave: public fhandler_tty_common
747 {
748 public:
749   /* Constructor */
750   fhandler_tty_slave (const char *name);
751   fhandler_tty_slave (int, const char *name);
752
753   int open (const char *path, int flags, mode_t mode = 0);
754   int write (const void *ptr, size_t len);
755   int read (void *ptr, size_t len);
756   void init (HANDLE, DWORD, mode_t);
757
758   int tcsetattr (int a, const struct termios *t);
759   int tcgetattr (struct termios *t);
760   int tcflush (int);
761   int ioctl (unsigned int cmd, void *);
762
763   off_t lseek (off_t, int) { return 0; }
764   select_record *select_read (select_record *s);
765   int ready_for_read (int fd, DWORD howlong, int ignra);
766 };
767
768 class fhandler_pty_master: public fhandler_tty_common
769 {
770   int pktmode;                  // non-zero if pty in a packet mode.
771 public:
772   int need_nl;                  // Next read should start with \n
773
774   /* Constructor */
775   fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
776
777   int process_slave_output (char *buf, size_t len, int pktmode_on);
778   void doecho (const void *str, DWORD len);
779   int accept_input ();
780   int open (const char *path, int flags, mode_t mode = 0);
781   int write (const void *ptr, size_t len);
782   int read (void *ptr, size_t len);
783   int close ();
784
785   int tcsetattr (int a, const struct termios *t);
786   int tcgetattr (struct termios *t);
787   int tcflush (int);
788   int ioctl (unsigned int cmd, void *);
789
790   off_t lseek (off_t, int) { return 0; }
791   char *ptsname ();
792
793   void set_close_on_exec (int val);
794   BOOL hit_eof ();
795 };
796
797 class fhandler_tty_master: public fhandler_pty_master
798 {
799 public:
800   /* Constructor */
801   fhandler_tty_master (const char *name, int unit);
802   fhandler_console *console;    // device handler to perform real i/o.
803   HANDLE hThread;               // process_output thread handle.
804
805   int init (int);
806   int init_console ();
807   void fixup_after_fork (HANDLE parent);
808   void fixup_after_exec (HANDLE);
809 };
810
811 class fhandler_dev_null: public fhandler_base
812 {
813 public:
814   fhandler_dev_null (const char *name);
815
816   void dump ();
817   select_record *select_read (select_record *s);
818   select_record *select_write (select_record *s);
819   select_record *select_except (select_record *s);
820 };
821
822 class fhandler_dev_zero: public fhandler_base
823 {
824 public:
825   fhandler_dev_zero (const char *name);
826   int open (const char *path, int flags, mode_t mode = 0);
827   int write (const void *ptr, size_t len);
828   int read (void *ptr, size_t len);
829   off_t lseek (off_t offset, int whence);
830   int close (void);
831
832   void dump ();
833 };
834
835 class fhandler_dev_random: public fhandler_base
836 {
837 protected:
838   int unit;
839   HCRYPTPROV crypt_prov;
840   long pseudo;
841
842   BOOL crypt_gen_random (void *ptr, size_t len);
843   int pseudo_write (const void *ptr, size_t len);
844   int pseudo_read (void *ptr, size_t len);
845
846 public:
847   fhandler_dev_random (const char *name, int unit);
848   int get_unit () { return unit; }
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   int dup (fhandler_base *child);
855
856   void dump ();
857 };
858
859 class fhandler_dev_mem: public fhandler_base
860 {
861 protected:
862   int unit;
863   DWORD mem_size;
864   DWORD pos;
865
866 public:
867   fhandler_dev_mem (const char *name, int unit);
868   ~fhandler_dev_mem (void);
869
870   int open (const char *path, int flags, mode_t mode = 0);
871   int write (const void *ptr, size_t ulen);
872   int read (void *ptr, size_t ulen);
873   off_t lseek (off_t offset, int whence);
874   int close (void);
875   int fstat (struct stat *buf);
876   int dup (fhandler_base *child);
877
878   HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
879   int munmap (HANDLE h, caddr_t addr, size_t len);
880   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
881   BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
882                               DWORD size, void *address);
883
884   void dump ();
885 } ;
886
887 class fhandler_dev_clipboard: public fhandler_base
888 {
889 public:
890   fhandler_dev_clipboard (const char *name);
891   int is_windows (void) { return 1; }
892   int open (const char *path, int flags, mode_t mode = 0);
893   int write (const void *ptr, size_t len);
894   int read (void *ptr, size_t len);
895   off_t lseek (off_t offset, int whence);
896   int close (void);
897
898   void dump ();
899 };
900
901 class fhandler_windows: public fhandler_base
902 {
903 private:
904   HWND hWnd_;   // the window whose messages are to be retrieved by read() call
905   int method_;  // write method (Post or Send)
906 public:
907   fhandler_windows (const char *name = 0);
908   int is_windows (void) { return 1; }
909   int open (const char *path, int flags, mode_t mode = 0);
910   int write (const void *ptr, size_t len);
911   int read (void *ptr, size_t len);
912   int ioctl (unsigned int cmd, void *);
913   off_t lseek (off_t, int) { return 0; }
914   int close (void) { return 0; }
915
916   void set_close_on_exec (int val);
917   void fixup_after_fork (HANDLE parent);
918   select_record *select_read (select_record *s);
919   select_record *select_write (select_record *s);
920   select_record *select_except (select_record *s);
921   int ready_for_read (int fd, DWORD howlong, int ignra);
922 };
923
924 #if 0
925 /* You can't do this */
926 typedef union
927 {
928   fhandler_normal normal;
929   fhandler_dev_null dev_null;
930   fhandler bare;
931   fhandler_serial tty;
932 } fhandler_union;
933 #else
934 #define fhandler_union fhandler_console
935 #endif
936 struct select_record
937 {
938   int fd;
939   HANDLE h;
940   fhandler_base *fh;
941   BOOL saw_error;
942   BOOL windows_handle;
943   BOOL read_ready, write_ready, except_ready;
944   BOOL read_selected, write_selected, except_selected;
945   int (*startup) (select_record *me, class select_stuff *stuff);
946   int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
947                fd_set *exceptfds);
948   int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
949                  fd_set *exceptfds);
950   void (*cleanup) (select_record *me, class select_stuff *stuff);
951   struct select_record *next;
952
953   select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
954                  fh (in_fh), saw_error (0), windows_handle (0),
955                  read_ready (0), write_ready (0), except_ready (0),
956                  read_selected (0), write_selected (0), except_selected (0),
957                  startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
958                  next (NULL) {}
959 };
960
961 class select_stuff
962 {
963 public:
964   ~select_stuff ();
965   select_stuff (): always_ready (0), windows_used (0), start (0)
966   {
967     memset (device_specific, 0, sizeof (device_specific));
968   }
969   BOOL always_ready, windows_used;
970   select_record start;
971   void *device_specific[FH_NDEV];
972
973   int test_and_set (int i, fd_set *readfds, fd_set *writefds,
974                      fd_set *exceptfds);
975   int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
976   int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
977 };
978
979 int __stdcall set_console_state_for_spawn ();
980
981 #endif /* _FHANDLER_H_ */