OSDN Git Service

* fhandler.h (fhandler_console): Remove tcsetpgrp.
[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_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 class fhandler_base
126 {
127 private:
128   DWORD status;
129 public:
130   int cb;
131 private:
132   int access_;
133   HANDLE io_handle;
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 x) { io_handle = x; }
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) { return stat_dev (get_device (), get_unit (), get_namehash (), 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   virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access,
267                        int flags, off_t off);
268   virtual int munmap (HANDLE h, caddr_t addr, size_t len);
269   virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
270
271   void *operator new (size_t, void *p) {return p;}
272
273   virtual void init (HANDLE, DWORD, mode_t);
274
275   virtual int tcflush (int);
276   virtual int tcsendbreak (int);
277   virtual int tcdrain ();
278   virtual int tcflow (int);
279   virtual int tcsetattr (int a, const struct termios *t);
280   virtual int tcgetattr (struct termios *t);
281   virtual int tcsetpgrp (const pid_t pid);
282   virtual int tcgetpgrp ();
283   virtual int is_tty () { return 0; }
284   virtual BOOL is_device () { return TRUE; }
285   virtual char *ptsname () { return NULL;}
286   virtual class fhandler_socket *is_socket () { return 0; }
287   virtual class fhandler_console *is_console () { return 0; }
288   virtual int is_windows () {return 0; }
289
290   virtual int raw_read (void *ptr, size_t ulen);
291   virtual int raw_write (const void *ptr, size_t ulen);
292
293   virtual void fixup_after_exec (HANDLE) {}
294
295   /* Virtual accessor functions to hide the fact
296      that some fd's have two handles. */
297   virtual HANDLE get_handle () const { return io_handle; }
298   virtual HANDLE get_io_handle () const { return io_handle; }
299   virtual HANDLE get_output_handle () const { return io_handle; }
300   virtual BOOL hit_eof () {return FALSE;}
301   virtual select_record *select_read (select_record *s);
302   virtual select_record *select_write (select_record *s);
303   virtual select_record *select_except (select_record *s);
304   virtual int ready_for_read (int fd, DWORD howlong, int ignra);
305   virtual const char * get_native_name ()
306   {
307     return windows_device_names[FHDEVN (status)];
308   }
309   virtual int bg_check (int) {return 1;}
310   void clear_readahead ()
311   {
312     raixput = raixget = ralen = rabuflen = 0;
313     rabuf = NULL;
314   }
315   void operator delete (void *);
316 };
317
318 class fhandler_socket: public fhandler_base
319 {
320 private:
321   int addr_family;
322 public:
323   fhandler_socket (const char *name = 0);
324   fhandler_socket (unsigned int, const char *name = 0);
325   int get_socket () const { return (int) get_handle(); }
326   fhandler_socket * is_socket () { return this; }
327   int write (const void *ptr, size_t len);
328   int read (void *ptr, size_t len);
329   int ioctl (unsigned int cmd, void *);
330   off_t lseek (off_t, int) { return 0; }
331   int close ();
332   void hclose (HANDLE) {close ();}
333
334   select_record *select_read (select_record *s);
335   select_record *select_write (select_record *s);
336   select_record *select_except (select_record *s);
337   int ready_for_read (int fd, DWORD howlong, int ignra);
338   int get_addr_family () {return addr_family;}
339   void set_addr_family (int af) {addr_family = af;}
340 };
341
342 class fhandler_pipe: public fhandler_base
343 {
344 public:
345   fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
346   off_t lseek (off_t offset, int whence);
347   /* This strange test is due to the fact that we can't rely on
348      Windows shells to "do the right thing" with pipes.  Apparently
349      the can keep one end of the pipe open when it shouldn't be. */
350   BOOL is_slow () {return os_being_run == winNT;}
351   select_record *select_read (select_record *s);
352   select_record *select_write (select_record *s);
353   select_record *select_except (select_record *s);
354   int ready_for_read (int fd, DWORD howlong, int ignra);
355 };
356
357 class fhandler_dev_raw: public fhandler_base
358 {
359 protected:
360   char *devbuf;
361   size_t devbufsiz;
362   size_t devbufstart;
363   size_t devbufend;
364   int eom_detected    : 1;
365   int eof_detected    : 1;
366   int lastblk_to_read : 1;
367   int is_writing      : 1;
368   int has_written     : 1;
369   int varblkop        : 1;
370   int unit;
371
372   virtual void clear (void);
373   virtual int writebuf (void);
374
375   /* returns not null, if `win_error' determines an end of media condition */
376   virtual int is_eom(int win_error) = 0;
377   /* returns not null, if `win_error' determines an end of file condition */
378   virtual int is_eof(int win_error) = 0;
379
380   fhandler_dev_raw (DWORD dev, const char *name, int unit);
381
382 public:
383   ~fhandler_dev_raw (void);
384
385   int open (const char *path, int flags, mode_t mode = 0);
386   int close (void);
387
388   int raw_read (void *ptr, size_t ulen);
389   int raw_write (const void *ptr, size_t ulen);
390
391   int fstat (struct stat *buf);
392
393   int dup (fhandler_base *child);
394
395   int ioctl (unsigned int cmd, void *buf);
396 };
397
398 class fhandler_dev_floppy: public fhandler_dev_raw
399 {
400 protected:
401   virtual int is_eom (int win_error);
402   virtual int is_eof (int win_error);
403
404 public:
405   fhandler_dev_floppy (const char *name, int unit);
406
407   virtual int open (const char *path, int flags, mode_t mode = 0);
408   virtual int close (void);
409
410   virtual off_t lseek (off_t offset, int whence);
411
412   virtual int ioctl (unsigned int cmd, void *buf);
413 };
414
415 class fhandler_dev_tape: public fhandler_dev_raw
416 {
417   int norewind;
418   int lasterr;
419
420 protected:
421   virtual void clear (void);
422
423   virtual int is_eom (int win_error);
424   virtual int is_eof (int win_error);
425
426 public:
427   fhandler_dev_tape (const char *name, int unit);
428
429   virtual int open (const char *path, int flags, mode_t mode = 0);
430   virtual int close (void);
431
432   virtual off_t lseek (off_t offset, int whence);
433
434   virtual int fstat (struct stat *buf);
435
436   virtual int dup (fhandler_base *child);
437
438   virtual int ioctl (unsigned int cmd, void *buf);
439
440 private:
441   int tape_write_marks (int marktype, DWORD len);
442   int tape_get_pos (unsigned long *ret);
443   int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
444   int tape_erase (int mode);
445   int tape_prepare (int action);
446   BOOLEAN tape_get_feature (DWORD parm);
447   int tape_get_blocksize (long *min, long *def, long *max, long *cur);
448   int tape_set_blocksize (long count);
449   int tape_status (struct mtget *get);
450   int tape_compression (long count);
451 };
452
453 /* Standard disk file */
454
455 class fhandler_disk_file: public fhandler_base
456 {
457 private:
458   int check_execable_p (const char *path);
459
460 public:
461   fhandler_disk_file (const char *name);
462
463   int open (const char *path, int flags, mode_t mode = 0);
464   int open (path_conv& real_path, int flags, mode_t mode);
465   int close ();
466   int lock (int, struct flock *);
467   BOOL is_device () { return FALSE; }
468   int fstat (struct stat *buf);
469
470   HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
471   int munmap (HANDLE h, caddr_t addr, size_t len);
472   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
473 };
474
475 class fhandler_serial: public fhandler_base
476 {
477 private:
478   unsigned int vmin_;                   /* from termios */
479   unsigned int vtime_;                  /* from termios */
480   pid_t pgrp_;
481
482 public:
483   int overlapped_armed;
484   OVERLAPPED io_status;
485
486   /* Constructor */
487   fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
488
489   int open (const char *path, int flags, mode_t mode);
490   int close ();
491   void init (HANDLE h, DWORD a, mode_t flags);
492   void overlapped_setup ();
493   int dup (fhandler_base *child);
494   int raw_read (void *ptr, size_t ulen);
495   int raw_write (const void *ptr, size_t ulen);
496   int tcsendbreak (int);
497   int tcdrain ();
498   int tcflow (int);
499   int tcsetattr (int a, const struct termios *t);
500   int tcgetattr (struct termios *t);
501   off_t lseek (off_t, int) { return 0; }
502   int tcflush (int);
503   void dump ();
504   int is_tty () { return 1; }
505   void fixup_after_fork (HANDLE parent);
506   void fixup_after_exec (HANDLE);
507
508   /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
509      don't use it for permissions checking.  fhandler_tty_slave does
510      permission checking on pgrps.  */
511   virtual int tcgetpgrp () { return pgrp_; }
512   virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
513   select_record *select_read (select_record *s);
514   select_record *select_write (select_record *s);
515   select_record *select_except (select_record *s);
516   int ready_for_read (int fd, DWORD howlong, int ignra);
517 };
518
519 #define acquire_output_mutex(ms) \
520   __acquire_output_mutex (__PRETTY_FUNCTION__, __LINE__, ms);
521
522 #define release_output_mutex() \
523   __release_output_mutex (__PRETTY_FUNCTION__, __LINE__);
524
525 class tty;
526 class tty_min;
527 class fhandler_termios: public fhandler_base
528 {
529 protected:
530   HANDLE output_handle;
531   virtual void doecho (const void *, DWORD) {};
532   virtual int accept_input () {return 1;};
533 public:
534   tty_min *tc;
535   fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
536   fhandler_base (dev, name, unit)
537   {
538     // nothing to do
539   }
540   HANDLE get_output_handle () const { return output_handle; }
541   int line_edit (const char *rptr, int nread, int always_accept = 0);
542   void set_output_handle (HANDLE h) { output_handle = h; }
543   void tcinit (tty_min *this_tc, int force = FALSE);
544   virtual int is_tty () { return 1; }
545   int tcgetpgrp ();
546   int tcsetpgrp (int pid);
547   void set_ctty (int ttynum, int flags);
548   int bg_check (int sig);
549   virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
550   virtual void __release_output_mutex (const char *fn, int ln) {}
551 };
552
553 /* This is a input and output console handle */
554 class fhandler_console: public fhandler_termios
555 {
556 private:
557
558 /* Output state */
559
560   // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
561 #define normal 1
562 #define gotesc 2
563 #define gotsquare 3
564 #define gotarg1 4
565 #define gotrsquare 5
566 #define gotcommand 6
567 #define gettitle 7
568 #define eattitle 8
569 #define MAXARGS 10
570   int state_;
571   int args_[MAXARGS];
572   int nargs_;
573
574   DWORD default_color;
575
576 /* Output calls */
577
578   BOOL fillin_info ();
579   void clear_screen (int, int, int, int);
580   void scroll_screen (int, int, int, int, int, int);
581   void cursor_set (BOOL, int, int);
582   void cursor_get (int *, int *);
583   void cursor_rel (int, int);
584   const unsigned char * write_normal (unsigned const char*, unsigned const char *);
585   void char_command (char);
586   int output_tcsetattr (int a, const struct termios *t);
587
588 /* Input calls */
589   int igncr_enabled ();
590   int input_tcsetattr (int a, const struct termios *t);
591   void set_cursor_maybe ();
592
593 public:
594
595   fhandler_console (const char *name);
596
597   fhandler_console* is_console () { return this; }
598
599   int open (const char *path, int flags, mode_t mode = 0);
600
601   int write (const void *ptr, size_t len);
602   void doecho (const void *str, DWORD len) { (void) write (str, len); }
603   int read (void *ptr, size_t len);
604   int close ();
605
606   int tcflush (int);
607   int tcsetattr (int a, const struct termios *t);
608   int tcgetattr (struct termios *t);
609
610   /* Special dup as we must dup two handles */
611   int dup (fhandler_base *child);
612
613   int ioctl (unsigned int cmd, void *);
614   void init (HANDLE, DWORD, mode_t);
615
616   select_record *select_read (select_record *s);
617   select_record *select_write (select_record *s);
618   select_record *select_except (select_record *s);
619   int ready_for_read (int fd, DWORD howlong, int ignra);
620   void fixup_after_exec (HANDLE);
621   void set_close_on_exec (int val);
622   void fixup_after_fork (HANDLE parent);
623   void set_input_state ();
624 };
625
626 class fhandler_tty_common: public fhandler_termios
627 {
628 public:
629   fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
630     fhandler_termios (dev, name, unit),
631     ttynum (unit)
632   {
633     // nothing to do
634   }
635   HANDLE output_done_event;     // Raised by master when tty's output buffer
636                                 // written. Write status in tty::write_retval.
637   HANDLE ioctl_request_event;   // Raised by slave to perform ioctl() request.
638                                 // Ioctl() request in tty::cmd/arg.
639   HANDLE ioctl_done_event;      // Raised by master on ioctl() completion.
640                                 // Ioctl() status in tty::ioctl_retval.
641   HANDLE output_mutex;
642   HANDLE inuse;                 // used to indicate that a tty is in use
643
644
645   DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
646   void __release_output_mutex (const char *fn, int ln);
647
648   int ttynum;                   // Master tty num.
649   virtual int dup (fhandler_base *child);
650
651   tty *get_ttyp () { return (tty *)tc; }
652   int get_unit () { return ttynum; }
653
654   int close ();
655   void set_close_on_exec (int val);
656   void fixup_after_fork (HANDLE parent);
657   select_record *select_read (select_record *s);
658   select_record *select_write (select_record *s);
659   select_record *select_except (select_record *s);
660   int ready_for_read (int fd, DWORD howlong, int ignra);
661 };
662
663 class fhandler_tty_slave: public fhandler_tty_common
664 {
665 public:
666   /* Constructor */
667   fhandler_tty_slave (const char *name);
668   fhandler_tty_slave (int, const char *name);
669
670   int open (const char *path, int flags, mode_t mode = 0);
671   int write (const void *ptr, size_t len);
672   int read (void *ptr, size_t len);
673   void init (HANDLE, DWORD, mode_t);
674
675   int tcsetattr (int a, const struct termios *t);
676   int tcgetattr (struct termios *t);
677   int tcflush (int);
678   int ioctl (unsigned int cmd, void *);
679
680   off_t lseek (off_t, int) { return 0; }
681 };
682
683 class fhandler_pty_master: public fhandler_tty_common
684 {
685   int pktmode;                  // non-zero if pty in a packet mode.
686 public:
687   int need_nl;                  // Next read should start with \n
688
689   /* Constructor */
690   fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
691
692   int process_slave_output (char *buf, size_t len, int pktmode_on);
693   void doecho (const void *str, DWORD len);
694   int accept_input ();
695   int open (const char *path, int flags, mode_t mode = 0);
696   int write (const void *ptr, size_t len);
697   int read (void *ptr, size_t len);
698   int close ();
699
700   int tcsetattr (int a, const struct termios *t);
701   int tcgetattr (struct termios *t);
702   int tcflush (int);
703   int ioctl (unsigned int cmd, void *);
704
705   off_t lseek (off_t, int) { return 0; }
706   char *ptsname ();
707
708   void set_close_on_exec (int val);
709   BOOL hit_eof ();
710 };
711
712 class fhandler_tty_master: public fhandler_pty_master
713 {
714 public:
715   /* Constructor */
716   fhandler_tty_master (const char *name, int unit);
717   fhandler_console *console;    // device handler to perform real i/o.
718   HANDLE hThread;               // process_output thread handle.
719
720   int init (int);
721   int init_console ();
722   void fixup_after_fork (HANDLE parent);
723   void fixup_after_exec (HANDLE);
724 };
725
726 class fhandler_dev_null: public fhandler_base
727 {
728 public:
729   fhandler_dev_null (const char *name);
730
731   void dump ();
732   select_record *select_read (select_record *s);
733   select_record *select_write (select_record *s);
734   select_record *select_except (select_record *s);
735 };
736
737 class fhandler_dev_zero: public fhandler_base
738 {
739 public:
740   fhandler_dev_zero (const char *name);
741   int open (const char *path, int flags, mode_t mode = 0);
742   int write (const void *ptr, size_t len);
743   int read (void *ptr, size_t len);
744   off_t lseek (off_t offset, int whence);
745   int close (void);
746
747   void dump ();
748 };
749
750 class fhandler_dev_random: public fhandler_base
751 {
752 protected:
753   int unit;
754   HCRYPTPROV crypt_prov;
755   long pseudo;
756
757   BOOL crypt_gen_random (void *ptr, size_t len);
758   int pseudo_write (const void *ptr, size_t len);
759   int pseudo_read (void *ptr, size_t len);
760
761 public:
762   fhandler_dev_random (const char *name, int unit);
763   int get_unit () { return unit; }
764   int open (const char *path, int flags, mode_t mode = 0);
765   int write (const void *ptr, size_t len);
766   int read (void *ptr, size_t len);
767   off_t lseek (off_t offset, int whence);
768   int close (void);
769   int dup (fhandler_base *child);
770
771   void dump ();
772 };
773
774 class fhandler_dev_mem: public fhandler_base
775 {
776 protected:
777   int unit;
778   DWORD mem_size;
779   DWORD pos;
780
781 public:
782   fhandler_dev_mem (const char *name, int unit);
783   ~fhandler_dev_mem (void);
784
785   int open (const char *path, int flags, mode_t mode = 0);
786   int write (const void *ptr, size_t ulen);
787   int read (void *ptr, size_t ulen);
788   off_t lseek (off_t offset, int whence);
789   int close (void);
790   int fstat (struct stat *buf);
791   int dup (fhandler_base *child);
792
793   HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
794   int munmap (HANDLE h, caddr_t addr, size_t len);
795   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
796
797   void dump ();
798 } ;
799  
800 class fhandler_dev_clipboard: public fhandler_base
801 {
802 public:
803   fhandler_dev_clipboard (const char *name);
804   int is_windows (void) { return 1; }
805   int open (const char *path, int flags, mode_t mode = 0);
806   int write (const void *ptr, size_t len);
807   int read (void *ptr, size_t len);
808   off_t lseek (off_t offset, int whence);
809   int close (void);
810
811   void dump ();
812 };
813
814 class fhandler_windows: public fhandler_base
815 {
816 private:
817   HWND hWnd_;   // the window whose messages are to be retrieved by read() call
818   int method_;  // write method (Post or Send)
819 public:
820   fhandler_windows (const char *name = 0);
821   int is_windows (void) { return 1; }
822   int open (const char *path, int flags, mode_t mode = 0);
823   int write (const void *ptr, size_t len);
824   int read (void *ptr, size_t len);
825   int ioctl (unsigned int cmd, void *);
826   off_t lseek (off_t, int) { return 0; }
827   int close (void) { return 0; }
828
829   void set_close_on_exec (int val);
830   void fixup_after_fork (HANDLE parent);
831   select_record *select_read (select_record *s);
832   select_record *select_write (select_record *s);
833   select_record *select_except (select_record *s);
834   int ready_for_read (int fd, DWORD howlong, int ignra);
835 };
836
837 #if 0
838 /* You can't do this */
839 typedef union
840 {
841   fhandler_normal normal;
842   fhandler_dev_null dev_null;
843   fhandler bare;
844   fhandler_serial tty;
845 } fhandler_union;
846 #else
847 #define fhandler_union fhandler_console
848 #endif
849 struct select_record
850 {
851   int fd;
852   HANDLE h;
853   fhandler_base *fh;
854   BOOL saw_error;
855   BOOL windows_handle;
856   BOOL read_ready, write_ready, except_ready;
857   BOOL read_selected, write_selected, except_selected;
858   int (*startup) (select_record *me, class select_stuff *stuff);
859   int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
860                fd_set *exceptfds);
861   int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
862                  fd_set *exceptfds);
863   void (*cleanup) (select_record *me, class select_stuff *stuff);
864   struct select_record *next;
865
866   select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
867                  fh (in_fh), saw_error (0), windows_handle (0),
868                  read_ready (0), write_ready (0), except_ready (0),
869                  read_selected (0), write_selected (0), except_selected (0),
870                  startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
871                  next (NULL) {}
872 };
873
874 class select_stuff
875 {
876 public:
877   ~select_stuff ();
878   select_stuff (): always_ready (0), windows_used (0), start (0)
879   {
880     memset (device_specific, 0, sizeof (device_specific));
881   }
882   BOOL always_ready, windows_used;
883   select_record start;
884   void *device_specific[FH_NDEV];
885
886   int test_and_set (int i, fd_set *readfds, fd_set *writefds,
887                      fd_set *exceptfds);
888   int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
889   int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
890 };
891
892 uid_t __stdcall get_file_owner (int, const char *);
893 gid_t __stdcall get_file_group (int, const char *);
894 int __stdcall set_console_state_for_spawn ();
895
896 #endif /* _FHANDLER_H_ */