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);
153 fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
154 virtual ~fhandler_base ();
156 /* Non-virtual simple accessor functions. */
157 void set_io_handle (HANDLE);
159 void set_cb (size_t size) { cb = size; }
160 DWORD get_device () { return status & FH_DEVMASK; }
161 virtual int get_unit () { return 0; }
162 virtual BOOL is_slow () { return get_device () < FH_SLOW; }
164 int get_access () { return access_; }
165 void set_access (int x) { access_ = x; }
167 int get_async () { return FHISSETF (ASYNC); }
168 void set_async (int x) { FHCONDSETF (x, ASYNC); }
170 int get_flags () { return openflags_; }
171 void set_flags (int x) { openflags_ = x; }
173 int get_w_binary () { return FHISSETF (WBINARY); }
174 int get_r_binary () { return FHISSETF (RBINARY); }
176 int get_w_binset () { return FHISSETF (WBINSET); }
177 int get_r_binset () { return FHISSETF (RBINSET); }
179 void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
180 void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
182 int get_default_fmode (int flags);
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,
241 const char *name = NULL);
243 /* fixup fd possibly non-inherited handles after fork */
244 void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
246 /* Potentially overridden virtual functions. */
247 virtual int open (const char *, int flags, mode_t mode = 0)
249 return open (flags, mode);
251 virtual int open (int flags, mode_t mode = 0);
252 virtual int close ();
253 virtual int fstat (struct stat *buf);
254 virtual int ioctl (unsigned int cmd, void *);
255 virtual char const * ttyname () { return get_name(); }
256 virtual int read (void *ptr, size_t len);
257 virtual int write (const void *ptr, size_t len);
258 virtual off_t lseek (off_t offset, int whence);
259 virtual int lock (int, struct flock *);
260 virtual void dump ();
261 virtual int dup (fhandler_base *child);
263 void *operator new (size_t, void *p) {return p;}
265 virtual void init (HANDLE, DWORD, mode_t);
267 virtual int tcflush (int);
268 virtual int tcsendbreak (int);
269 virtual int tcdrain ();
270 virtual int tcflow (int);
271 virtual int tcsetattr (int a, const struct termios *t);
272 virtual int tcgetattr (struct termios *t);
273 virtual int tcsetpgrp (const pid_t pid);
274 virtual int tcgetpgrp ();
275 virtual int is_tty () { return 0; }
276 virtual BOOL is_device () { return TRUE; }
277 virtual char *ptsname () { return NULL;}
278 virtual class fhandler_socket *is_socket () { return 0; }
279 virtual class fhandler_console *is_console () { return 0; }
280 virtual int is_windows () {return 0; }
282 virtual int raw_read (void *ptr, size_t ulen);
283 virtual int raw_write (const void *ptr, size_t ulen);
285 virtual void fixup_after_exec (HANDLE) {}
287 /* Virtual accessor functions to hide the fact
288 that some fd's have two handles. */
289 virtual HANDLE get_handle () const { return io_handle; }
290 virtual HANDLE get_io_handle () const { return io_handle; }
291 virtual HANDLE get_output_handle () const { return io_handle; }
292 virtual BOOL hit_eof () {return FALSE;}
293 virtual select_record *select_read (select_record *s);
294 virtual select_record *select_write (select_record *s);
295 virtual select_record *select_except (select_record *s);
296 virtual int ready_for_read (int fd, DWORD howlong, int ignra);
297 virtual const char * get_native_name ()
299 return windows_device_names[FHDEVN (status)];
301 virtual int bg_check (int) {return 1;}
302 void clear_readahead ()
304 raixput = raixget = ralen = rabuflen = 0;
307 void operator delete (void *);
310 class fhandler_socket: public fhandler_base
315 fhandler_socket (const char *name = 0);
316 fhandler_socket (unsigned int, const char *name = 0);
318 int get_socket () const { return (int) get_handle(); }
319 fhandler_socket * is_socket () { return this; }
320 int write (const void *ptr, size_t len);
321 int read (void *ptr, size_t len);
322 int ioctl (unsigned int cmd, void *);
323 off_t lseek (off_t, int) { return 0; }
325 void hclose (HANDLE) {close ();}
327 select_record *select_read (select_record *s);
328 select_record *select_write (select_record *s);
329 select_record *select_except (select_record *s);
330 int ready_for_read (int fd, DWORD howlong, int ignra);
331 int get_addr_family () {return addr_family;}
332 void set_addr_family (int af) {addr_family = af;}
335 class fhandler_pipe: public fhandler_base
338 fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
339 off_t lseek (off_t offset, int whence);
340 /* This strange test is due to the fact that we can't rely on
341 Windows shells to "do the right thing" with pipes. Apparently
342 the can keep one end of the pipe open when it shouldn't be. */
343 BOOL is_slow () {return os_being_run == winNT;}
344 select_record *select_read (select_record *s);
345 select_record *select_write (select_record *s);
346 select_record *select_except (select_record *s);
347 int ready_for_read (int fd, DWORD howlong, int ignra);
350 class fhandler_dev_raw: public fhandler_base
357 int eom_detected : 1;
358 int eof_detected : 1;
359 int lastblk_to_read : 1;
365 virtual void clear (void);
366 virtual int writebuf (void);
368 /* returns not null, if `win_error' determines an end of media condition */
369 virtual int is_eom(int win_error) = 0;
370 /* returns not null, if `win_error' determines an end of file condition */
371 virtual int is_eof(int win_error) = 0;
373 fhandler_dev_raw (DWORD dev, const char *name, int unit);
376 ~fhandler_dev_raw (void);
378 int open (const char *path, int flags, mode_t mode = 0);
381 int raw_read (void *ptr, size_t ulen);
382 int raw_write (const void *ptr, size_t ulen);
384 int fstat (struct stat *buf);
386 int dup (fhandler_base *child);
388 int ioctl (unsigned int cmd, void *buf);
391 class fhandler_dev_floppy: public fhandler_dev_raw
394 virtual int is_eom (int win_error);
395 virtual int is_eof (int win_error);
398 fhandler_dev_floppy (const char *name, int unit);
400 virtual int open (const char *path, int flags, mode_t mode = 0);
401 virtual int close (void);
403 virtual off_t lseek (off_t offset, int whence);
405 virtual int ioctl (unsigned int cmd, void *buf);
408 class fhandler_dev_tape: public fhandler_dev_raw
414 virtual void clear (void);
416 virtual int is_eom (int win_error);
417 virtual int is_eof (int win_error);
420 fhandler_dev_tape (const char *name, int unit);
422 virtual int open (const char *path, int flags, mode_t mode = 0);
423 virtual int close (void);
425 virtual off_t lseek (off_t offset, int whence);
427 virtual int fstat (struct stat *buf);
429 virtual int dup (fhandler_base *child);
431 virtual int ioctl (unsigned int cmd, void *buf);
434 int tape_write_marks (int marktype, DWORD len);
435 int tape_get_pos (unsigned long *ret);
436 int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
437 int tape_erase (int mode);
438 int tape_prepare (int action);
439 BOOLEAN tape_get_feature (DWORD parm);
440 int tape_get_blocksize (long *min, long *def, long *max, long *cur);
441 int tape_set_blocksize (long count);
442 int tape_status (struct mtget *get);
443 int tape_compression (long count);
446 /* Standard disk file */
448 class fhandler_disk_file: public fhandler_base
451 int check_execable_p (const char *path);
454 fhandler_disk_file (const char *name);
456 int open (const char *path, int flags, mode_t mode = 0);
457 int open (path_conv& real_path, int flags, mode_t mode);
459 int lock (int, struct flock *);
460 BOOL is_device () { return FALSE; }
461 int fstat (struct stat *buf);
464 class fhandler_serial: public fhandler_base
467 unsigned int vmin_; /* from termios */
468 unsigned int vtime_; /* from termios */
472 int overlapped_armed;
473 OVERLAPPED io_status;
476 fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
478 int open (const char *path, int flags, mode_t mode);
480 void init (HANDLE h, DWORD a, mode_t flags);
481 void overlapped_setup ();
482 int dup (fhandler_base *child);
483 int raw_read (void *ptr, size_t ulen);
484 int raw_write (const void *ptr, size_t ulen);
485 int tcsendbreak (int);
488 int tcsetattr (int a, const struct termios *t);
489 int tcgetattr (struct termios *t);
490 off_t lseek (off_t, int) { return 0; }
493 int is_tty () { return 1; }
494 void fixup_after_fork (HANDLE parent);
495 void fixup_after_exec (HANDLE);
497 /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
498 don't use it for permissions checking. fhandler_tty_slave does
499 permission checking on pgrps. */
500 virtual int tcgetpgrp () { return pgrp_; }
501 virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
502 select_record *select_read (select_record *s);
503 select_record *select_write (select_record *s);
504 select_record *select_except (select_record *s);
505 int ready_for_read (int fd, DWORD howlong, int ignra);
508 class fhandler_termios: public fhandler_base
511 HANDLE output_handle;
512 virtual void doecho (const void *, DWORD) {};
513 virtual int accept_input () {return 1;};
516 fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
517 fhandler_base (dev, name, unit)
521 HANDLE restart_output_event;
522 HANDLE get_output_handle () const { return output_handle; }
523 int line_edit (const char *rptr, int nread, int always_accept = 0);
524 void set_output_handle (HANDLE h) { output_handle = h; }
525 void tcinit (tty_min *this_tc, int force = FALSE);
526 virtual int is_tty () { return 1; }
528 int tcsetpgrp (int pid);
529 void set_ctty (int ttynum, int flags);
530 int bg_check (int sig);
533 /* This is a input and output console handle */
534 class fhandler_console: public fhandler_termios
540 // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
559 void clear_screen (int, int, int, int);
560 void scroll_screen (int, int, int, int, int, int);
561 void cursor_set (BOOL, int, int);
562 void cursor_get (int *, int *);
563 void cursor_rel (int, int);
564 const unsigned char * write_normal (unsigned const char*, unsigned const char *);
565 void char_command (char);
566 int output_tcsetattr (int a, const struct termios *t);
569 int igncr_enabled ();
570 int input_tcsetattr (int a, const struct termios *t);
571 void set_cursor_maybe ();
575 fhandler_console (const char *name);
577 fhandler_console* is_console () { return this; }
579 int open (const char *path, int flags, mode_t mode = 0);
581 int write (const void *ptr, size_t len);
582 void doecho (const void *str, DWORD len) { (void) write (str, len); }
583 int read (void *ptr, size_t len);
587 int tcsetattr (int a, const struct termios *t);
588 int tcgetattr (struct termios *t);
590 int tcsetpgrp (const pid_t pid) { tc->pgid = pid; return 0; }
592 /* Special dup as we must dup two handles */
593 int dup (fhandler_base *child);
595 int ioctl (unsigned int cmd, void *);
596 void init (HANDLE, DWORD, mode_t);
598 select_record *select_read (select_record *s);
599 select_record *select_write (select_record *s);
600 select_record *select_except (select_record *s);
601 int ready_for_read (int fd, DWORD howlong, int ignra);
602 void fixup_after_exec (HANDLE);
603 void set_close_on_exec (int val);
604 void fixup_after_fork (HANDLE parent);
605 void set_input_state ()
607 if (TTYISSETF (RSTCONS))
608 input_tcsetattr (0, &tc->ti);
612 class fhandler_tty_common: public fhandler_termios
615 fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
616 fhandler_termios (dev, name, unit),
621 HANDLE output_done_event; // Raised by master when tty's output buffer
622 // written. Write status in tty::write_retval.
623 HANDLE ioctl_request_event; // Raised by slave to perform ioctl() request.
624 // Ioctl() request in tty::cmd/arg.
625 HANDLE ioctl_done_event; // Raised by master on ioctl() completion.
626 // Ioctl() status in tty::ioctl_retval.
628 HANDLE inuse; // used to indicate that a tty is in use
631 DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
632 void __release_output_mutex (const char *fn, int ln);
634 int ttynum; // Master tty num.
635 virtual int dup (fhandler_base *child);
637 tty *get_ttyp () { return (tty *)tc; }
638 int get_unit () { return ttynum; }
641 void set_close_on_exec (int val);
642 void fixup_after_fork (HANDLE parent);
643 select_record *select_read (select_record *s);
644 select_record *select_write (select_record *s);
645 select_record *select_except (select_record *s);
646 int ready_for_read (int fd, DWORD howlong, int ignra);
649 class fhandler_tty_slave: public fhandler_tty_common
653 fhandler_tty_slave (const char *name);
654 fhandler_tty_slave (int, const char *name);
656 int open (const char *path, int flags, mode_t mode = 0);
657 int write (const void *ptr, size_t len);
658 int read (void *ptr, size_t len);
659 void init (HANDLE, DWORD, mode_t);
661 int tcsetattr (int a, const struct termios *t);
662 int tcgetattr (struct termios *t);
664 int ioctl (unsigned int cmd, void *);
666 off_t lseek (off_t, int) { return 0; }
669 class fhandler_pty_master: public fhandler_tty_common
671 int pktmode; // non-zero if pty in a packet mode.
673 int need_nl; // Next read should start with \n
676 fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
678 int process_slave_output (char *buf, size_t len, int pktmode_on);
679 void doecho (const void *str, DWORD len);
681 int open (const char *path, int flags, mode_t mode = 0);
682 int write (const void *ptr, size_t len);
683 int read (void *ptr, size_t len);
686 int tcsetattr (int a, const struct termios *t);
687 int tcgetattr (struct termios *t);
689 int ioctl (unsigned int cmd, void *);
691 off_t lseek (off_t, int) { return 0; }
694 void set_close_on_exec (int val);
695 void fixup_after_fork (HANDLE parent);
699 class fhandler_tty_master: public fhandler_pty_master
703 fhandler_tty_master (const char *name, int unit);
704 fhandler_console *console; // device handler to perform real i/o.
705 HANDLE hThread; // process_output thread handle.
709 void fixup_after_fork (HANDLE parent);
710 void fixup_after_exec (HANDLE);
713 class fhandler_dev_null: public fhandler_base
716 fhandler_dev_null (const char *name);
719 select_record *select_read (select_record *s);
720 select_record *select_write (select_record *s);
721 select_record *select_except (select_record *s);
724 class fhandler_dev_zero: public fhandler_base
727 fhandler_dev_zero (const char *name);
728 int open (const char *path, int flags, mode_t mode = 0);
729 int write (const void *ptr, size_t len);
730 int read (void *ptr, size_t len);
731 off_t lseek (off_t offset, int whence);
737 class fhandler_dev_random: public fhandler_base
741 HCRYPTPROV crypt_prov;
744 BOOL crypt_gen_random (void *ptr, size_t len);
745 int pseudo_write (const void *ptr, size_t len);
746 int pseudo_read (void *ptr, size_t len);
749 fhandler_dev_random (const char *name, int unit);
750 int get_unit () { return unit; }
751 int open (const char *path, int flags, mode_t mode = 0);
752 int write (const void *ptr, size_t len);
753 int read (void *ptr, size_t len);
754 off_t lseek (off_t offset, int whence);
756 int dup (fhandler_base *child);
761 class fhandler_windows: public fhandler_base
764 HWND hWnd_; // the window whose messages are to be retrieved by read() call
765 int method_; // write method (Post or Send)
767 fhandler_windows (const char *name = 0);
768 int is_windows (void) { return 1; }
769 int open (const char *path, int flags, mode_t mode = 0);
770 int write (const void *ptr, size_t len);
771 int read (void *ptr, size_t len);
772 int ioctl (unsigned int cmd, void *);
773 off_t lseek (off_t, int) { return 0; }
774 int close (void) { return 0; }
776 void set_close_on_exec (int val);
777 void fixup_after_fork (HANDLE parent);
778 select_record *select_read (select_record *s);
779 select_record *select_write (select_record *s);
780 select_record *select_except (select_record *s);
781 int ready_for_read (int fd, DWORD howlong, int ignra);
785 /* You can't do this */
788 fhandler_normal normal;
789 fhandler_dev_null dev_null;
794 #define fhandler_union fhandler_console
803 BOOL read_ready, write_ready, except_ready;
804 BOOL read_selected, write_selected, except_selected;
805 int (*startup) (select_record *me, class select_stuff *stuff);
806 int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
808 int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
810 void (*cleanup) (select_record *me, class select_stuff *stuff);
811 struct select_record *next;
813 select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
814 fh (in_fh), saw_error (0), windows_handle (0),
815 read_ready (0), write_ready (0), except_ready (0),
816 read_selected (0), write_selected (0), except_selected (0),
817 startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
825 select_stuff (): always_ready (0), windows_used (0), start (0)
827 memset (device_specific, 0, sizeof (device_specific));
829 BOOL always_ready, windows_used;
831 void *device_specific[FH_NDEV];
833 int test_and_set (int i, fd_set *readfds, fd_set *writefds,
835 int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
836 int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
839 uid_t __stdcall get_file_owner (int, const char *);
840 gid_t __stdcall get_file_group (int, const char *);
842 #endif /* _FHANDLER_H_ */