OSDN Git Service

* autoload.cc (noload): Use proper method for multiline strings or newer gcc's
[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     // nothing to do
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 };
585
586 enum ansi_intensity
587 {
588   INTENSITY_INVISIBLE,
589   INTENSITY_DIM,
590   INTENSITY_NORMAL,
591   INTENSITY_BOLD
592 };
593
594 #define normal 1
595 #define gotesc 2
596 #define gotsquare 3
597 #define gotarg1 4
598 #define gotrsquare 5
599 #define gotcommand 6
600 #define gettitle 7
601 #define eattitle 8
602 #define MAXARGS 10
603
604 /* This is a input and output console handle */
605 class fhandler_console: public fhandler_termios
606 {
607 private:
608
609   WORD default_color, underline_color, dim_color;
610
611   /* Used to determine if an input keystroke should be modified with META. */
612   int meta_mask;
613
614 /* Output state */
615   int state_;
616   int args_[MAXARGS];
617   int nargs_;
618   unsigned rarg;
619   BOOL saw_question_mark;
620
621   char my_title_buf [TITLESIZE + 1];
622
623   WORD current_win32_attr;
624   ansi_intensity intensity;
625   BOOL underline, blink, reverse;
626   WORD fg, bg;
627
628   /* saved cursor coordinates */
629   int savex, savey;
630
631   struct
632     {
633       short Top, Bottom;
634     } scroll_region;
635   struct
636     {
637       SHORT winTop;
638       SHORT winBottom;
639       COORD dwWinSize;
640       COORD dwBufferSize;
641       COORD dwCursorPosition;
642       WORD wAttributes;
643     } info;
644
645   COORD dwLastCursorPosition;
646   DWORD dwLastButtonState;
647   int nModifiers;
648
649   BOOL use_mouse;
650   BOOL raw_win32_keyboard_mode;
651
652 /* Output calls */
653   void set_default_attr ();
654   WORD get_win32_attr ();
655
656   BOOL fillin_info ();
657   void clear_screen (int, int, int, int);
658   void scroll_screen (int, int, int, int, int, int);
659   void cursor_set (BOOL, int, int);
660   void cursor_get (int *, int *);
661   void cursor_rel (int, int);
662   const unsigned char * write_normal (unsigned const char*, unsigned const char *);
663   void char_command (char);
664   BOOL set_raw_win32_keyboard_mode (BOOL);
665   int output_tcsetattr (int a, const struct termios *t);
666
667 /* Input calls */
668   int igncr_enabled ();
669   int input_tcsetattr (int a, const struct termios *t);
670   void set_cursor_maybe ();
671
672 public:
673
674   fhandler_console (const char *name);
675
676   fhandler_console* is_console () { return this; }
677
678   int open (const char *path, int flags, mode_t mode = 0);
679
680   int write (const void *ptr, size_t len);
681   void doecho (const void *str, DWORD len) { (void) write (str, len); }
682   int read (void *ptr, size_t len);
683   int close ();
684
685   int tcflush (int);
686   int tcsetattr (int a, const struct termios *t);
687   int tcgetattr (struct termios *t);
688
689   /* Special dup as we must dup two handles */
690   int dup (fhandler_base *child);
691
692   int ioctl (unsigned int cmd, void *);
693   void init (HANDLE, DWORD, mode_t);
694   bool mouse_aware () {return use_mouse;}
695
696   select_record *select_read (select_record *s);
697   select_record *select_write (select_record *s);
698   select_record *select_except (select_record *s);
699   int ready_for_read (int fd, DWORD howlong, int ignra);
700   void fixup_after_exec (HANDLE);
701   void set_close_on_exec (int val);
702   void fixup_after_fork (HANDLE parent);
703   void set_input_state ();
704 };
705
706 class fhandler_tty_common: public fhandler_termios
707 {
708 public:
709   fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
710     fhandler_termios (dev, name, unit),
711     ttynum (unit)
712   {
713     // nothing to do
714   }
715   HANDLE output_done_event;     // Raised by master when tty's output buffer
716                                 // written. Write status in tty::write_retval.
717   HANDLE ioctl_request_event;   // Raised by slave to perform ioctl() request.
718                                 // Ioctl() request in tty::cmd/arg.
719   HANDLE ioctl_done_event;      // Raised by master on ioctl() completion.
720                                 // Ioctl() status in tty::ioctl_retval.
721   HANDLE output_mutex, input_mutex;
722   HANDLE input_available_event;
723   HANDLE inuse;                 // used to indicate that a tty is in use
724
725
726   DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
727   void __release_output_mutex (const char *fn, int ln);
728
729   int ttynum;                   // Master tty num.
730   virtual int dup (fhandler_base *child);
731
732   tty *get_ttyp () { return (tty *)tc; }
733   int get_unit () { return ttynum; }
734
735   int close ();
736   void set_close_on_exec (int val);
737   void fixup_after_fork (HANDLE parent);
738   select_record *select_read (select_record *s);
739   select_record *select_write (select_record *s);
740   select_record *select_except (select_record *s);
741   int ready_for_read (int fd, DWORD howlong, int ignra);
742 };
743
744 class fhandler_tty_slave: public fhandler_tty_common
745 {
746 public:
747   /* Constructor */
748   fhandler_tty_slave (const char *name);
749   fhandler_tty_slave (int, const char *name);
750
751   int open (const char *path, int flags, mode_t mode = 0);
752   int write (const void *ptr, size_t len);
753   int read (void *ptr, size_t len);
754   void init (HANDLE, DWORD, mode_t);
755
756   int tcsetattr (int a, const struct termios *t);
757   int tcgetattr (struct termios *t);
758   int tcflush (int);
759   int ioctl (unsigned int cmd, void *);
760
761   off_t lseek (off_t, int) { return 0; }
762 };
763
764 class fhandler_pty_master: public fhandler_tty_common
765 {
766   int pktmode;                  // non-zero if pty in a packet mode.
767 public:
768   int need_nl;                  // Next read should start with \n
769
770   /* Constructor */
771   fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
772
773   int process_slave_output (char *buf, size_t len, int pktmode_on);
774   void doecho (const void *str, DWORD len);
775   int accept_input ();
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   int close ();
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   char *ptsname ();
788
789   void set_close_on_exec (int val);
790   BOOL hit_eof ();
791 };
792
793 class fhandler_tty_master: public fhandler_pty_master
794 {
795 public:
796   /* Constructor */
797   fhandler_tty_master (const char *name, int unit);
798   fhandler_console *console;    // device handler to perform real i/o.
799   HANDLE hThread;               // process_output thread handle.
800
801   int init (int);
802   int init_console ();
803   void fixup_after_fork (HANDLE parent);
804   void fixup_after_exec (HANDLE);
805 };
806
807 class fhandler_dev_null: public fhandler_base
808 {
809 public:
810   fhandler_dev_null (const char *name);
811
812   void dump ();
813   select_record *select_read (select_record *s);
814   select_record *select_write (select_record *s);
815   select_record *select_except (select_record *s);
816 };
817
818 class fhandler_dev_zero: public fhandler_base
819 {
820 public:
821   fhandler_dev_zero (const char *name);
822   int open (const char *path, int flags, mode_t mode = 0);
823   int write (const void *ptr, size_t len);
824   int read (void *ptr, size_t len);
825   off_t lseek (off_t offset, int whence);
826   int close (void);
827
828   void dump ();
829 };
830
831 class fhandler_dev_random: public fhandler_base
832 {
833 protected:
834   int unit;
835   HCRYPTPROV crypt_prov;
836   long pseudo;
837
838   BOOL crypt_gen_random (void *ptr, size_t len);
839   int pseudo_write (const void *ptr, size_t len);
840   int pseudo_read (void *ptr, size_t len);
841
842 public:
843   fhandler_dev_random (const char *name, int unit);
844   int get_unit () { return unit; }
845   int open (const char *path, int flags, mode_t mode = 0);
846   int write (const void *ptr, size_t len);
847   int read (void *ptr, size_t len);
848   off_t lseek (off_t offset, int whence);
849   int close (void);
850   int dup (fhandler_base *child);
851
852   void dump ();
853 };
854
855 class fhandler_dev_mem: public fhandler_base
856 {
857 protected:
858   int unit;
859   DWORD mem_size;
860   DWORD pos;
861
862 public:
863   fhandler_dev_mem (const char *name, int unit);
864   ~fhandler_dev_mem (void);
865
866   int open (const char *path, int flags, mode_t mode = 0);
867   int write (const void *ptr, size_t ulen);
868   int read (void *ptr, size_t ulen);
869   off_t lseek (off_t offset, int whence);
870   int close (void);
871   int fstat (struct stat *buf);
872   int dup (fhandler_base *child);
873
874   HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
875   int munmap (HANDLE h, caddr_t addr, size_t len);
876   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
877   BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
878                               DWORD size, void *address);
879
880   void dump ();
881 } ;
882
883 class fhandler_dev_clipboard: public fhandler_base
884 {
885 public:
886   fhandler_dev_clipboard (const char *name);
887   int is_windows (void) { return 1; }
888   int open (const char *path, int flags, mode_t mode = 0);
889   int write (const void *ptr, size_t len);
890   int read (void *ptr, size_t len);
891   off_t lseek (off_t offset, int whence);
892   int close (void);
893
894   void dump ();
895 };
896
897 class fhandler_windows: public fhandler_base
898 {
899 private:
900   HWND hWnd_;   // the window whose messages are to be retrieved by read() call
901   int method_;  // write method (Post or Send)
902 public:
903   fhandler_windows (const char *name = 0);
904   int is_windows (void) { return 1; }
905   int open (const char *path, int flags, mode_t mode = 0);
906   int write (const void *ptr, size_t len);
907   int read (void *ptr, size_t len);
908   int ioctl (unsigned int cmd, void *);
909   off_t lseek (off_t, int) { return 0; }
910   int close (void) { return 0; }
911
912   void set_close_on_exec (int val);
913   void fixup_after_fork (HANDLE parent);
914   select_record *select_read (select_record *s);
915   select_record *select_write (select_record *s);
916   select_record *select_except (select_record *s);
917   int ready_for_read (int fd, DWORD howlong, int ignra);
918 };
919
920 #if 0
921 /* You can't do this */
922 typedef union
923 {
924   fhandler_normal normal;
925   fhandler_dev_null dev_null;
926   fhandler bare;
927   fhandler_serial tty;
928 } fhandler_union;
929 #else
930 #define fhandler_union fhandler_console
931 #endif
932 struct select_record
933 {
934   int fd;
935   HANDLE h;
936   fhandler_base *fh;
937   BOOL saw_error;
938   BOOL windows_handle;
939   BOOL read_ready, write_ready, except_ready;
940   BOOL read_selected, write_selected, except_selected;
941   int (*startup) (select_record *me, class select_stuff *stuff);
942   int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
943                fd_set *exceptfds);
944   int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
945                  fd_set *exceptfds);
946   void (*cleanup) (select_record *me, class select_stuff *stuff);
947   struct select_record *next;
948
949   select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
950                  fh (in_fh), saw_error (0), windows_handle (0),
951                  read_ready (0), write_ready (0), except_ready (0),
952                  read_selected (0), write_selected (0), except_selected (0),
953                  startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
954                  next (NULL) {}
955 };
956
957 class select_stuff
958 {
959 public:
960   ~select_stuff ();
961   select_stuff (): always_ready (0), windows_used (0), start (0)
962   {
963     memset (device_specific, 0, sizeof (device_specific));
964   }
965   BOOL always_ready, windows_used;
966   select_record start;
967   void *device_specific[FH_NDEV];
968
969   int test_and_set (int i, fd_set *readfds, fd_set *writefds,
970                      fd_set *exceptfds);
971   int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
972   int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
973 };
974
975 int __stdcall set_console_state_for_spawn ();
976
977 #endif /* _FHANDLER_H_ */