OSDN Git Service

* gas/mri/mri.exp: Fix test of m6811/m6812 targets.
[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 };
765
766 class fhandler_pty_master: public fhandler_tty_common
767 {
768   int pktmode;                  // non-zero if pty in a packet mode.
769 public:
770   int need_nl;                  // Next read should start with \n
771
772   /* Constructor */
773   fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
774
775   int process_slave_output (char *buf, size_t len, int pktmode_on);
776   void doecho (const void *str, DWORD len);
777   int accept_input ();
778   int open (const char *path, int flags, mode_t mode = 0);
779   int write (const void *ptr, size_t len);
780   int read (void *ptr, size_t len);
781   int close ();
782
783   int tcsetattr (int a, const struct termios *t);
784   int tcgetattr (struct termios *t);
785   int tcflush (int);
786   int ioctl (unsigned int cmd, void *);
787
788   off_t lseek (off_t, int) { return 0; }
789   char *ptsname ();
790
791   void set_close_on_exec (int val);
792   BOOL hit_eof ();
793 };
794
795 class fhandler_tty_master: public fhandler_pty_master
796 {
797 public:
798   /* Constructor */
799   fhandler_tty_master (const char *name, int unit);
800   fhandler_console *console;    // device handler to perform real i/o.
801   HANDLE hThread;               // process_output thread handle.
802
803   int init (int);
804   int init_console ();
805   void fixup_after_fork (HANDLE parent);
806   void fixup_after_exec (HANDLE);
807 };
808
809 class fhandler_dev_null: public fhandler_base
810 {
811 public:
812   fhandler_dev_null (const char *name);
813
814   void dump ();
815   select_record *select_read (select_record *s);
816   select_record *select_write (select_record *s);
817   select_record *select_except (select_record *s);
818 };
819
820 class fhandler_dev_zero: public fhandler_base
821 {
822 public:
823   fhandler_dev_zero (const char *name);
824   int open (const char *path, int flags, mode_t mode = 0);
825   int write (const void *ptr, size_t len);
826   int read (void *ptr, size_t len);
827   off_t lseek (off_t offset, int whence);
828   int close (void);
829
830   void dump ();
831 };
832
833 class fhandler_dev_random: public fhandler_base
834 {
835 protected:
836   int unit;
837   HCRYPTPROV crypt_prov;
838   long pseudo;
839
840   BOOL crypt_gen_random (void *ptr, size_t len);
841   int pseudo_write (const void *ptr, size_t len);
842   int pseudo_read (void *ptr, size_t len);
843
844 public:
845   fhandler_dev_random (const char *name, int unit);
846   int get_unit () { return unit; }
847   int open (const char *path, int flags, mode_t mode = 0);
848   int write (const void *ptr, size_t len);
849   int read (void *ptr, size_t len);
850   off_t lseek (off_t offset, int whence);
851   int close (void);
852   int dup (fhandler_base *child);
853
854   void dump ();
855 };
856
857 class fhandler_dev_mem: public fhandler_base
858 {
859 protected:
860   int unit;
861   DWORD mem_size;
862   DWORD pos;
863
864 public:
865   fhandler_dev_mem (const char *name, int unit);
866   ~fhandler_dev_mem (void);
867
868   int open (const char *path, int flags, mode_t mode = 0);
869   int write (const void *ptr, size_t ulen);
870   int read (void *ptr, size_t ulen);
871   off_t lseek (off_t offset, int whence);
872   int close (void);
873   int fstat (struct stat *buf);
874   int dup (fhandler_base *child);
875
876   HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
877   int munmap (HANDLE h, caddr_t addr, size_t len);
878   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
879   BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
880                               DWORD size, void *address);
881
882   void dump ();
883 } ;
884
885 class fhandler_dev_clipboard: public fhandler_base
886 {
887 public:
888   fhandler_dev_clipboard (const char *name);
889   int is_windows (void) { return 1; }
890   int open (const char *path, int flags, mode_t mode = 0);
891   int write (const void *ptr, size_t len);
892   int read (void *ptr, size_t len);
893   off_t lseek (off_t offset, int whence);
894   int close (void);
895
896   void dump ();
897 };
898
899 class fhandler_windows: public fhandler_base
900 {
901 private:
902   HWND hWnd_;   // the window whose messages are to be retrieved by read() call
903   int method_;  // write method (Post or Send)
904 public:
905   fhandler_windows (const char *name = 0);
906   int is_windows (void) { return 1; }
907   int open (const char *path, int flags, mode_t mode = 0);
908   int write (const void *ptr, size_t len);
909   int read (void *ptr, size_t len);
910   int ioctl (unsigned int cmd, void *);
911   off_t lseek (off_t, int) { return 0; }
912   int close (void) { return 0; }
913
914   void set_close_on_exec (int val);
915   void fixup_after_fork (HANDLE parent);
916   select_record *select_read (select_record *s);
917   select_record *select_write (select_record *s);
918   select_record *select_except (select_record *s);
919   int ready_for_read (int fd, DWORD howlong, int ignra);
920 };
921
922 #if 0
923 /* You can't do this */
924 typedef union
925 {
926   fhandler_normal normal;
927   fhandler_dev_null dev_null;
928   fhandler bare;
929   fhandler_serial tty;
930 } fhandler_union;
931 #else
932 #define fhandler_union fhandler_console
933 #endif
934 struct select_record
935 {
936   int fd;
937   HANDLE h;
938   fhandler_base *fh;
939   BOOL saw_error;
940   BOOL windows_handle;
941   BOOL read_ready, write_ready, except_ready;
942   BOOL read_selected, write_selected, except_selected;
943   int (*startup) (select_record *me, class select_stuff *stuff);
944   int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
945                fd_set *exceptfds);
946   int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
947                  fd_set *exceptfds);
948   void (*cleanup) (select_record *me, class select_stuff *stuff);
949   struct select_record *next;
950
951   select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
952                  fh (in_fh), saw_error (0), windows_handle (0),
953                  read_ready (0), write_ready (0), except_ready (0),
954                  read_selected (0), write_selected (0), except_selected (0),
955                  startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
956                  next (NULL) {}
957 };
958
959 class select_stuff
960 {
961 public:
962   ~select_stuff ();
963   select_stuff (): always_ready (0), windows_used (0), start (0)
964   {
965     memset (device_specific, 0, sizeof (device_specific));
966   }
967   BOOL always_ready, windows_used;
968   select_record start;
969   void *device_specific[FH_NDEV];
970
971   int test_and_set (int i, fd_set *readfds, fd_set *writefds,
972                      fd_set *exceptfds);
973   int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
974   int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
975 };
976
977 int __stdcall set_console_state_for_spawn ();
978
979 #endif /* _FHANDLER_H_ */