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_; }
239 /* fixup fd possibly non-inherited handles after fork */
240 void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
242 /* Potentially overridden virtual functions. */
243 virtual int open (const char *, int flags, mode_t mode = 0)
245 return open (flags, mode);
247 virtual int open (int flags, mode_t mode = 0);
248 virtual int close ();
249 virtual int fstat (struct stat *buf);
250 virtual int ioctl (unsigned int cmd, void *);
251 virtual char const * ttyname () { return get_name(); }
252 virtual int read (void *ptr, size_t len);
253 virtual int write (const void *ptr, size_t len);
254 virtual off_t lseek (off_t offset, int whence);
255 virtual int lock (int, struct flock *);
256 virtual void dump ();
257 virtual int dup (fhandler_base *child);
259 void *operator new (size_t, void *p) {return p;}
261 virtual void init (HANDLE, DWORD, mode_t);
263 virtual int tcflush (int);
264 virtual int tcsendbreak (int);
265 virtual int tcdrain ();
266 virtual int tcflow (int);
267 virtual int tcsetattr (int a, const struct termios *t);
268 virtual int tcgetattr (struct termios *t);
269 virtual int tcsetpgrp (const pid_t pid);
270 virtual int tcgetpgrp ();
271 virtual int is_tty () { return 0; }
272 virtual BOOL is_device () { return TRUE; }
273 virtual char *ptsname () { return NULL;}
274 virtual class fhandler_socket *is_socket () { return 0; }
275 virtual class fhandler_console *is_console () { return 0; }
276 virtual int is_windows () {return 0; }
278 virtual int raw_read (void *ptr, size_t ulen);
279 virtual int raw_write (const void *ptr, size_t ulen);
281 /* Function to save state of a fhandler_base into memory. */
282 virtual int linearize (unsigned char *);
283 /* Function to de-linearize into a fd */
284 virtual int de_linearize (const char *, const char *, const char *);
286 /* Virtual accessor functions to hide the fact
287 that some fd's have two handles. */
288 virtual HANDLE get_handle () const { return io_handle; }
289 virtual HANDLE get_io_handle () const { return io_handle; }
290 virtual HANDLE get_output_handle () const { return io_handle; }
291 virtual BOOL hit_eof () {return FALSE;}
292 virtual select_record *select_read (select_record *s);
293 virtual select_record *select_write (select_record *s);
294 virtual select_record *select_except (select_record *s);
295 virtual int ready_for_read (int fd, DWORD howlong, int ignra);
296 virtual const char * get_native_name ()
298 return windows_device_names[FHDEVN (status)];
300 virtual int bg_check (int) {return 1;}
303 class fhandler_socket: public fhandler_base
308 fhandler_socket (const char *name = 0);
309 fhandler_socket (unsigned int, const char *name = 0);
311 int get_socket () const { return (int) get_handle(); }
312 fhandler_socket * is_socket () { return this; }
313 int write (const void *ptr, size_t len);
314 int read (void *ptr, size_t len);
315 int ioctl (unsigned int cmd, void *);
316 off_t lseek (off_t, int) { return 0; }
319 select_record *select_read (select_record *s);
320 select_record *select_write (select_record *s);
321 select_record *select_except (select_record *s);
322 int ready_for_read (int fd, DWORD howlong, int ignra);
323 int get_addr_family () {return addr_family;}
324 void set_addr_family (int af) {addr_family = af;}
327 class fhandler_pipe: public fhandler_base
330 fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
331 off_t lseek (off_t offset, int whence);
332 /* This strange test is due to the fact that we can't rely on
333 Windows shells to "do the right thing" with pipes. Apparently
334 the can keep one end of the pipe open when it shouldn't be. */
335 BOOL is_slow () {return os_being_run == winNT;}
336 select_record *select_read (select_record *s);
337 select_record *select_write (select_record *s);
338 select_record *select_except (select_record *s);
339 int ready_for_read (int fd, DWORD howlong, int ignra);
342 class fhandler_dev_raw: public fhandler_base
349 int eom_detected : 1;
350 int eof_detected : 1;
351 int lastblk_to_read : 1;
356 virtual void clear (void);
357 virtual int writebuf (void);
359 /* returns not null, if `win_error' determines an end of media condition */
360 virtual int is_eom(int win_error) = 0;
361 /* returns not null, if `win_error' determines an end of file condition */
362 virtual int is_eof(int win_error) = 0;
364 fhandler_dev_raw (DWORD dev, const char *name, int unit);
367 ~fhandler_dev_raw (void);
369 /* Function to de-linearize into a fd */
370 int de_linearize (const char *, const char *, const char *);
372 int open (const char *path, int flags, mode_t mode = 0);
375 int raw_read (void *ptr, size_t ulen);
376 int raw_write (const void *ptr, size_t ulen);
378 int fstat (struct stat *buf);
380 int dup (fhandler_base *child);
382 int ioctl (unsigned int cmd, void *buf);
385 class fhandler_dev_floppy: public fhandler_dev_raw
388 virtual int is_eom (int win_error);
389 virtual int is_eof (int win_error);
392 fhandler_dev_floppy (const char *name, int unit);
394 virtual int open (const char *path, int flags, mode_t mode = 0);
395 virtual int close (void);
397 virtual off_t lseek (off_t offset, int whence);
399 virtual int ioctl (unsigned int cmd, void *buf);
402 class fhandler_dev_tape: public fhandler_dev_raw
408 virtual void clear (void);
410 virtual int is_eom (int win_error);
411 virtual int is_eof (int win_error);
414 fhandler_dev_tape (const char *name, int unit);
416 virtual int open (const char *path, int flags, mode_t mode = 0);
417 virtual int close (void);
419 virtual off_t lseek (off_t offset, int whence);
421 virtual int fstat (struct stat *buf);
423 virtual int dup (fhandler_base *child);
425 virtual int ioctl (unsigned int cmd, void *buf);
428 int tape_write_marks (int marktype, DWORD len);
429 int tape_get_pos (unsigned long *ret);
430 int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
431 int tape_erase (int mode);
432 int tape_prepare (int action);
433 BOOLEAN tape_get_feature (DWORD parm);
434 int tape_get_blocksize (long *min, long *def, long *max, long *cur);
435 int tape_set_blocksize (long count);
436 int tape_status (struct mtget *get);
437 int tape_compression (long count);
440 /* Standard disk file */
442 class fhandler_disk_file: public fhandler_base
445 int check_execable_p (const char *path);
448 fhandler_disk_file (const char *name);
450 int open (const char *path, int flags, mode_t mode = 0);
451 int open (path_conv& real_path, int flags, mode_t mode);
453 int lock (int, struct flock *);
454 BOOL is_device () { return FALSE; }
455 int fstat (struct stat *buf);
458 class fhandler_serial: public fhandler_base
461 unsigned int vmin_; /* from termios */
462 unsigned int vtime_; /* from termios */
466 int overlapped_armed;
467 OVERLAPPED io_status;
470 fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
472 int open (const char *path, int flags, mode_t mode);
474 void init (HANDLE h, DWORD a, mode_t flags);
475 void overlapped_setup ();
476 int dup (fhandler_base *child);
477 int raw_read (void *ptr, size_t ulen);
478 int raw_write (const void *ptr, size_t ulen);
479 int tcsendbreak (int);
482 int tcsetattr (int a, const struct termios *t);
483 int tcgetattr (struct termios *t);
484 off_t lseek (off_t, int) { return 0; }
487 int is_tty () { return 1; }
488 void fixup_after_fork (HANDLE parent);
489 int de_linearize (const char *, const char *, const char *);
491 /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
492 don't use it for permissions checking. fhandler_tty_slave does
493 permission checking on pgrps. */
494 virtual int tcgetpgrp () { return pgrp_; }
495 virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
496 select_record *select_read (select_record *s);
497 select_record *select_write (select_record *s);
498 select_record *select_except (select_record *s);
499 int ready_for_read (int fd, DWORD howlong, int ignra);
502 class fhandler_termios: public fhandler_base
505 HANDLE output_handle;
506 virtual void doecho (const void *, DWORD) {};
507 virtual int accept_input () {return 1;};
510 fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
511 fhandler_base (dev, name, unit)
515 HANDLE restart_output_event;
516 HANDLE get_output_handle () const { return output_handle; }
517 int line_edit (const char *rptr, int nread, int always_accept = 0);
518 void set_output_handle (HANDLE h) { output_handle = h; }
519 void tcinit (tty_min *this_tc, int force = FALSE);
520 virtual int is_tty () { return 1; }
522 int tcsetpgrp (int pid);
523 void set_ctty (int ttynum, int flags);
524 int bg_check (int sig);
527 /* This is a input and output console handle */
528 class fhandler_console: public fhandler_termios
534 // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
553 void clear_screen (int, int, int, int);
554 void scroll_screen (int, int, int, int, int, int);
555 void cursor_set (BOOL, int, int);
556 void cursor_get (int *, int *);
557 void cursor_rel (int, int);
558 const unsigned char * write_normal (unsigned const char*, unsigned const char *);
559 void char_command (char);
560 int output_tcsetattr (int a, const struct termios *t);
563 int igncr_enabled ();
564 int input_tcsetattr (int a, const struct termios *t);
568 fhandler_console (const char *name);
570 fhandler_console* is_console () { return this; }
572 int open (const char *path, int flags, mode_t mode = 0);
574 int write (const void *ptr, size_t len);
575 void doecho (const void *str, DWORD len) { (void) write (str, len); }
576 int read (void *ptr, size_t len);
580 int tcsetattr (int a, const struct termios *t);
581 int tcgetattr (struct termios *t);
583 int tcsetpgrp (const pid_t pid) { tc->pgid = pid; return 0; }
585 /* Special dup as we must dup two handles */
586 int dup (fhandler_base *child);
588 int ioctl (unsigned int cmd, void *);
589 void init (HANDLE, DWORD, mode_t);
591 select_record *select_read (select_record *s);
592 select_record *select_write (select_record *s);
593 select_record *select_except (select_record *s);
594 int ready_for_read (int fd, DWORD howlong, int ignra);
595 int de_linearize (const char *, const char *, const char *);
596 void set_close_on_exec (int val);
597 void fixup_after_fork (HANDLE parent);
598 void set_input_state ()
600 if (TTYISSETF (RSTCONS))
601 input_tcsetattr (0, &tc->ti);
605 class fhandler_tty_common: public fhandler_termios
608 fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
609 fhandler_termios (dev, name, unit),
614 HANDLE output_done_event; // Raised by master when tty's output buffer
615 // written. Write status in tty::write_retval.
616 HANDLE ioctl_request_event; // Raised by slave to perform ioctl() request.
617 // Ioctl() request in tty::cmd/arg.
618 HANDLE ioctl_done_event; // Raised by master on ioctl() completion.
619 // Ioctl() status in tty::ioctl_retval.
621 HANDLE inuse; // used to indicate that a tty is in use
624 DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
625 void __release_output_mutex (const char *fn, int ln);
627 int ttynum; // Master tty num.
628 virtual int dup (fhandler_base *child);
630 tty *get_ttyp () { return (tty *)tc; }
631 int get_unit () { return ttynum; }
634 void set_close_on_exec (int val);
635 void fixup_after_fork (HANDLE parent);
636 select_record *select_read (select_record *s);
637 select_record *select_write (select_record *s);
638 select_record *select_except (select_record *s);
639 int ready_for_read (int fd, DWORD howlong, int ignra);
642 class fhandler_tty_slave: public fhandler_tty_common
644 void send_ioctl_request ();
648 fhandler_tty_slave (const char *name);
649 fhandler_tty_slave (int, const char *name);
651 int open (const char *path, int flags, mode_t mode = 0);
652 int write (const void *ptr, size_t len);
653 int read (void *ptr, size_t len);
654 void init (HANDLE, DWORD, mode_t);
656 int tcsetattr (int a, const struct termios *t);
657 int tcgetattr (struct termios *t);
659 int ioctl (unsigned int cmd, void *);
661 off_t lseek (off_t, int) { return 0; }
664 class fhandler_pty_master: public fhandler_tty_common
666 int pktmode; // non-zero if pty in a packet mode.
668 int need_nl; // Next read should start with \n
671 fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
673 int process_slave_output (char *buf, size_t len, int pktmode_on);
674 void doecho (const void *str, DWORD len);
676 int open (const char *path, int flags, mode_t mode = 0);
677 int write (const void *ptr, size_t len);
678 int read (void *ptr, size_t len);
681 int tcsetattr (int a, const struct termios *t);
682 int tcgetattr (struct termios *t);
684 int ioctl (unsigned int cmd, void *);
686 off_t lseek (off_t, int) { return 0; }
689 void set_close_on_exec (int val);
690 void fixup_after_fork (HANDLE parent);
694 class fhandler_tty_master: public fhandler_pty_master
698 fhandler_tty_master (const char *name, int unit);
699 fhandler_console *console; // device handler to perform real i/o.
700 HANDLE hThread; // process_output thread handle.
704 void fixup_after_fork (HANDLE parent);
705 int de_linearize (const char *, const char *, const char *);
708 class fhandler_dev_null: public fhandler_base
711 fhandler_dev_null (const char *name);
714 select_record *select_read (select_record *s);
715 select_record *select_write (select_record *s);
716 select_record *select_except (select_record *s);
719 class fhandler_dev_zero: public fhandler_base
722 fhandler_dev_zero (const char *name);
723 int open (const char *path, int flags, mode_t mode = 0);
724 int write (const void *ptr, size_t len);
725 int read (void *ptr, size_t len);
726 off_t lseek (off_t offset, int whence);
732 class fhandler_windows: public fhandler_base
735 HWND hWnd_; // the window whose messages are to be retrieved by read() call
736 int method_; // write method (Post or Send)
738 fhandler_windows (const char *name = 0);
739 int is_windows (void) { return 1; }
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 int ioctl (unsigned int cmd, void *);
744 off_t lseek (off_t, int) { return 0; }
745 int close (void) { return 0; }
747 void set_close_on_exec (int val);
748 void fixup_after_fork (HANDLE parent);
749 select_record *select_read (select_record *s);
750 select_record *select_write (select_record *s);
751 select_record *select_except (select_record *s);
752 int ready_for_read (int fd, DWORD howlong, int ignra);
756 /* You can't do this */
759 fhandler_normal normal;
760 fhandler_dev_null dev_null;
765 #define fhandler_union fhandler_console
774 BOOL read_ready, write_ready, except_ready;
775 BOOL read_selected, write_selected, except_selected;
776 int (*startup) (select_record *me, class select_stuff *stuff);
777 int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
779 int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
781 void (*cleanup) (select_record *me, class select_stuff *stuff);
782 struct select_record *next;
784 select_record (fhandler_base *in_fh = NULL) {memset (this, 0, sizeof(select_record)); fh = in_fh;}
785 select_record (int) : fd (0), h (NULL), fh (0), saw_error (0), windows_handle (0),
786 read_ready (0), write_ready (0), except_ready (0),
787 read_selected (0), write_selected (0), except_selected (0),
788 startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
796 select_stuff (): always_ready (0), windows_used (0),
799 memset (device_specific, 0, sizeof (device_specific));
801 BOOL always_ready, windows_used;
804 void *device_specific[FH_NDEV];
806 int test_and_set (int i, fd_set *readfds, fd_set *writefds,
808 int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
809 int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
812 uid_t __stdcall get_file_owner (int, const char *);
813 gid_t __stdcall get_file_group (int, const char *);
815 void __stdcall set_inheritance (HANDLE &h, int val, const char *name = NULL);
817 #endif /* _FHANDLER_H_ */