3 Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
14 #include <sys/ioctl.h>
18 Code is located in fhandler.cc unless another file name is given.
20 fhandler_base normal I/O
23 fhandler_serial Adds vmin and vtime.
24 fhandler_dev_null Not really I/O
25 fhandler_dev_zero Faked
27 fhandler_dev_raw (fhandler_raw.cc)
28 fhandler_dev_floppy (fhandler_floppy.cc)
29 fhandler_dev_tape (fhandler_tape.cc)
32 fhandler_socket (net.cc)
34 fhandler_tty_slave (tty.cc)
35 fhandler_pty_master (tty.cc)
36 fhandler_tty_master (tty.cc)
38 fhandler_console Out with ansi control. (console.cc)
40 fhandler_windows Windows messages I/O (fhandler_windows.cc)
42 fhandler_dev_random /dev/[u]random implementation (fhandler_random.cc)
44 fhandler_proc Interesting possibility, not implemented yet
49 FH_RBINARY = 0x00001000, /* binary read mode */
50 FH_WBINARY = 0x00002000, /* binary write mode */
51 FH_CLOEXEC = 0x00004000, /* close-on-exec */
52 FH_RBINSET = 0x00008000, /* binary read mode has been explicitly set */
53 FH_WBINSET = 0x00010000, /* binary write mode has been explicitly set */
54 FH_APPEND = 0x00020000, /* always append */
55 FH_ASYNC = 0x00040000, /* async I/O */
56 FH_HADEOF = 0x00080000, /* EOF seen */
58 FH_SYMLINK = 0x00100000, /* is a symlink */
59 FH_EXECABL = 0x00200000, /* file looked like it would run:
60 * ends in .exe or .bat or begins with #! */
61 FH_W95LSBUG= 0x00400000, /* set when lseek is called as a flag that
62 * _write should check if we've moved beyond
63 * EOF, zero filling if so. */
64 FH_NOFRNAME= 0x00800000, /* Set if shouldn't free unix_path_name_ and
65 windows_path_name_ on destruction. */
66 FH_NOEINTR = 0x01000000, /* Set if I/O should be uninterruptible. */
67 FH_FFIXUP = 0x02000000, /* Set if need to fixup after fork. */
68 FH_LOCAL = 0x04000000, /* File is unix domain socket */
69 FH_FIFO = 0x08000000, /* File is FIFO */
70 FH_HASACLS = 0x40000000, /* True if fs of file has ACLS */
75 FH_CONSOLE = 0x00000001, /* is a console */
76 FH_CONIN = 0x00000002, /* console input */
77 FH_CONOUT = 0x00000003, /* console output */
78 FH_TTYM = 0x00000004, /* is a tty master */
79 FH_TTYS = 0x00000005, /* is a tty slave */
80 FH_PTYM = 0x00000006, /* is a pty master */
81 FH_SERIAL = 0x00000007, /* is a serial port */
82 FH_PIPE = 0x00000008, /* is a pipe */
83 FH_PIPER = 0x00000009, /* read end of a pipe */
84 FH_PIPEW = 0x0000000a, /* write end of a pipe */
85 FH_SOCKET = 0x0000000b, /* is a socket */
86 FH_WINDOWS = 0x0000000c, /* is a window */
88 FH_SLOW = 0x00000010, /* "slow" device if below this */
91 FH_DISK = 0x00000010, /* is a disk */
92 FH_FLOPPY = 0x00000011, /* is a floppy */
93 FH_TAPE = 0x00000012, /* is a tape */
94 FH_NULL = 0x00000013, /* is the null device */
95 FH_ZERO = 0x00000014, /* is the zero device */
96 FH_RANDOM = 0x00000015, /* is a random device */
98 FH_NDEV = 0x00000016, /* Maximum number of devices */
99 FH_DEVMASK = 0x00000fff, /* devices live here */
103 #define FHDEVN(n) ((n) & FH_DEVMASK)
104 #define FHISSETF(x) __ISSETF (this, x, FH)
105 #define FHSETF(x) __SETF (this, x, FH)
106 #define FHCLEARF(x) __CLEARF (this, x, FH)
107 #define FHCONDSETF(n, x) __CONDSETF(n, this, x, FH)
111 extern const char *windows_device_names[];
112 extern struct __cygwin_perfile *perfile_table;
113 #define __fmode (*(user_data->fmode_ptr))
117 class fhandler_disk_file;
129 int rpos_; /* Used in text reading */
132 unsigned long namehash_; /* hashed filename, used as inode num */
134 /* Full unix path name of this file */
135 /* File open flags from open () and fcntl () calls */
139 char *rabuf; /* used for crlf conversion in text files */
145 char *unix_path_name_;
146 char *win32_path_name_;
149 void set_name (const char * unix_path, const char * win32_path = NULL,
152 virtual fhandler_base& operator =(fhandler_base &x)
154 memcpy (this, &x, sizeof *this);
155 unix_path_name_ = x.unix_path_name_ ? strdup (x.unix_path_name_) : NULL;
156 win32_path_name_ = x.win32_path_name_ ? strdup (x.win32_path_name_) : NULL;
159 fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
160 virtual ~fhandler_base ();
162 /* Non-virtual simple accessor functions. */
163 void set_io_handle (HANDLE);
165 void set_cb (size_t size) { cb = size; }
166 DWORD get_device () { return status & FH_DEVMASK; }
167 virtual int get_unit () { return 0; }
168 virtual BOOL is_slow () { return get_device () < FH_SLOW; }
170 int get_access () { return access_; }
171 void set_access (int x) { access_ = x; }
173 int get_async () { return FHISSETF (ASYNC); }
174 void set_async (int x) { FHCONDSETF (x, ASYNC); }
176 int get_flags () { return openflags_; }
177 void set_flags (int x) { openflags_ = x; }
179 int get_w_binary () { return FHISSETF (WBINARY); }
180 int get_r_binary () { return FHISSETF (RBINARY); }
182 int get_w_binset () { return FHISSETF (WBINSET); }
183 int get_r_binset () { return FHISSETF (RBINSET); }
185 void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
186 void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
188 int get_default_fmode (int flags);
190 int get_r_no_interrupt () { return FHISSETF (NOEINTR); }
191 void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); }
193 int get_close_on_exec () { return FHISSETF (CLOEXEC); }
194 int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); }
196 void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); }
197 int get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); }
199 int get_need_fork_fixup () { return FHISSETF (FFIXUP); }
200 void set_need_fork_fixup () { FHSETF (FFIXUP); }
202 virtual void set_close_on_exec (int val);
203 virtual void fixup_after_fork (HANDLE parent);
205 int get_symlink_p () { return FHISSETF (SYMLINK); }
206 void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); }
207 void set_symlink_p () { FHSETF (SYMLINK); }
209 int get_socket_p () { return FHISSETF (LOCAL); }
210 void set_socket_p (int val) { FHCONDSETF (val, LOCAL); }
211 void set_socket_p () { FHSETF (LOCAL); }
213 int get_execable_p () { return FHISSETF (EXECABL); }
214 void set_execable_p (int val) { FHCONDSETF (val, EXECABL); }
215 void set_execable_p () { FHSETF (EXECABL); }
217 int get_append_p () { return FHISSETF (APPEND); }
218 void set_append_p (int val) { FHCONDSETF (val, APPEND); }
219 void set_append_p () { FHSETF (APPEND); }
221 int get_readahead_valid () { return raixget < ralen; }
222 int puts_readahead (const char *s, size_t len = (size_t) -1);
223 int put_readahead (char value);
225 int get_readahead ();
226 int peek_readahead (int queryput = 0);
228 int eat_readahead (int n);
230 void set_readahead_valid (int val, int ch = -1);
232 int get_readahead_into_buffer (char *buf, size_t buflen);
234 int has_acls () { return FHISSETF (HASACLS); }
235 void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
237 int no_free_names () { return FHISSETF (NOFRNAME); }
238 void set_no_free_names (int val) { FHCONDSETF (val, NOFRNAME); }
239 void set_no_free_names () { FHSETF (NOFRNAME); }
241 const char *get_name () { return unix_path_name_; }
242 const char *get_win32_name () { return win32_path_name_; }
243 unsigned long get_namehash () { return namehash_; }
245 virtual void hclose (HANDLE h) {CloseHandle (h);}
246 virtual void set_inheritance (HANDLE &h, int not_inheriting, const char *name = NULL);
248 /* fixup fd possibly non-inherited handles after fork */
249 void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
251 /* Potentially overridden virtual functions. */
252 virtual int open (const char *, int flags, mode_t mode = 0)
254 return open (flags, mode);
256 virtual int open (int flags, mode_t mode = 0);
257 virtual int close ();
258 virtual int fstat (struct stat *buf);
259 virtual int ioctl (unsigned int cmd, void *);
260 virtual char const * ttyname () { return get_name(); }
261 virtual int read (void *ptr, size_t len);
262 virtual int write (const void *ptr, size_t len);
263 virtual off_t lseek (off_t offset, int whence);
264 virtual int lock (int, struct flock *);
265 virtual void dump ();
266 virtual int dup (fhandler_base *child);
268 void *operator new (size_t, void *p) {return p;}
270 virtual void init (HANDLE, DWORD, mode_t);
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; }
287 virtual int raw_read (void *ptr, size_t ulen);
288 virtual int raw_write (const void *ptr, size_t ulen);
290 /* Function to save state of a fhandler_base into memory. */
291 virtual int linearize (unsigned char *);
292 /* Function to de-linearize into a fd */
293 virtual int de_linearize (const char *, const char *, const char *);
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 ()
307 return windows_device_names[FHDEVN (status)];
309 virtual int bg_check (int) {return 1;}
312 class fhandler_socket: public fhandler_base
317 fhandler_socket (const char *name = 0);
318 fhandler_socket (unsigned int, const char *name = 0);
320 int get_socket () const { return (int) get_handle(); }
321 fhandler_socket * is_socket () { return this; }
322 int write (const void *ptr, size_t len);
323 int read (void *ptr, size_t len);
324 int ioctl (unsigned int cmd, void *);
325 off_t lseek (off_t, int) { return 0; }
327 void hclose (HANDLE) {close ();}
329 select_record *select_read (select_record *s);
330 select_record *select_write (select_record *s);
331 select_record *select_except (select_record *s);
332 int ready_for_read (int fd, DWORD howlong, int ignra);
333 int get_addr_family () {return addr_family;}
334 void set_addr_family (int af) {addr_family = af;}
337 class fhandler_pipe: public fhandler_base
340 fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
341 off_t lseek (off_t offset, int whence);
342 /* This strange test is due to the fact that we can't rely on
343 Windows shells to "do the right thing" with pipes. Apparently
344 the can keep one end of the pipe open when it shouldn't be. */
345 BOOL is_slow () {return os_being_run == winNT;}
346 select_record *select_read (select_record *s);
347 select_record *select_write (select_record *s);
348 select_record *select_except (select_record *s);
349 int ready_for_read (int fd, DWORD howlong, int ignra);
352 class fhandler_dev_raw: public fhandler_base
359 int eom_detected : 1;
360 int eof_detected : 1;
361 int lastblk_to_read : 1;
367 virtual void clear (void);
368 virtual int writebuf (void);
370 /* returns not null, if `win_error' determines an end of media condition */
371 virtual int is_eom(int win_error) = 0;
372 /* returns not null, if `win_error' determines an end of file condition */
373 virtual int is_eof(int win_error) = 0;
375 fhandler_dev_raw (DWORD dev, const char *name, int unit);
378 ~fhandler_dev_raw (void);
380 /* Function to de-linearize into a fd */
381 int de_linearize (const char *, const char *, const char *);
383 int open (const char *path, int flags, mode_t mode = 0);
386 int raw_read (void *ptr, size_t ulen);
387 int raw_write (const void *ptr, size_t ulen);
389 int fstat (struct stat *buf);
391 int dup (fhandler_base *child);
393 int ioctl (unsigned int cmd, void *buf);
396 class fhandler_dev_floppy: public fhandler_dev_raw
399 virtual int is_eom (int win_error);
400 virtual int is_eof (int win_error);
403 fhandler_dev_floppy (const char *name, int unit);
405 virtual int open (const char *path, int flags, mode_t mode = 0);
406 virtual int close (void);
408 virtual off_t lseek (off_t offset, int whence);
410 virtual int ioctl (unsigned int cmd, void *buf);
413 class fhandler_dev_tape: public fhandler_dev_raw
419 virtual void clear (void);
421 virtual int is_eom (int win_error);
422 virtual int is_eof (int win_error);
425 fhandler_dev_tape (const char *name, int unit);
427 virtual int open (const char *path, int flags, mode_t mode = 0);
428 virtual int close (void);
430 virtual off_t lseek (off_t offset, int whence);
432 virtual int fstat (struct stat *buf);
434 virtual int dup (fhandler_base *child);
436 virtual int ioctl (unsigned int cmd, void *buf);
439 int tape_write_marks (int marktype, DWORD len);
440 int tape_get_pos (unsigned long *ret);
441 int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
442 int tape_erase (int mode);
443 int tape_prepare (int action);
444 BOOLEAN tape_get_feature (DWORD parm);
445 int tape_get_blocksize (long *min, long *def, long *max, long *cur);
446 int tape_set_blocksize (long count);
447 int tape_status (struct mtget *get);
448 int tape_compression (long count);
451 /* Standard disk file */
453 class fhandler_disk_file: public fhandler_base
456 int check_execable_p (const char *path);
459 fhandler_disk_file (const char *name);
461 int open (const char *path, int flags, mode_t mode = 0);
462 int open (path_conv& real_path, int flags, mode_t mode);
464 int lock (int, struct flock *);
465 BOOL is_device () { return FALSE; }
466 int fstat (struct stat *buf);
469 class fhandler_serial: public fhandler_base
472 unsigned int vmin_; /* from termios */
473 unsigned int vtime_; /* from termios */
477 int overlapped_armed;
478 OVERLAPPED io_status;
481 fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
483 int open (const char *path, int flags, mode_t mode);
485 void init (HANDLE h, DWORD a, mode_t flags);
486 void overlapped_setup ();
487 int dup (fhandler_base *child);
488 int raw_read (void *ptr, size_t ulen);
489 int raw_write (const void *ptr, size_t ulen);
490 int tcsendbreak (int);
493 int tcsetattr (int a, const struct termios *t);
494 int tcgetattr (struct termios *t);
495 off_t lseek (off_t, int) { return 0; }
498 int is_tty () { return 1; }
499 void fixup_after_fork (HANDLE parent);
500 int de_linearize (const char *, const char *, const char *);
502 /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
503 don't use it for permissions checking. fhandler_tty_slave does
504 permission checking on pgrps. */
505 virtual int tcgetpgrp () { return pgrp_; }
506 virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
507 select_record *select_read (select_record *s);
508 select_record *select_write (select_record *s);
509 select_record *select_except (select_record *s);
510 int ready_for_read (int fd, DWORD howlong, int ignra);
513 class fhandler_termios: public fhandler_base
516 HANDLE output_handle;
517 virtual void doecho (const void *, DWORD) {};
518 virtual int accept_input () {return 1;};
521 fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
522 fhandler_base (dev, name, unit)
526 HANDLE restart_output_event;
527 HANDLE get_output_handle () const { return output_handle; }
528 int line_edit (const char *rptr, int nread, int always_accept = 0);
529 void set_output_handle (HANDLE h) { output_handle = h; }
530 void tcinit (tty_min *this_tc, int force = FALSE);
531 virtual int is_tty () { return 1; }
533 int tcsetpgrp (int pid);
534 void set_ctty (int ttynum, int flags);
535 int bg_check (int sig);
538 /* This is a input and output console handle */
539 class fhandler_console: public fhandler_termios
545 // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
564 void clear_screen (int, int, int, int);
565 void scroll_screen (int, int, int, int, int, int);
566 void cursor_set (BOOL, int, int);
567 void cursor_get (int *, int *);
568 void cursor_rel (int, int);
569 const unsigned char * write_normal (unsigned const char*, unsigned const char *);
570 void char_command (char);
571 int output_tcsetattr (int a, const struct termios *t);
574 int igncr_enabled ();
575 int input_tcsetattr (int a, const struct termios *t);
576 void set_cursor_maybe ();
580 fhandler_console (const char *name);
582 fhandler_console* is_console () { return this; }
584 int open (const char *path, int flags, mode_t mode = 0);
586 int write (const void *ptr, size_t len);
587 void doecho (const void *str, DWORD len) { (void) write (str, len); }
588 int read (void *ptr, size_t len);
592 int tcsetattr (int a, const struct termios *t);
593 int tcgetattr (struct termios *t);
595 int tcsetpgrp (const pid_t pid) { tc->pgid = pid; return 0; }
597 /* Special dup as we must dup two handles */
598 int dup (fhandler_base *child);
600 int ioctl (unsigned int cmd, void *);
601 void init (HANDLE, DWORD, mode_t);
603 select_record *select_read (select_record *s);
604 select_record *select_write (select_record *s);
605 select_record *select_except (select_record *s);
606 int ready_for_read (int fd, DWORD howlong, int ignra);
607 int de_linearize (const char *, const char *, const char *);
608 void set_close_on_exec (int val);
609 void fixup_after_fork (HANDLE parent);
610 void set_input_state ()
612 if (TTYISSETF (RSTCONS))
613 input_tcsetattr (0, &tc->ti);
617 class fhandler_tty_common: public fhandler_termios
620 fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
621 fhandler_termios (dev, name, unit),
626 HANDLE output_done_event; // Raised by master when tty's output buffer
627 // written. Write status in tty::write_retval.
628 HANDLE ioctl_request_event; // Raised by slave to perform ioctl() request.
629 // Ioctl() request in tty::cmd/arg.
630 HANDLE ioctl_done_event; // Raised by master on ioctl() completion.
631 // Ioctl() status in tty::ioctl_retval.
633 HANDLE inuse; // used to indicate that a tty is in use
636 DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
637 void __release_output_mutex (const char *fn, int ln);
639 int ttynum; // Master tty num.
640 virtual int dup (fhandler_base *child);
642 tty *get_ttyp () { return (tty *)tc; }
643 int get_unit () { return ttynum; }
646 void set_close_on_exec (int val);
647 void fixup_after_fork (HANDLE parent);
648 select_record *select_read (select_record *s);
649 select_record *select_write (select_record *s);
650 select_record *select_except (select_record *s);
651 int ready_for_read (int fd, DWORD howlong, int ignra);
654 class fhandler_tty_slave: public fhandler_tty_common
658 fhandler_tty_slave (const char *name);
659 fhandler_tty_slave (int, const char *name);
661 int open (const char *path, int flags, mode_t mode = 0);
662 int write (const void *ptr, size_t len);
663 int read (void *ptr, size_t len);
664 void init (HANDLE, DWORD, mode_t);
666 int tcsetattr (int a, const struct termios *t);
667 int tcgetattr (struct termios *t);
669 int ioctl (unsigned int cmd, void *);
671 off_t lseek (off_t, int) { return 0; }
674 class fhandler_pty_master: public fhandler_tty_common
676 int pktmode; // non-zero if pty in a packet mode.
678 int need_nl; // Next read should start with \n
681 fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
683 int process_slave_output (char *buf, size_t len, int pktmode_on);
684 void doecho (const void *str, DWORD len);
686 int open (const char *path, int flags, mode_t mode = 0);
687 int write (const void *ptr, size_t len);
688 int read (void *ptr, size_t len);
691 int tcsetattr (int a, const struct termios *t);
692 int tcgetattr (struct termios *t);
694 int ioctl (unsigned int cmd, void *);
696 off_t lseek (off_t, int) { return 0; }
699 void set_close_on_exec (int val);
700 void fixup_after_fork (HANDLE parent);
704 class fhandler_tty_master: public fhandler_pty_master
708 fhandler_tty_master (const char *name, int unit);
709 fhandler_console *console; // device handler to perform real i/o.
710 HANDLE hThread; // process_output thread handle.
714 void fixup_after_fork (HANDLE parent);
715 int de_linearize (const char *, const char *, const char *);
718 class fhandler_dev_null: public fhandler_base
721 fhandler_dev_null (const char *name);
724 select_record *select_read (select_record *s);
725 select_record *select_write (select_record *s);
726 select_record *select_except (select_record *s);
729 class fhandler_dev_zero: public fhandler_base
732 fhandler_dev_zero (const char *name);
733 int open (const char *path, int flags, mode_t mode = 0);
734 int write (const void *ptr, size_t len);
735 int read (void *ptr, size_t len);
736 off_t lseek (off_t offset, int whence);
742 class fhandler_dev_random: public fhandler_base
746 HCRYPTPROV crypt_prov;
749 BOOL crypt_gen_random (void *ptr, size_t len);
750 int pseudo_write (const void *ptr, size_t len);
751 int pseudo_read (void *ptr, size_t len);
754 fhandler_dev_random (const char *name, int unit);
755 int get_unit () { return unit; }
756 int open (const char *path, int flags, mode_t mode = 0);
757 int write (const void *ptr, size_t len);
758 int read (void *ptr, size_t len);
759 off_t lseek (off_t offset, int whence);
761 int dup (fhandler_base *child);
766 class fhandler_windows: public fhandler_base
769 HWND hWnd_; // the window whose messages are to be retrieved by read() call
770 int method_; // write method (Post or Send)
772 fhandler_windows (const char *name = 0);
773 int is_windows (void) { return 1; }
774 int open (const char *path, int flags, mode_t mode = 0);
775 int write (const void *ptr, size_t len);
776 int read (void *ptr, size_t len);
777 int ioctl (unsigned int cmd, void *);
778 off_t lseek (off_t, int) { return 0; }
779 int close (void) { return 0; }
781 void set_close_on_exec (int val);
782 void fixup_after_fork (HANDLE parent);
783 select_record *select_read (select_record *s);
784 select_record *select_write (select_record *s);
785 select_record *select_except (select_record *s);
786 int ready_for_read (int fd, DWORD howlong, int ignra);
790 /* You can't do this */
793 fhandler_normal normal;
794 fhandler_dev_null dev_null;
799 #define fhandler_union fhandler_console
808 BOOL read_ready, write_ready, except_ready;
809 BOOL read_selected, write_selected, except_selected;
810 int (*startup) (select_record *me, class select_stuff *stuff);
811 int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
813 int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
815 void (*cleanup) (select_record *me, class select_stuff *stuff);
816 struct select_record *next;
818 select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
819 fh (in_fh), saw_error (0), windows_handle (0),
820 read_ready (0), write_ready (0), except_ready (0),
821 read_selected (0), write_selected (0), except_selected (0),
822 startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
830 select_stuff (): always_ready (0), windows_used (0), start (0)
832 memset (device_specific, 0, sizeof (device_specific));
834 BOOL always_ready, windows_used;
836 void *device_specific[FH_NDEV];
838 int test_and_set (int i, fd_set *readfds, fd_set *writefds,
840 int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
841 int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
844 uid_t __stdcall get_file_owner (int, const char *);
845 gid_t __stdcall get_file_group (int, const char *);
847 #endif /* _FHANDLER_H_ */