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 */
94 FH_RANDOM = 0x00000015, /* is a random device */
96 FH_NDEV = 0x00000016, /* Maximum number of devices */
97 FH_DEVMASK = 0x00000fff, /* devices live here */
101 #define FHDEVN(n) ((n) & FH_DEVMASK)
102 #define FHISSETF(x) __ISSETF (this, x, FH)
103 #define FHSETF(x) __SETF (this, x, FH)
104 #define FHCLEARF(x) __CLEARF (this, x, FH)
105 #define FHCONDSETF(n, x) __CONDSETF(n, this, x, FH)
109 extern const char *windows_device_names[];
110 #define __fmode (*(user_data->fmode_ptr))
114 class fhandler_disk_file;
126 int rpos_; /* Used in text reading */
129 unsigned long namehash_; /* hashed filename, used as inode num */
131 /* Full unix path name of this file */
132 /* File open flags from open () and fcntl () calls */
136 char *rabuf; /* used for crlf conversion in text files */
142 char *unix_path_name_;
143 char *win32_path_name_;
146 void set_name (const char *unix, const char *win32 = NULL, int unit = 0);
148 virtual fhandler_base& operator =(fhandler_base &x)
150 memcpy (this, &x, sizeof *this);
151 unix_path_name_ = x.unix_path_name_ ? strdup (x.unix_path_name_) : NULL;
152 win32_path_name_ = x.win32_path_name_ ? strdup (x.win32_path_name_) : NULL;
155 fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
156 virtual ~fhandler_base ();
158 /* Non-virtual simple accessor functions. */
159 void set_io_handle (HANDLE);
161 void set_cb (size_t size) { cb = size; }
162 DWORD get_device () { return status & FH_DEVMASK; }
163 virtual int get_unit () { return 0; }
164 virtual BOOL is_slow () { return get_device () < FH_SLOW; }
166 int get_access () { return access_; }
167 void set_access (int x) { access_ = x; }
169 int get_async () { return FHISSETF (ASYNC); }
170 void set_async (int x) { FHCONDSETF (x, ASYNC); }
172 int get_flags () { return openflags_; }
173 void set_flags (int x) { openflags_ = x; }
175 int get_w_binary () { return FHISSETF (WBINARY); }
176 int get_r_binary () { return FHISSETF (RBINARY); }
178 int get_w_binset () { return FHISSETF (WBINSET); }
179 int get_r_binset () { return FHISSETF (RBINSET); }
181 void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
182 void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
184 int get_r_no_interrupt () { return FHISSETF (NOEINTR); }
185 void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); }
187 int get_close_on_exec () { return FHISSETF (CLOEXEC); }
188 int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); }
190 void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); }
191 int get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); }
193 int get_need_fork_fixup () { return FHISSETF (FFIXUP); }
194 void set_need_fork_fixup () { FHSETF (FFIXUP); }
196 virtual void set_close_on_exec (int val);
197 virtual void fixup_after_fork (HANDLE parent);
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); }
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); }
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); }
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); }
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);
219 int get_readahead ();
220 int peek_readahead (int queryput = 0);
222 int eat_readahead (int n);
224 void set_readahead_valid (int val, int ch = -1);
226 int get_readahead_into_buffer (char *buf, size_t buflen);
228 int has_acls () { return FHISSETF (HASACLS); }
229 void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
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); }
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_; }
239 virtual void hclose (HANDLE h) {CloseHandle (h);}
240 virtual void set_inheritance (HANDLE &h, int not_inheriting, const char *name = NULL);
242 /* fixup fd possibly non-inherited handles after fork */
243 void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
245 /* Potentially overridden virtual functions. */
246 virtual int open (const char *, int flags, mode_t mode = 0)
248 return open (flags, mode);
250 virtual int open (int flags, mode_t mode = 0);
251 virtual int close ();
252 virtual int fstat (struct stat *buf);
253 virtual int ioctl (unsigned int cmd, void *);
254 virtual char const * ttyname () { return get_name(); }
255 virtual int read (void *ptr, size_t len);
256 virtual int write (const void *ptr, size_t len);
257 virtual off_t lseek (off_t offset, int whence);
258 virtual int lock (int, struct flock *);
259 virtual void dump ();
260 virtual int dup (fhandler_base *child);
262 void *operator new (size_t, void *p) {return p;}
264 virtual void init (HANDLE, DWORD, mode_t);
266 virtual int tcflush (int);
267 virtual int tcsendbreak (int);
268 virtual int tcdrain ();
269 virtual int tcflow (int);
270 virtual int tcsetattr (int a, const struct termios *t);
271 virtual int tcgetattr (struct termios *t);
272 virtual int tcsetpgrp (const pid_t pid);
273 virtual int tcgetpgrp ();
274 virtual int is_tty () { return 0; }
275 virtual BOOL is_device () { return TRUE; }
276 virtual char *ptsname () { return NULL;}
277 virtual class fhandler_socket *is_socket () { return 0; }
278 virtual class fhandler_console *is_console () { return 0; }
279 virtual int is_windows () {return 0; }
281 virtual int raw_read (void *ptr, size_t ulen);
282 virtual int raw_write (const void *ptr, size_t ulen);
284 /* Function to save state of a fhandler_base into memory. */
285 virtual int linearize (unsigned char *);
286 /* Function to de-linearize into a fd */
287 virtual int de_linearize (const char *, const char *, const char *);
289 /* Virtual accessor functions to hide the fact
290 that some fd's have two handles. */
291 virtual HANDLE get_handle () const { return io_handle; }
292 virtual HANDLE get_io_handle () const { return io_handle; }
293 virtual HANDLE get_output_handle () const { return io_handle; }
294 virtual BOOL hit_eof () {return FALSE;}
295 virtual select_record *select_read (select_record *s);
296 virtual select_record *select_write (select_record *s);
297 virtual select_record *select_except (select_record *s);
298 virtual int ready_for_read (int fd, DWORD howlong, int ignra);
299 virtual const char * get_native_name ()
301 return windows_device_names[FHDEVN (status)];
303 virtual int bg_check (int) {return 1;}
306 class fhandler_socket: public fhandler_base
311 fhandler_socket (const char *name = 0);
312 fhandler_socket (unsigned int, const char *name = 0);
314 int get_socket () const { return (int) get_handle(); }
315 fhandler_socket * is_socket () { return this; }
316 int write (const void *ptr, size_t len);
317 int read (void *ptr, size_t len);
318 int ioctl (unsigned int cmd, void *);
319 off_t lseek (off_t, int) { return 0; }
321 void hclose (HANDLE) {close ();}
323 select_record *select_read (select_record *s);
324 select_record *select_write (select_record *s);
325 select_record *select_except (select_record *s);
326 int ready_for_read (int fd, DWORD howlong, int ignra);
327 int get_addr_family () {return addr_family;}
328 void set_addr_family (int af) {addr_family = af;}
331 class fhandler_pipe: public fhandler_base
334 fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
335 off_t lseek (off_t offset, int whence);
336 /* This strange test is due to the fact that we can't rely on
337 Windows shells to "do the right thing" with pipes. Apparently
338 the can keep one end of the pipe open when it shouldn't be. */
339 BOOL is_slow () {return os_being_run == winNT;}
340 select_record *select_read (select_record *s);
341 select_record *select_write (select_record *s);
342 select_record *select_except (select_record *s);
343 int ready_for_read (int fd, DWORD howlong, int ignra);
346 class fhandler_dev_raw: public fhandler_base
353 int eom_detected : 1;
354 int eof_detected : 1;
355 int lastblk_to_read : 1;
360 virtual void clear (void);
361 virtual int writebuf (void);
363 /* returns not null, if `win_error' determines an end of media condition */
364 virtual int is_eom(int win_error) = 0;
365 /* returns not null, if `win_error' determines an end of file condition */
366 virtual int is_eof(int win_error) = 0;
368 fhandler_dev_raw (DWORD dev, const char *name, int unit);
371 ~fhandler_dev_raw (void);
373 /* Function to de-linearize into a fd */
374 int de_linearize (const char *, const char *, const char *);
376 int open (const char *path, int flags, mode_t mode = 0);
379 int raw_read (void *ptr, size_t ulen);
380 int raw_write (const void *ptr, size_t ulen);
382 int fstat (struct stat *buf);
384 int dup (fhandler_base *child);
386 int ioctl (unsigned int cmd, void *buf);
389 class fhandler_dev_floppy: public fhandler_dev_raw
392 virtual int is_eom (int win_error);
393 virtual int is_eof (int win_error);
396 fhandler_dev_floppy (const char *name, int unit);
398 virtual int open (const char *path, int flags, mode_t mode = 0);
399 virtual int close (void);
401 virtual off_t lseek (off_t offset, int whence);
403 virtual int ioctl (unsigned int cmd, void *buf);
406 class fhandler_dev_tape: public fhandler_dev_raw
412 virtual void clear (void);
414 virtual int is_eom (int win_error);
415 virtual int is_eof (int win_error);
418 fhandler_dev_tape (const char *name, int unit);
420 virtual int open (const char *path, int flags, mode_t mode = 0);
421 virtual int close (void);
423 virtual off_t lseek (off_t offset, int whence);
425 virtual int fstat (struct stat *buf);
427 virtual int dup (fhandler_base *child);
429 virtual int ioctl (unsigned int cmd, void *buf);
432 int tape_write_marks (int marktype, DWORD len);
433 int tape_get_pos (unsigned long *ret);
434 int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
435 int tape_erase (int mode);
436 int tape_prepare (int action);
437 BOOLEAN tape_get_feature (DWORD parm);
438 int tape_get_blocksize (long *min, long *def, long *max, long *cur);
439 int tape_set_blocksize (long count);
440 int tape_status (struct mtget *get);
441 int tape_compression (long count);
444 /* Standard disk file */
446 class fhandler_disk_file: public fhandler_base
449 int check_execable_p (const char *path);
452 fhandler_disk_file (const char *name);
454 int open (const char *path, int flags, mode_t mode = 0);
455 int open (path_conv& real_path, int flags, mode_t mode);
457 int lock (int, struct flock *);
458 BOOL is_device () { return FALSE; }
459 int fstat (struct stat *buf);
462 class fhandler_serial: public fhandler_base
465 unsigned int vmin_; /* from termios */
466 unsigned int vtime_; /* from termios */
470 int overlapped_armed;
471 OVERLAPPED io_status;
474 fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
476 int open (const char *path, int flags, mode_t mode);
478 void init (HANDLE h, DWORD a, mode_t flags);
479 void overlapped_setup ();
480 int dup (fhandler_base *child);
481 int raw_read (void *ptr, size_t ulen);
482 int raw_write (const void *ptr, size_t ulen);
483 int tcsendbreak (int);
486 int tcsetattr (int a, const struct termios *t);
487 int tcgetattr (struct termios *t);
488 off_t lseek (off_t, int) { return 0; }
491 int is_tty () { return 1; }
492 void fixup_after_fork (HANDLE parent);
493 int de_linearize (const char *, const char *, const char *);
495 /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
496 don't use it for permissions checking. fhandler_tty_slave does
497 permission checking on pgrps. */
498 virtual int tcgetpgrp () { return pgrp_; }
499 virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
500 select_record *select_read (select_record *s);
501 select_record *select_write (select_record *s);
502 select_record *select_except (select_record *s);
503 int ready_for_read (int fd, DWORD howlong, int ignra);
506 class fhandler_termios: public fhandler_base
509 HANDLE output_handle;
510 virtual void doecho (const void *, DWORD) {};
511 virtual int accept_input () {return 1;};
514 fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
515 fhandler_base (dev, name, unit)
519 HANDLE restart_output_event;
520 HANDLE get_output_handle () const { return output_handle; }
521 int line_edit (const char *rptr, int nread, int always_accept = 0);
522 void set_output_handle (HANDLE h) { output_handle = h; }
523 void tcinit (tty_min *this_tc, int force = FALSE);
524 virtual int is_tty () { return 1; }
526 int tcsetpgrp (int pid);
527 void set_ctty (int ttynum, int flags);
528 int bg_check (int sig);
531 /* This is a input and output console handle */
532 class fhandler_console: public fhandler_termios
538 // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
557 void clear_screen (int, int, int, int);
558 void scroll_screen (int, int, int, int, int, int);
559 void cursor_set (BOOL, int, int);
560 void cursor_get (int *, int *);
561 void cursor_rel (int, int);
562 const unsigned char * write_normal (unsigned const char*, unsigned const char *);
563 void char_command (char);
564 int output_tcsetattr (int a, const struct termios *t);
567 int igncr_enabled ();
568 int input_tcsetattr (int a, const struct termios *t);
572 fhandler_console (const char *name);
574 fhandler_console* is_console () { return this; }
576 int open (const char *path, int flags, mode_t mode = 0);
578 int write (const void *ptr, size_t len);
579 void doecho (const void *str, DWORD len) { (void) write (str, len); }
580 int read (void *ptr, size_t len);
584 int tcsetattr (int a, const struct termios *t);
585 int tcgetattr (struct termios *t);
587 int tcsetpgrp (const pid_t pid) { tc->pgid = pid; return 0; }
589 /* Special dup as we must dup two handles */
590 int dup (fhandler_base *child);
592 int ioctl (unsigned int cmd, void *);
593 void init (HANDLE, DWORD, mode_t);
595 select_record *select_read (select_record *s);
596 select_record *select_write (select_record *s);
597 select_record *select_except (select_record *s);
598 int ready_for_read (int fd, DWORD howlong, int ignra);
599 int de_linearize (const char *, const char *, const char *);
600 void set_close_on_exec (int val);
601 void fixup_after_fork (HANDLE parent);
602 void set_input_state ()
604 if (TTYISSETF (RSTCONS))
605 input_tcsetattr (0, &tc->ti);
609 class fhandler_tty_common: public fhandler_termios
612 fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
613 fhandler_termios (dev, name, unit),
618 HANDLE output_done_event; // Raised by master when tty's output buffer
619 // written. Write status in tty::write_retval.
620 HANDLE ioctl_request_event; // Raised by slave to perform ioctl() request.
621 // Ioctl() request in tty::cmd/arg.
622 HANDLE ioctl_done_event; // Raised by master on ioctl() completion.
623 // Ioctl() status in tty::ioctl_retval.
625 HANDLE inuse; // used to indicate that a tty is in use
628 DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
629 void __release_output_mutex (const char *fn, int ln);
631 int ttynum; // Master tty num.
632 virtual int dup (fhandler_base *child);
634 tty *get_ttyp () { return (tty *)tc; }
635 int get_unit () { return ttynum; }
638 void set_close_on_exec (int val);
639 void fixup_after_fork (HANDLE parent);
640 select_record *select_read (select_record *s);
641 select_record *select_write (select_record *s);
642 select_record *select_except (select_record *s);
643 int ready_for_read (int fd, DWORD howlong, int ignra);
646 class fhandler_tty_slave: public fhandler_tty_common
650 fhandler_tty_slave (const char *name);
651 fhandler_tty_slave (int, const char *name);
653 int open (const char *path, int flags, mode_t mode = 0);
654 int write (const void *ptr, size_t len);
655 int read (void *ptr, size_t len);
656 void init (HANDLE, DWORD, mode_t);
658 int tcsetattr (int a, const struct termios *t);
659 int tcgetattr (struct termios *t);
661 int ioctl (unsigned int cmd, void *);
663 off_t lseek (off_t, int) { return 0; }
666 class fhandler_pty_master: public fhandler_tty_common
668 int pktmode; // non-zero if pty in a packet mode.
670 int need_nl; // Next read should start with \n
673 fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
675 int process_slave_output (char *buf, size_t len, int pktmode_on);
676 void doecho (const void *str, DWORD len);
678 int open (const char *path, int flags, mode_t mode = 0);
679 int write (const void *ptr, size_t len);
680 int read (void *ptr, size_t len);
683 int tcsetattr (int a, const struct termios *t);
684 int tcgetattr (struct termios *t);
686 int ioctl (unsigned int cmd, void *);
688 off_t lseek (off_t, int) { return 0; }
691 void set_close_on_exec (int val);
692 void fixup_after_fork (HANDLE parent);
696 class fhandler_tty_master: public fhandler_pty_master
700 fhandler_tty_master (const char *name, int unit);
701 fhandler_console *console; // device handler to perform real i/o.
702 HANDLE hThread; // process_output thread handle.
706 void fixup_after_fork (HANDLE parent);
707 int de_linearize (const char *, const char *, const char *);
710 class fhandler_dev_null: public fhandler_base
713 fhandler_dev_null (const char *name);
716 select_record *select_read (select_record *s);
717 select_record *select_write (select_record *s);
718 select_record *select_except (select_record *s);
721 class fhandler_dev_zero: public fhandler_base
724 fhandler_dev_zero (const char *name);
725 int open (const char *path, int flags, mode_t mode = 0);
726 int write (const void *ptr, size_t len);
727 int read (void *ptr, size_t len);
728 off_t lseek (off_t offset, int whence);
734 class fhandler_dev_random: public fhandler_base
738 HCRYPTPROV crypt_prov;
740 fhandler_dev_random (const char *name, int unit);
741 int get_unit () { return unit; }
742 int open (const char *path, int flags, mode_t mode = 0);
743 int write (const void *ptr, size_t len);
744 int read (void *ptr, size_t len);
745 off_t lseek (off_t offset, int whence);
747 int dup (fhandler_base *child);
752 class fhandler_windows: public fhandler_base
755 HWND hWnd_; // the window whose messages are to be retrieved by read() call
756 int method_; // write method (Post or Send)
758 fhandler_windows (const char *name = 0);
759 int is_windows (void) { return 1; }
760 int open (const char *path, int flags, mode_t mode = 0);
761 int write (const void *ptr, size_t len);
762 int read (void *ptr, size_t len);
763 int ioctl (unsigned int cmd, void *);
764 off_t lseek (off_t, int) { return 0; }
765 int close (void) { return 0; }
767 void set_close_on_exec (int val);
768 void fixup_after_fork (HANDLE parent);
769 select_record *select_read (select_record *s);
770 select_record *select_write (select_record *s);
771 select_record *select_except (select_record *s);
772 int ready_for_read (int fd, DWORD howlong, int ignra);
776 /* You can't do this */
779 fhandler_normal normal;
780 fhandler_dev_null dev_null;
785 #define fhandler_union fhandler_console
794 BOOL read_ready, write_ready, except_ready;
795 BOOL read_selected, write_selected, except_selected;
796 int (*startup) (select_record *me, class select_stuff *stuff);
797 int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
799 int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
801 void (*cleanup) (select_record *me, class select_stuff *stuff);
802 struct select_record *next;
804 select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
805 fh (in_fh), saw_error (0), windows_handle (0),
806 read_ready (0), write_ready (0), except_ready (0),
807 read_selected (0), write_selected (0), except_selected (0),
808 startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
816 select_stuff (): always_ready (0), windows_used (0), start (0)
818 memset (device_specific, 0, sizeof (device_specific));
820 BOOL always_ready, windows_used;
822 void *device_specific[FH_NDEV];
824 int test_and_set (int i, fd_set *readfds, fd_set *writefds,
826 int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
827 int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
830 uid_t __stdcall get_file_owner (int, const char *);
831 gid_t __stdcall get_file_group (int, const char *);
833 #endif /* _FHANDLER_H_ */