OSDN Git Service

* Makefile.in: Add fhandler_mem.o to the dependencies.
[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      (net.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_proc        Interesting possibility, not implemented yet
47 */
48
49 enum
50 {
51   FH_RBINARY = 0x00001000,      /* binary read mode */
52   FH_WBINARY = 0x00002000,      /* binary write mode */
53   FH_CLOEXEC = 0x00004000,      /* close-on-exec */
54   FH_RBINSET = 0x00008000,      /* binary read mode has been explicitly set */
55   FH_WBINSET = 0x00010000,      /* binary write mode has been explicitly set */
56   FH_APPEND  = 0x00020000,      /* always append */
57   FH_ASYNC   = 0x00040000,      /* async I/O */
58   FH_HADEOF  = 0x00080000,      /* EOF seen */
59
60   FH_SYMLINK = 0x00100000,      /* is a symlink */
61   FH_EXECABL = 0x00200000,      /* file looked like it would run:
62                                  * ends in .exe or .bat or begins with #! */
63   FH_W95LSBUG= 0x00400000,      /* set when lseek is called as a flag that
64                                  * _write should check if we've moved beyond
65                                  * EOF, zero filling if so. */
66   FH_NOFRNAME= 0x00800000,      /* Set if shouldn't free unix_path_name_ and
67                                    windows_path_name_ on destruction. */
68   FH_NOEINTR = 0x01000000,      /* Set if I/O should be uninterruptible. */
69   FH_FFIXUP  = 0x02000000,      /* Set if need to fixup after fork. */
70   FH_LOCAL   = 0x04000000,      /* File is unix domain socket */
71   FH_FIFO    = 0x08000000,      /* File is FIFO */
72   FH_HASACLS = 0x40000000,      /* True if fs of file has ACLS */
73
74   /* Device flags */
75
76   /* Slow devices */
77   FH_CONSOLE = 0x00000001,      /* is a console */
78   FH_CONIN   = 0x00000002,      /* console input */
79   FH_CONOUT  = 0x00000003,      /* console output */
80   FH_TTYM    = 0x00000004,      /* is a tty master */
81   FH_TTYS    = 0x00000005,      /* is a tty slave */
82   FH_PTYM    = 0x00000006,      /* is a pty master */
83   FH_SERIAL  = 0x00000007,      /* is a serial port */
84   FH_PIPE    = 0x00000008,      /* is a pipe */
85   FH_PIPER   = 0x00000009,      /* read end of a pipe */
86   FH_PIPEW   = 0x0000000a,      /* write end of a pipe */
87   FH_SOCKET  = 0x0000000b,      /* is a socket */
88   FH_WINDOWS = 0x0000000c,      /* is a window */
89
90   FH_SLOW    = 0x00000010,      /* "slow" device if below this */
91
92   /* Fast devices */
93   FH_DISK    = 0x00000010,      /* is a disk */
94   FH_FLOPPY  = 0x00000011,      /* is a floppy */
95   FH_TAPE    = 0x00000012,      /* is a tape */
96   FH_NULL    = 0x00000013,      /* is the null device */
97   FH_ZERO    = 0x00000014,      /* is the zero device */
98   FH_RANDOM  = 0x00000015,      /* is a random device */
99   FH_MEM     = 0x00000016,      /* is a mem device */
100
101   FH_NDEV    = 0x00000017,      /* Maximum number of devices */
102   FH_DEVMASK = 0x00000fff,      /* devices live here */
103   FH_BAD     = 0xffffffff
104 };
105
106 #define FHDEVN(n)       ((n) & FH_DEVMASK)
107 #define FHISSETF(x)     __ISSETF (this, x, FH)
108 #define FHSETF(x)       __SETF (this, x, FH)
109 #define FHCLEARF(x)     __CLEARF (this, x, FH)
110 #define FHCONDSETF(n, x) __CONDSETF(n, this, x, FH)
111
112 #define FHSTATOFF       0
113
114 extern const char *windows_device_names[];
115 extern struct __cygwin_perfile *perfile_table;
116 #define __fmode (*(user_data->fmode_ptr))
117
118 class select_record;
119 class path_conv;
120 class fhandler_disk_file;
121
122 class fhandler_base
123 {
124 private:
125   DWORD status;
126 public:
127   int cb;
128 private:
129   int access_;
130   HANDLE io_handle;
131
132   int rpos_; /* Used in text reading */
133   int rsize_;
134
135   unsigned long namehash_;      /* hashed filename, used as inode num */
136
137   /* Full unix path name of this file */
138   /* File open flags from open () and fcntl () calls */
139   int openflags_;
140
141 protected:
142   char *rabuf;          /* used for crlf conversion in text files */
143   size_t ralen;
144   size_t raixget;
145   size_t raixput;
146   size_t rabuflen;
147
148   char *unix_path_name_;
149   char *win32_path_name_;
150
151 public:
152   void set_name (const char * unix_path, const char * win32_path = NULL,
153                  int unit = 0);
154
155   virtual fhandler_base& operator =(fhandler_base &x);
156   fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
157   virtual ~fhandler_base ();
158
159   /* Non-virtual simple accessor functions. */
160   void set_io_handle (HANDLE);
161
162   void set_cb (size_t size) { cb = size; }
163   DWORD get_device () { return status & FH_DEVMASK; }
164   virtual int get_unit () { return 0; }
165   virtual BOOL is_slow () { return get_device () < FH_SLOW; }
166
167   int get_access () { return access_; }
168   void set_access (int x) { access_ = x; }
169
170   int get_async () { return FHISSETF (ASYNC); }
171   void set_async (int x) { FHCONDSETF (x, ASYNC); }
172
173   int get_flags () { return openflags_; }
174   void set_flags (int x) { openflags_ = x; }
175
176   int get_w_binary () { return FHISSETF (WBINARY); }
177   int get_r_binary () { return FHISSETF (RBINARY); }
178
179   int get_w_binset () { return FHISSETF (WBINSET); }
180   int get_r_binset () { return FHISSETF (RBINSET); }
181
182   void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
183   void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
184
185   int get_default_fmode (int flags);
186
187   int get_r_no_interrupt () { return FHISSETF (NOEINTR); }
188   void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); }
189
190   int get_close_on_exec () { return FHISSETF (CLOEXEC); }
191   int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); }
192
193   void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); }
194   int get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); }
195
196   int get_need_fork_fixup () { return FHISSETF (FFIXUP); }
197   void set_need_fork_fixup () { FHSETF (FFIXUP); }
198
199   virtual void set_close_on_exec (int val);
200   virtual void fixup_after_fork (HANDLE parent);
201
202   int get_symlink_p () { return FHISSETF (SYMLINK); }
203   void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); }
204   void set_symlink_p () { FHSETF (SYMLINK); }
205
206   int get_socket_p () { return FHISSETF (LOCAL); }
207   void set_socket_p (int val) { FHCONDSETF (val, LOCAL); }
208   void set_socket_p () { FHSETF (LOCAL); }
209
210   int get_execable_p () { return FHISSETF (EXECABL); }
211   void set_execable_p (int val) { FHCONDSETF (val, EXECABL); }
212   void set_execable_p () { FHSETF (EXECABL); }
213
214   int get_append_p () { return FHISSETF (APPEND); }
215   void set_append_p (int val) { FHCONDSETF (val, APPEND); }
216   void set_append_p () { FHSETF (APPEND); }
217
218   int get_readahead_valid () { return raixget < ralen; }
219   int puts_readahead (const char *s, size_t len = (size_t) -1);
220   int put_readahead (char value);
221
222   int get_readahead ();
223   int peek_readahead (int queryput = 0);
224
225   int eat_readahead (int n);
226
227   void set_readahead_valid (int val, int ch = -1);
228
229   int get_readahead_into_buffer (char *buf, size_t buflen);
230
231   int has_acls () { return FHISSETF (HASACLS); }
232   void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
233
234   int no_free_names () { return FHISSETF (NOFRNAME); }
235   void set_no_free_names (int val) { FHCONDSETF (val, NOFRNAME); }
236   void set_no_free_names () { FHSETF (NOFRNAME); }
237
238   const char *get_name () { return unix_path_name_; }
239   const char *get_win32_name () { return win32_path_name_; }
240   unsigned long get_namehash () { return namehash_; }
241
242   virtual void hclose (HANDLE h) {CloseHandle (h);}
243   virtual void set_inheritance (HANDLE &h, int not_inheriting,
244                                 const char *name = NULL);
245
246   /* fixup fd possibly non-inherited handles after fork */
247   void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
248
249   /* Potentially overridden virtual functions. */
250   virtual int open (const char *, int flags, mode_t mode = 0)
251   {
252     return open (flags, mode);
253   }
254   virtual int open (int flags, mode_t mode = 0);
255   virtual int close ();
256   virtual int fstat (struct stat *buf);
257   virtual int ioctl (unsigned int cmd, void *);
258   virtual char const * ttyname () { return get_name(); }
259   virtual int read (void *ptr, size_t len);
260   virtual int write (const void *ptr, size_t len);
261   virtual off_t lseek (off_t offset, int whence);
262   virtual int lock (int, struct flock *);
263   virtual void dump ();
264   virtual int dup (fhandler_base *child);
265
266   void *operator new (size_t, void *p) {return p;}
267
268   virtual void init (HANDLE, DWORD, mode_t);
269
270   virtual int tcflush (int);
271   virtual int tcsendbreak (int);
272   virtual int tcdrain ();
273   virtual int tcflow (int);
274   virtual int tcsetattr (int a, const struct termios *t);
275   virtual int tcgetattr (struct termios *t);
276   virtual int tcsetpgrp (const pid_t pid);
277   virtual int tcgetpgrp ();
278   virtual int is_tty () { return 0; }
279   virtual BOOL is_device () { return TRUE; }
280   virtual char *ptsname () { return NULL;}
281   virtual class fhandler_socket *is_socket () { return 0; }
282   virtual class fhandler_console *is_console () { return 0; }
283   virtual int is_windows () {return 0; }
284
285   virtual int raw_read (void *ptr, size_t ulen);
286   virtual int raw_write (const void *ptr, size_t ulen);
287
288   virtual void fixup_after_exec (HANDLE) {}
289
290   /* Virtual accessor functions to hide the fact
291      that some fd's have two handles. */
292   virtual HANDLE get_handle () const { return io_handle; }
293   virtual HANDLE get_io_handle () const { return io_handle; }
294   virtual HANDLE get_output_handle () const { return io_handle; }
295   virtual BOOL hit_eof () {return FALSE;}
296   virtual select_record *select_read (select_record *s);
297   virtual select_record *select_write (select_record *s);
298   virtual select_record *select_except (select_record *s);
299   virtual int ready_for_read (int fd, DWORD howlong, int ignra);
300   virtual const char * get_native_name ()
301   {
302     return windows_device_names[FHDEVN (status)];
303   }
304   virtual int bg_check (int) {return 1;}
305   void clear_readahead ()
306   {
307     raixput = raixget = ralen = rabuflen = 0;
308     rabuf = NULL;
309   }
310   void operator delete (void *);
311 };
312
313 class fhandler_socket: public fhandler_base
314 {
315 private:
316   int addr_family;
317 public:
318   fhandler_socket (const char *name = 0);
319   fhandler_socket (unsigned int, const char *name = 0);
320   int get_socket () const { return (int) get_handle(); }
321   fhandler_socket * is_socket () { return this; }
322   int write (const void *ptr, size_t len);
323   int read (void *ptr, size_t len);
324   int ioctl (unsigned int cmd, void *);
325   off_t lseek (off_t, int) { return 0; }
326   int close ();
327   void hclose (HANDLE) {close ();}
328
329   select_record *select_read (select_record *s);
330   select_record *select_write (select_record *s);
331   select_record *select_except (select_record *s);
332   int ready_for_read (int fd, DWORD howlong, int ignra);
333   int get_addr_family () {return addr_family;}
334   void set_addr_family (int af) {addr_family = af;}
335 };
336
337 class fhandler_pipe: public fhandler_base
338 {
339 public:
340   fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
341   off_t lseek (off_t offset, int whence);
342   /* This strange test is due to the fact that we can't rely on
343      Windows shells to "do the right thing" with pipes.  Apparently
344      the can keep one end of the pipe open when it shouldn't be. */
345   BOOL is_slow () {return os_being_run == winNT;}
346   select_record *select_read (select_record *s);
347   select_record *select_write (select_record *s);
348   select_record *select_except (select_record *s);
349   int ready_for_read (int fd, DWORD howlong, int ignra);
350 };
351
352 class fhandler_dev_raw: public fhandler_base
353 {
354 protected:
355   char *devbuf;
356   size_t devbufsiz;
357   size_t devbufstart;
358   size_t devbufend;
359   int eom_detected    : 1;
360   int eof_detected    : 1;
361   int lastblk_to_read : 1;
362   int is_writing      : 1;
363   int has_written     : 1;
364   int varblkop        : 1;
365   int unit;
366
367   virtual void clear (void);
368   virtual int writebuf (void);
369
370   /* returns not null, if `win_error' determines an end of media condition */
371   virtual int is_eom(int win_error) = 0;
372   /* returns not null, if `win_error' determines an end of file condition */
373   virtual int is_eof(int win_error) = 0;
374
375   fhandler_dev_raw (DWORD dev, const char *name, int unit);
376
377 public:
378   ~fhandler_dev_raw (void);
379
380   int open (const char *path, int flags, mode_t mode = 0);
381   int close (void);
382
383   int raw_read (void *ptr, size_t ulen);
384   int raw_write (const void *ptr, size_t ulen);
385
386   int fstat (struct stat *buf);
387
388   int dup (fhandler_base *child);
389
390   int ioctl (unsigned int cmd, void *buf);
391 };
392
393 class fhandler_dev_floppy: public fhandler_dev_raw
394 {
395 protected:
396   virtual int is_eom (int win_error);
397   virtual int is_eof (int win_error);
398
399 public:
400   fhandler_dev_floppy (const char *name, int unit);
401
402   virtual int open (const char *path, int flags, mode_t mode = 0);
403   virtual int close (void);
404
405   virtual off_t lseek (off_t offset, int whence);
406
407   virtual int ioctl (unsigned int cmd, void *buf);
408 };
409
410 class fhandler_dev_tape: public fhandler_dev_raw
411 {
412   int norewind;
413   int lasterr;
414
415 protected:
416   virtual void clear (void);
417
418   virtual int is_eom (int win_error);
419   virtual int is_eof (int win_error);
420
421 public:
422   fhandler_dev_tape (const char *name, int unit);
423
424   virtual int open (const char *path, int flags, mode_t mode = 0);
425   virtual int close (void);
426
427   virtual off_t lseek (off_t offset, int whence);
428
429   virtual int fstat (struct stat *buf);
430
431   virtual int dup (fhandler_base *child);
432
433   virtual int ioctl (unsigned int cmd, void *buf);
434
435 private:
436   int tape_write_marks (int marktype, DWORD len);
437   int tape_get_pos (unsigned long *ret);
438   int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
439   int tape_erase (int mode);
440   int tape_prepare (int action);
441   BOOLEAN tape_get_feature (DWORD parm);
442   int tape_get_blocksize (long *min, long *def, long *max, long *cur);
443   int tape_set_blocksize (long count);
444   int tape_status (struct mtget *get);
445   int tape_compression (long count);
446 };
447
448 /* Standard disk file */
449
450 class fhandler_disk_file: public fhandler_base
451 {
452 private:
453   int check_execable_p (const char *path);
454
455 public:
456   fhandler_disk_file (const char *name);
457
458   int open (const char *path, int flags, mode_t mode = 0);
459   int open (path_conv& real_path, int flags, mode_t mode);
460   int close ();
461   int lock (int, struct flock *);
462   BOOL is_device () { return FALSE; }
463   int fstat (struct stat *buf);
464 };
465
466 class fhandler_serial: public fhandler_base
467 {
468 private:
469   unsigned int vmin_;                   /* from termios */
470   unsigned int vtime_;                  /* from termios */
471   pid_t pgrp_;
472
473 public:
474   int overlapped_armed;
475   OVERLAPPED io_status;
476
477   /* Constructor */
478   fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
479
480   int open (const char *path, int flags, mode_t mode);
481   int close ();
482   void init (HANDLE h, DWORD a, mode_t flags);
483   void overlapped_setup ();
484   int dup (fhandler_base *child);
485   int raw_read (void *ptr, size_t ulen);
486   int raw_write (const void *ptr, size_t ulen);
487   int tcsendbreak (int);
488   int tcdrain ();
489   int tcflow (int);
490   int tcsetattr (int a, const struct termios *t);
491   int tcgetattr (struct termios *t);
492   off_t lseek (off_t, int) { return 0; }
493   int tcflush (int);
494   void dump ();
495   int is_tty () { return 1; }
496   void fixup_after_fork (HANDLE parent);
497   void fixup_after_exec (HANDLE);
498
499   /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
500      don't use it for permissions checking.  fhandler_tty_slave does
501      permission checking on pgrps.  */
502   virtual int tcgetpgrp () { return pgrp_; }
503   virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
504   select_record *select_read (select_record *s);
505   select_record *select_write (select_record *s);
506   select_record *select_except (select_record *s);
507   int ready_for_read (int fd, DWORD howlong, int ignra);
508 };
509
510 #define acquire_output_mutex(ms) \
511   __acquire_output_mutex (__PRETTY_FUNCTION__, __LINE__, ms);
512
513 #define release_output_mutex() \
514   __release_output_mutex (__PRETTY_FUNCTION__, __LINE__);
515
516 class tty;
517 class tty_min;
518 class fhandler_termios: public fhandler_base
519 {
520 protected:
521   HANDLE output_handle;
522   virtual void doecho (const void *, DWORD) {};
523   virtual int accept_input () {return 1;};
524 public:
525   tty_min *tc;
526   fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
527   fhandler_base (dev, name, unit)
528   {
529     // nothing to do
530   }
531   HANDLE get_output_handle () const { return output_handle; }
532   int line_edit (const char *rptr, int nread, int always_accept = 0);
533   void set_output_handle (HANDLE h) { output_handle = h; }
534   void tcinit (tty_min *this_tc, int force = FALSE);
535   virtual int is_tty () { return 1; }
536   int tcgetpgrp ();
537   int tcsetpgrp (int pid);
538   void set_ctty (int ttynum, int flags);
539   int bg_check (int sig);
540   virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
541   virtual void __release_output_mutex (const char *fn, int ln) {}
542 };
543
544 /* This is a input and output console handle */
545 class fhandler_console: public fhandler_termios
546 {
547 private:
548
549 /* Output state */
550
551   // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
552 #define normal 1
553 #define gotesc 2
554 #define gotsquare 3
555 #define gotarg1 4
556 #define gotrsquare 5
557 #define gotcommand 6
558 #define gettitle 7
559 #define eattitle 8
560 #define MAXARGS 10
561   int state_;
562   int args_[MAXARGS];
563   int nargs_;
564
565   DWORD default_color;
566
567 /* Output calls */
568
569   BOOL fillin_info ();
570   void clear_screen (int, int, int, int);
571   void scroll_screen (int, int, int, int, int, int);
572   void cursor_set (BOOL, int, int);
573   void cursor_get (int *, int *);
574   void cursor_rel (int, int);
575   const unsigned char * write_normal (unsigned const char*, unsigned const char *);
576   void char_command (char);
577   int output_tcsetattr (int a, const struct termios *t);
578
579 /* Input calls */
580   int igncr_enabled ();
581   int input_tcsetattr (int a, const struct termios *t);
582   void set_cursor_maybe ();
583
584 public:
585
586   fhandler_console (const char *name);
587
588   fhandler_console* is_console () { return this; }
589
590   int open (const char *path, int flags, mode_t mode = 0);
591
592   int write (const void *ptr, size_t len);
593   void doecho (const void *str, DWORD len) { (void) write (str, len); }
594   int read (void *ptr, size_t len);
595   int close ();
596
597   int tcflush (int);
598   int tcsetattr (int a, const struct termios *t);
599   int tcgetattr (struct termios *t);
600
601   int tcsetpgrp (const pid_t pid);
602
603   /* Special dup as we must dup two handles */
604   int dup (fhandler_base *child);
605
606   int ioctl (unsigned int cmd, void *);
607   void init (HANDLE, DWORD, mode_t);
608
609   select_record *select_read (select_record *s);
610   select_record *select_write (select_record *s);
611   select_record *select_except (select_record *s);
612   int ready_for_read (int fd, DWORD howlong, int ignra);
613   void fixup_after_exec (HANDLE);
614   void set_close_on_exec (int val);
615   void fixup_after_fork (HANDLE parent);
616   void set_input_state ();
617 };
618
619 class fhandler_tty_common: public fhandler_termios
620 {
621 public:
622   fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
623     fhandler_termios (dev, name, unit),
624     ttynum (unit)
625   {
626     // nothing to do
627   }
628   HANDLE output_done_event;     // Raised by master when tty's output buffer
629                                 // written. Write status in tty::write_retval.
630   HANDLE ioctl_request_event;   // Raised by slave to perform ioctl() request.
631                                 // Ioctl() request in tty::cmd/arg.
632   HANDLE ioctl_done_event;      // Raised by master on ioctl() completion.
633                                 // Ioctl() status in tty::ioctl_retval.
634   HANDLE output_mutex;
635   HANDLE inuse;                 // used to indicate that a tty is in use
636
637
638   DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
639   void __release_output_mutex (const char *fn, int ln);
640
641   int ttynum;                   // Master tty num.
642   virtual int dup (fhandler_base *child);
643
644   tty *get_ttyp () { return (tty *)tc; }
645   int get_unit () { return ttynum; }
646
647   int close ();
648   void set_close_on_exec (int val);
649   void fixup_after_fork (HANDLE parent);
650   select_record *select_read (select_record *s);
651   select_record *select_write (select_record *s);
652   select_record *select_except (select_record *s);
653   int ready_for_read (int fd, DWORD howlong, int ignra);
654 };
655
656 class fhandler_tty_slave: public fhandler_tty_common
657 {
658 public:
659   /* Constructor */
660   fhandler_tty_slave (const char *name);
661   fhandler_tty_slave (int, const char *name);
662
663   int open (const char *path, int flags, mode_t mode = 0);
664   int write (const void *ptr, size_t len);
665   int read (void *ptr, size_t len);
666   void init (HANDLE, DWORD, mode_t);
667
668   int tcsetattr (int a, const struct termios *t);
669   int tcgetattr (struct termios *t);
670   int tcflush (int);
671   int ioctl (unsigned int cmd, void *);
672
673   off_t lseek (off_t, int) { return 0; }
674 };
675
676 class fhandler_pty_master: public fhandler_tty_common
677 {
678   int pktmode;                  // non-zero if pty in a packet mode.
679 public:
680   int need_nl;                  // Next read should start with \n
681
682   /* Constructor */
683   fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
684
685   int process_slave_output (char *buf, size_t len, int pktmode_on);
686   void doecho (const void *str, DWORD len);
687   int accept_input ();
688   int open (const char *path, int flags, mode_t mode = 0);
689   int write (const void *ptr, size_t len);
690   int read (void *ptr, size_t len);
691   int close ();
692
693   int tcsetattr (int a, const struct termios *t);
694   int tcgetattr (struct termios *t);
695   int tcflush (int);
696   int ioctl (unsigned int cmd, void *);
697
698   off_t lseek (off_t, int) { return 0; }
699   char *ptsname ();
700
701   void set_close_on_exec (int val);
702   BOOL hit_eof ();
703 };
704
705 class fhandler_tty_master: public fhandler_pty_master
706 {
707 public:
708   /* Constructor */
709   fhandler_tty_master (const char *name, int unit);
710   fhandler_console *console;    // device handler to perform real i/o.
711   HANDLE hThread;               // process_output thread handle.
712
713   int init (int);
714   int init_console ();
715   void fixup_after_fork (HANDLE parent);
716   void fixup_after_exec (HANDLE);
717 };
718
719 class fhandler_dev_null: public fhandler_base
720 {
721 public:
722   fhandler_dev_null (const char *name);
723
724   void dump ();
725   select_record *select_read (select_record *s);
726   select_record *select_write (select_record *s);
727   select_record *select_except (select_record *s);
728 };
729
730 class fhandler_dev_zero: public fhandler_base
731 {
732 public:
733   fhandler_dev_zero (const char *name);
734   int open (const char *path, int flags, mode_t mode = 0);
735   int write (const void *ptr, size_t len);
736   int read (void *ptr, size_t len);
737   off_t lseek (off_t offset, int whence);
738   int close (void);
739
740   void dump ();
741 };
742
743 class fhandler_dev_random: public fhandler_base
744 {
745 protected:
746   int unit;
747   HCRYPTPROV crypt_prov;
748   long pseudo;
749
750   BOOL crypt_gen_random (void *ptr, size_t len);
751   int pseudo_write (const void *ptr, size_t len);
752   int pseudo_read (void *ptr, size_t len);
753
754 public:
755   fhandler_dev_random (const char *name, int unit);
756   int get_unit () { return unit; }
757   int open (const char *path, int flags, mode_t mode = 0);
758   int write (const void *ptr, size_t len);
759   int read (void *ptr, size_t len);
760   off_t lseek (off_t offset, int whence);
761   int close (void);
762   int dup (fhandler_base *child);
763
764   void dump ();
765 };
766
767 class fhandler_dev_mem: public fhandler_base
768 {
769 protected:
770   unsigned long pos;
771
772 public:
773   fhandler_dev_mem (const char *name, int unit);
774   ~fhandler_dev_mem (void);
775
776   int open (const char *path, int flags, mode_t mode = 0);
777   int write (const void *ptr, size_t ulen);
778   int read (void *ptr, size_t ulen);
779   off_t lseek (off_t offset, int whence);
780   int close (void);
781   int fstat (struct stat *buf);
782   int dup (fhandler_base *child);
783
784   void dump ();
785 };
786
787 class fhandler_windows: public fhandler_base
788 {
789 private:
790   HWND hWnd_;   // the window whose messages are to be retrieved by read() call
791   int method_;  // write method (Post or Send)
792 public:
793   fhandler_windows (const char *name = 0);
794   int is_windows (void) { return 1; }
795   int open (const char *path, int flags, mode_t mode = 0);
796   int write (const void *ptr, size_t len);
797   int read (void *ptr, size_t len);
798   int ioctl (unsigned int cmd, void *);
799   off_t lseek (off_t, int) { return 0; }
800   int close (void) { return 0; }
801
802   void set_close_on_exec (int val);
803   void fixup_after_fork (HANDLE parent);
804   select_record *select_read (select_record *s);
805   select_record *select_write (select_record *s);
806   select_record *select_except (select_record *s);
807   int ready_for_read (int fd, DWORD howlong, int ignra);
808 };
809
810 #if 0
811 /* You can't do this */
812 typedef union
813 {
814   fhandler_normal normal;
815   fhandler_dev_null dev_null;
816   fhandler bare;
817   fhandler_serial tty;
818 } fhandler_union;
819 #else
820 #define fhandler_union fhandler_console
821 #endif
822 struct select_record
823 {
824   int fd;
825   HANDLE h;
826   fhandler_base *fh;
827   BOOL saw_error;
828   BOOL windows_handle;
829   BOOL read_ready, write_ready, except_ready;
830   BOOL read_selected, write_selected, except_selected;
831   int (*startup) (select_record *me, class select_stuff *stuff);
832   int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
833                fd_set *exceptfds);
834   int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
835                  fd_set *exceptfds);
836   void (*cleanup) (select_record *me, class select_stuff *stuff);
837   struct select_record *next;
838
839   select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
840                  fh (in_fh), saw_error (0), windows_handle (0),
841                  read_ready (0), write_ready (0), except_ready (0),
842                  read_selected (0), write_selected (0), except_selected (0),
843                  startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
844                  next (NULL) {}
845 };
846
847 class select_stuff
848 {
849 public:
850   ~select_stuff ();
851   select_stuff (): always_ready (0), windows_used (0), start (0)
852   {
853     memset (device_specific, 0, sizeof (device_specific));
854   }
855   BOOL always_ready, windows_used;
856   select_record start;
857   void *device_specific[FH_NDEV];
858
859   int test_and_set (int i, fd_set *readfds, fd_set *writefds,
860                      fd_set *exceptfds);
861   int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
862   int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
863 };
864
865 uid_t __stdcall get_file_owner (int, const char *);
866 gid_t __stdcall get_file_group (int, const char *);
867 int __stdcall set_console_state_for_spawn ();
868
869 #endif /* _FHANDLER_H_ */