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_proc Interesting possibility, not implemented yet
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 */
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 */
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 */
86 FH_SLOW = 0x00000010, /* "slow" device if below this */
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 */
95 FH_NDEV = 0x00000015, /* Maximum number of devices */
96 FH_DEVMASK = 0x00000fff, /* devices live here */
100 #define FHDEVN(n) ((n) & FH_DEVMASK)
101 #define FHISSETF(x) __ISSETF (this, x, FH)
102 #define FHSETF(x) __SETF (this, x, FH)
103 #define FHCLEARF(x) __CLEARF (this, x, FH)
104 #define FHCONDSETF(n, x) __CONDSETF(n, this, x, FH)
108 extern const char *windows_device_names[];
109 #define __fmode (*(user_data->fmode_ptr))
113 class fhandler_disk_file;
125 int rpos_; /* Used in text reading */
128 unsigned long namehash_; /* hashed filename, used as inode num */
130 /* Full unix path name of this file */
131 /* File open flags from open () and fcntl () calls */
135 char *rabuf; /* used for crlf conversion in text files */
141 char *unix_path_name_;
142 char *win32_path_name_;
145 void set_name (const char *unix, const char *win32 = NULL, int unit = 0);
147 virtual fhandler_base& operator =(fhandler_base &x)
149 memcpy (this, &x, sizeof *this);
150 unix_path_name_ = x.unix_path_name_ ? strdup (x.unix_path_name_) : NULL;
151 win32_path_name_ = x.win32_path_name_ ? strdup (x.win32_path_name_) : NULL;
154 fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
155 virtual ~fhandler_base ();
157 /* Non-virtual simple accessor functions. */
158 void set_io_handle (HANDLE);
160 void set_cb (size_t size) { cb = size; }
161 DWORD get_device () { return status & FH_DEVMASK; }
162 virtual int get_unit () { return 0; }
163 virtual BOOL is_slow () { return get_device () < FH_SLOW; }
165 int get_access () { return access_; }
166 void set_access (int x) { access_ = x; }
168 int get_async () { return FHISSETF (ASYNC); }
169 void set_async (int x) { FHCONDSETF (x, ASYNC); }
171 int get_flags () { return openflags_; }
172 void set_flags (int x) { openflags_ = x; }
174 int get_w_binary () { return FHISSETF (WBINARY); }
175 int get_r_binary () { return FHISSETF (RBINARY); }
177 int get_w_binset () { return FHISSETF (WBINSET); }
178 int get_r_binset () { return FHISSETF (RBINSET); }
180 void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
181 void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
183 int get_r_no_interrupt () { return FHISSETF (NOEINTR); }
184 void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); }
186 int get_close_on_exec () { return FHISSETF (CLOEXEC); }
187 int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); }
189 void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); }
190 int get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); }
192 int get_need_fork_fixup () { return FHISSETF (FFIXUP); }
193 void set_need_fork_fixup () { FHSETF (FFIXUP); }
195 virtual void set_close_on_exec (int val);
196 virtual void fixup_after_fork (HANDLE parent);
198 int get_symlink_p () { return FHISSETF (SYMLINK); }
199 void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); }
200 void set_symlink_p () { FHSETF (SYMLINK); }
202 int get_socket_p () { return FHISSETF (LOCAL); }
203 void set_socket_p (int val) { FHCONDSETF (val, LOCAL); }
204 void set_socket_p () { FHSETF (LOCAL); }
206 int get_execable_p () { return FHISSETF (EXECABL); }
207 void set_execable_p (int val) { FHCONDSETF (val, EXECABL); }
208 void set_execable_p () { FHSETF (EXECABL); }
210 int get_append_p () { return FHISSETF (APPEND); }
211 void set_append_p (int val) { FHCONDSETF (val, APPEND); }
212 void set_append_p () { FHSETF (APPEND); }
214 int get_readahead_valid () { return raixget < ralen; }
215 int puts_readahead (const char *s, size_t len = (size_t) -1);
216 int put_readahead (char value);
218 int get_readahead ();
219 int peek_readahead (int queryput = 0);
221 int eat_readahead (int n);
223 void set_readahead_valid (int val, int ch = -1);
225 int get_readahead_into_buffer (char *buf, size_t buflen);
227 int has_acls () { return FHISSETF (HASACLS); }
228 void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
230 int no_free_names () { return FHISSETF (NOFRNAME); }
231 void set_no_free_names (int val) { FHCONDSETF (val, NOFRNAME); }
232 void set_no_free_names () { FHSETF (NOFRNAME); }
234 const char *get_name () { return unix_path_name_; }
235 const char *get_win32_name () { return win32_path_name_; }
236 unsigned long get_namehash () { return namehash_; }
238 virtual void hclose (HANDLE h) {CloseHandle (h);}
239 virtual void set_inheritance (HANDLE &h, int not_inheriting, const char *name = NULL);
241 /* fixup fd possibly non-inherited handles after fork */
242 void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
244 /* Potentially overridden virtual functions. */
245 virtual int open (const char *, int flags, mode_t mode = 0)
247 return open (flags, mode);
249 virtual int open (int flags, mode_t mode = 0);
250 virtual int close ();
251 virtual int fstat (struct stat *buf);
252 virtual int ioctl (unsigned int cmd, void *);
253 virtual char const * ttyname () { return get_name(); }
254 virtual int read (void *ptr, size_t len);
255 virtual int write (const void *ptr, size_t len);
256 virtual off_t lseek (off_t offset, int whence);
257 virtual int lock (int, struct flock *);
258 virtual void dump ();
259 virtual int dup (fhandler_base *child);
261 void *operator new (size_t, void *p) {return p;}
263 virtual void init (HANDLE, DWORD, mode_t);
265 virtual int tcflush (int);
266 virtual int tcsendbreak (int);
267 virtual int tcdrain ();
268 virtual int tcflow (int);
269 virtual int tcsetattr (int a, const struct termios *t);
270 virtual int tcgetattr (struct termios *t);
271 virtual int tcsetpgrp (const pid_t pid);
272 virtual int tcgetpgrp ();
273 virtual int is_tty () { return 0; }
274 virtual BOOL is_device () { return TRUE; }
275 virtual char *ptsname () { return NULL;}
276 virtual class fhandler_socket *is_socket () { return 0; }
277 virtual class fhandler_console *is_console () { return 0; }
278 virtual int is_windows () {return 0; }
280 virtual int raw_read (void *ptr, size_t ulen);
281 virtual int raw_write (const void *ptr, size_t ulen);
283 /* Function to save state of a fhandler_base into memory. */
284 virtual int linearize (unsigned char *);
285 /* Function to de-linearize into a fd */
286 virtual int de_linearize (const char *, const char *, const char *);
288 /* Virtual accessor functions to hide the fact
289 that some fd's have two handles. */
290 virtual HANDLE get_handle () const { return io_handle; }
291 virtual HANDLE get_io_handle () const { return io_handle; }
292 virtual HANDLE get_output_handle () const { return io_handle; }
293 virtual BOOL hit_eof () {return FALSE;}
294 virtual select_record *select_read (select_record *s);
295 virtual select_record *select_write (select_record *s);
296 virtual select_record *select_except (select_record *s);
297 virtual int ready_for_read (int fd, DWORD howlong, int ignra);
298 virtual const char * get_native_name ()
300 return windows_device_names[FHDEVN (status)];
302 virtual int bg_check (int) {return 1;}
305 class fhandler_socket: public fhandler_base
310 fhandler_socket (const char *name = 0);
311 fhandler_socket (unsigned int, const char *name = 0);
313 int get_socket () const { return (int) get_handle(); }
314 fhandler_socket * is_socket () { return this; }
315 int write (const void *ptr, size_t len);
316 int read (void *ptr, size_t len);
317 int ioctl (unsigned int cmd, void *);
318 off_t lseek (off_t, int) { return 0; }
320 void hclose (HANDLE) {close ();}
322 select_record *select_read (select_record *s);
323 select_record *select_write (select_record *s);
324 select_record *select_except (select_record *s);
325 int ready_for_read (int fd, DWORD howlong, int ignra);
326 int get_addr_family () {return addr_family;}
327 void set_addr_family (int af) {addr_family = af;}
330 class fhandler_pipe: public fhandler_base
333 fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
334 off_t lseek (off_t offset, int whence);
335 /* This strange test is due to the fact that we can't rely on
336 Windows shells to "do the right thing" with pipes. Apparently
337 the can keep one end of the pipe open when it shouldn't be. */
338 BOOL is_slow () {return os_being_run == winNT;}
339 select_record *select_read (select_record *s);
340 select_record *select_write (select_record *s);
341 select_record *select_except (select_record *s);
342 int ready_for_read (int fd, DWORD howlong, int ignra);
345 class fhandler_dev_raw: public fhandler_base
352 int eom_detected : 1;
353 int eof_detected : 1;
354 int lastblk_to_read : 1;
359 virtual void clear (void);
360 virtual int writebuf (void);
362 /* returns not null, if `win_error' determines an end of media condition */
363 virtual int is_eom(int win_error) = 0;
364 /* returns not null, if `win_error' determines an end of file condition */
365 virtual int is_eof(int win_error) = 0;
367 fhandler_dev_raw (DWORD dev, const char *name, int unit);
370 ~fhandler_dev_raw (void);
372 /* Function to de-linearize into a fd */
373 int de_linearize (const char *, const char *, const char *);
375 int open (const char *path, int flags, mode_t mode = 0);
378 int raw_read (void *ptr, size_t ulen);
379 int raw_write (const void *ptr, size_t ulen);
381 int fstat (struct stat *buf);
383 int dup (fhandler_base *child);
385 int ioctl (unsigned int cmd, void *buf);
388 class fhandler_dev_floppy: public fhandler_dev_raw
391 virtual int is_eom (int win_error);
392 virtual int is_eof (int win_error);
395 fhandler_dev_floppy (const char *name, int unit);
397 virtual int open (const char *path, int flags, mode_t mode = 0);
398 virtual int close (void);
400 virtual off_t lseek (off_t offset, int whence);
402 virtual int ioctl (unsigned int cmd, void *buf);
405 class fhandler_dev_tape: public fhandler_dev_raw
411 virtual void clear (void);
413 virtual int is_eom (int win_error);
414 virtual int is_eof (int win_error);
417 fhandler_dev_tape (const char *name, int unit);
419 virtual int open (const char *path, int flags, mode_t mode = 0);
420 virtual int close (void);
422 virtual off_t lseek (off_t offset, int whence);
424 virtual int fstat (struct stat *buf);
426 virtual int dup (fhandler_base *child);
428 virtual int ioctl (unsigned int cmd, void *buf);
431 int tape_write_marks (int marktype, DWORD len);
432 int tape_get_pos (unsigned long *ret);
433 int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
434 int tape_erase (int mode);
435 int tape_prepare (int action);
436 BOOLEAN tape_get_feature (DWORD parm);
437 int tape_get_blocksize (long *min, long *def, long *max, long *cur);
438 int tape_set_blocksize (long count);
439 int tape_status (struct mtget *get);
440 int tape_compression (long count);
443 /* Standard disk file */
445 class fhandler_disk_file: public fhandler_base
448 int check_execable_p (const char *path);
451 fhandler_disk_file (const char *name);
453 int open (const char *path, int flags, mode_t mode = 0);
454 int open (path_conv& real_path, int flags, mode_t mode);
456 int lock (int, struct flock *);
457 BOOL is_device () { return FALSE; }
458 int fstat (struct stat *buf);
461 class fhandler_serial: public fhandler_base
464 unsigned int vmin_; /* from termios */
465 unsigned int vtime_; /* from termios */
469 int overlapped_armed;
470 OVERLAPPED io_status;
473 fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
475 int open (const char *path, int flags, mode_t mode);
477 void init (HANDLE h, DWORD a, mode_t flags);
478 void overlapped_setup ();
479 int dup (fhandler_base *child);
480 int raw_read (void *ptr, size_t ulen);
481 int raw_write (const void *ptr, size_t ulen);
482 int tcsendbreak (int);
485 int tcsetattr (int a, const struct termios *t);
486 int tcgetattr (struct termios *t);
487 off_t lseek (off_t, int) { return 0; }
490 int is_tty () { return 1; }
491 void fixup_after_fork (HANDLE parent);
492 int de_linearize (const char *, const char *, const char *);
494 /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
495 don't use it for permissions checking. fhandler_tty_slave does
496 permission checking on pgrps. */
497 virtual int tcgetpgrp () { return pgrp_; }
498 virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
499 select_record *select_read (select_record *s);
500 select_record *select_write (select_record *s);
501 select_record *select_except (select_record *s);
502 int ready_for_read (int fd, DWORD howlong, int ignra);
505 class fhandler_termios: public fhandler_base
508 HANDLE output_handle;
509 virtual void doecho (const void *, DWORD) {};
510 virtual int accept_input () {return 1;};
513 fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
514 fhandler_base (dev, name, unit)
518 HANDLE restart_output_event;
519 HANDLE get_output_handle () const { return output_handle; }
520 int line_edit (const char *rptr, int nread, int always_accept = 0);
521 void set_output_handle (HANDLE h) { output_handle = h; }
522 void tcinit (tty_min *this_tc, int force = FALSE);
523 virtual int is_tty () { return 1; }
525 int tcsetpgrp (int pid);
526 void set_ctty (int ttynum, int flags);
527 int bg_check (int sig);
530 /* This is a input and output console handle */
531 class fhandler_console: public fhandler_termios
537 // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
556 void clear_screen (int, int, int, int);
557 void scroll_screen (int, int, int, int, int, int);
558 void cursor_set (BOOL, int, int);
559 void cursor_get (int *, int *);
560 void cursor_rel (int, int);
561 const unsigned char * write_normal (unsigned const char*, unsigned const char *);
562 void char_command (char);
563 int output_tcsetattr (int a, const struct termios *t);
566 int igncr_enabled ();
567 int input_tcsetattr (int a, const struct termios *t);
571 fhandler_console (const char *name);
573 fhandler_console* is_console () { return this; }
575 int open (const char *path, int flags, mode_t mode = 0);
577 int write (const void *ptr, size_t len);
578 void doecho (const void *str, DWORD len) { (void) write (str, len); }
579 int read (void *ptr, size_t len);
583 int tcsetattr (int a, const struct termios *t);
584 int tcgetattr (struct termios *t);
586 int tcsetpgrp (const pid_t pid) { tc->pgid = pid; return 0; }
588 /* Special dup as we must dup two handles */
589 int dup (fhandler_base *child);
591 int ioctl (unsigned int cmd, void *);
592 void init (HANDLE, DWORD, mode_t);
594 select_record *select_read (select_record *s);
595 select_record *select_write (select_record *s);
596 select_record *select_except (select_record *s);
597 int ready_for_read (int fd, DWORD howlong, int ignra);
598 int de_linearize (const char *, const char *, const char *);
599 void set_close_on_exec (int val);
600 void fixup_after_fork (HANDLE parent);
601 void set_input_state ()
603 if (TTYISSETF (RSTCONS))
604 input_tcsetattr (0, &tc->ti);
608 class fhandler_tty_common: public fhandler_termios
611 fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
612 fhandler_termios (dev, name, unit),
617 HANDLE output_done_event; // Raised by master when tty's output buffer
618 // written. Write status in tty::write_retval.
619 HANDLE ioctl_request_event; // Raised by slave to perform ioctl() request.
620 // Ioctl() request in tty::cmd/arg.
621 HANDLE ioctl_done_event; // Raised by master on ioctl() completion.
622 // Ioctl() status in tty::ioctl_retval.
624 HANDLE inuse; // used to indicate that a tty is in use
627 DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
628 void __release_output_mutex (const char *fn, int ln);
630 int ttynum; // Master tty num.
631 virtual int dup (fhandler_base *child);
633 tty *get_ttyp () { return (tty *)tc; }
634 int get_unit () { return ttynum; }
637 void set_close_on_exec (int val);
638 void fixup_after_fork (HANDLE parent);
639 select_record *select_read (select_record *s);
640 select_record *select_write (select_record *s);
641 select_record *select_except (select_record *s);
642 int ready_for_read (int fd, DWORD howlong, int ignra);
645 class fhandler_tty_slave: public fhandler_tty_common
647 void send_ioctl_request ();
651 fhandler_tty_slave (const char *name);
652 fhandler_tty_slave (int, const char *name);
654 int open (const char *path, int flags, mode_t mode = 0);
655 int write (const void *ptr, size_t len);
656 int read (void *ptr, size_t len);
657 void init (HANDLE, DWORD, mode_t);
659 int tcsetattr (int a, const struct termios *t);
660 int tcgetattr (struct termios *t);
662 int ioctl (unsigned int cmd, void *);
664 off_t lseek (off_t, int) { return 0; }
667 class fhandler_pty_master: public fhandler_tty_common
669 int pktmode; // non-zero if pty in a packet mode.
671 int need_nl; // Next read should start with \n
674 fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
676 int process_slave_output (char *buf, size_t len, int pktmode_on);
677 void doecho (const void *str, DWORD len);
679 int open (const char *path, int flags, mode_t mode = 0);
680 int write (const void *ptr, size_t len);
681 int read (void *ptr, size_t len);
684 int tcsetattr (int a, const struct termios *t);
685 int tcgetattr (struct termios *t);
687 int ioctl (unsigned int cmd, void *);
689 off_t lseek (off_t, int) { return 0; }
692 void set_close_on_exec (int val);
693 void fixup_after_fork (HANDLE parent);
697 class fhandler_tty_master: public fhandler_pty_master
701 fhandler_tty_master (const char *name, int unit);
702 fhandler_console *console; // device handler to perform real i/o.
703 HANDLE hThread; // process_output thread handle.
707 void fixup_after_fork (HANDLE parent);
708 int de_linearize (const char *, const char *, const char *);
711 class fhandler_dev_null: public fhandler_base
714 fhandler_dev_null (const char *name);
717 select_record *select_read (select_record *s);
718 select_record *select_write (select_record *s);
719 select_record *select_except (select_record *s);
722 class fhandler_dev_zero: public fhandler_base
725 fhandler_dev_zero (const char *name);
726 int open (const char *path, int flags, mode_t mode = 0);
727 int write (const void *ptr, size_t len);
728 int read (void *ptr, size_t len);
729 off_t lseek (off_t offset, int whence);
735 class fhandler_windows: public fhandler_base
738 HWND hWnd_; // the window whose messages are to be retrieved by read() call
739 int method_; // write method (Post or Send)
741 fhandler_windows (const char *name = 0);
742 int is_windows (void) { return 1; }
743 int open (const char *path, int flags, mode_t mode = 0);
744 int write (const void *ptr, size_t len);
745 int read (void *ptr, size_t len);
746 int ioctl (unsigned int cmd, void *);
747 off_t lseek (off_t, int) { return 0; }
748 int close (void) { return 0; }
750 void set_close_on_exec (int val);
751 void fixup_after_fork (HANDLE parent);
752 select_record *select_read (select_record *s);
753 select_record *select_write (select_record *s);
754 select_record *select_except (select_record *s);
755 int ready_for_read (int fd, DWORD howlong, int ignra);
759 /* You can't do this */
762 fhandler_normal normal;
763 fhandler_dev_null dev_null;
768 #define fhandler_union fhandler_console
777 BOOL read_ready, write_ready, except_ready;
778 BOOL read_selected, write_selected, except_selected;
779 int (*startup) (select_record *me, class select_stuff *stuff);
780 int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
782 int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
784 void (*cleanup) (select_record *me, class select_stuff *stuff);
785 struct select_record *next;
787 select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
788 fh (in_fh), saw_error (0), windows_handle (0),
789 read_ready (0), write_ready (0), except_ready (0),
790 read_selected (0), write_selected (0), except_selected (0),
791 startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
799 select_stuff (): always_ready (0), windows_used (0), start (0)
801 memset (device_specific, 0, sizeof (device_specific));
803 BOOL always_ready, windows_used;
805 void *device_specific[FH_NDEV];
807 int test_and_set (int i, fd_set *readfds, fd_set *writefds,
809 int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
810 int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
813 uid_t __stdcall get_file_owner (int, const char *);
814 gid_t __stdcall get_file_group (int, const char *);
816 #endif /* _FHANDLER_H_ */