OSDN Git Service

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