OSDN Git Service

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