OSDN Git Service

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