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_dev_mem /dev/mem implementation (fhandler_mem.cc)
46 fhandler_proc Interesting possibility, not implemented yet
51 FH_RBINARY = 0x00001000, /* binary read mode */
52 FH_WBINARY = 0x00002000, /* binary write mode */
53 FH_CLOEXEC = 0x00004000, /* close-on-exec */
54 FH_RBINSET = 0x00008000, /* binary read mode has been explicitly set */
55 FH_WBINSET = 0x00010000, /* binary write mode has been explicitly set */
56 FH_APPEND = 0x00020000, /* always append */
57 FH_ASYNC = 0x00040000, /* async I/O */
58 FH_HADEOF = 0x00080000, /* EOF seen */
60 FH_SYMLINK = 0x00100000, /* is a symlink */
61 FH_EXECABL = 0x00200000, /* file looked like it would run:
62 * ends in .exe or .bat or begins with #! */
63 FH_W95LSBUG= 0x00400000, /* set when lseek is called as a flag that
64 * _write should check if we've moved beyond
65 * EOF, zero filling if so. */
66 FH_NOFRNAME= 0x00800000, /* Set if shouldn't free unix_path_name_ and
67 windows_path_name_ on destruction. */
68 FH_NOEINTR = 0x01000000, /* Set if I/O should be uninterruptible. */
69 FH_FFIXUP = 0x02000000, /* Set if need to fixup after fork. */
70 FH_LOCAL = 0x04000000, /* File is unix domain socket */
71 FH_FIFO = 0x08000000, /* File is FIFO */
72 FH_HASACLS = 0x40000000, /* True if fs of file has ACLS */
77 FH_CONSOLE = 0x00000001, /* is a console */
78 FH_CONIN = 0x00000002, /* console input */
79 FH_CONOUT = 0x00000003, /* console output */
80 FH_TTYM = 0x00000004, /* is a tty master */
81 FH_TTYS = 0x00000005, /* is a tty slave */
82 FH_PTYM = 0x00000006, /* is a pty master */
83 FH_SERIAL = 0x00000007, /* is a serial port */
84 FH_PIPE = 0x00000008, /* is a pipe */
85 FH_PIPER = 0x00000009, /* read end of a pipe */
86 FH_PIPEW = 0x0000000a, /* write end of a pipe */
87 FH_SOCKET = 0x0000000b, /* is a socket */
88 FH_WINDOWS = 0x0000000c, /* is a window */
90 FH_SLOW = 0x00000010, /* "slow" device if below this */
93 FH_DISK = 0x00000010, /* is a disk */
94 FH_FLOPPY = 0x00000011, /* is a floppy */
95 FH_TAPE = 0x00000012, /* is a tape */
96 FH_NULL = 0x00000013, /* is the null device */
97 FH_ZERO = 0x00000014, /* is the zero device */
98 FH_RANDOM = 0x00000015, /* is a random device */
99 FH_MEM = 0x00000016, /* is a mem device */
101 FH_NDEV = 0x00000017, /* Maximum number of devices */
102 FH_DEVMASK = 0x00000fff, /* devices live here */
106 #define FHDEVN(n) ((n) & FH_DEVMASK)
107 #define FHISSETF(x) __ISSETF (this, x, FH)
108 #define FHSETF(x) __SETF (this, x, FH)
109 #define FHCLEARF(x) __CLEARF (this, x, FH)
110 #define FHCONDSETF(n, x) __CONDSETF(n, this, x, FH)
114 extern const char *windows_device_names[];
115 extern struct __cygwin_perfile *perfile_table;
116 #define __fmode (*(user_data->fmode_ptr))
120 class fhandler_disk_file;
132 int rpos_; /* Used in text reading */
135 unsigned long namehash_; /* hashed filename, used as inode num */
137 /* Full unix path name of this file */
138 /* File open flags from open () and fcntl () calls */
142 char *rabuf; /* used for crlf conversion in text files */
148 char *unix_path_name_;
149 char *win32_path_name_;
152 void set_name (const char * unix_path, const char * win32_path = NULL,
155 virtual fhandler_base& operator =(fhandler_base &x);
156 fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
157 virtual ~fhandler_base ();
159 /* Non-virtual simple accessor functions. */
160 void set_io_handle (HANDLE);
162 void set_cb (size_t size) { cb = size; }
163 DWORD get_device () { return status & FH_DEVMASK; }
164 virtual int get_unit () { return 0; }
165 virtual BOOL is_slow () { return get_device () < FH_SLOW; }
167 int get_access () { return access_; }
168 void set_access (int x) { access_ = x; }
170 int get_async () { return FHISSETF (ASYNC); }
171 void set_async (int x) { FHCONDSETF (x, ASYNC); }
173 int get_flags () { return openflags_; }
174 void set_flags (int x) { openflags_ = x; }
176 int get_w_binary () { return FHISSETF (WBINARY); }
177 int get_r_binary () { return FHISSETF (RBINARY); }
179 int get_w_binset () { return FHISSETF (WBINSET); }
180 int get_r_binset () { return FHISSETF (RBINSET); }
182 void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
183 void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
185 int get_default_fmode (int flags);
187 int get_r_no_interrupt () { return FHISSETF (NOEINTR); }
188 void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); }
190 int get_close_on_exec () { return FHISSETF (CLOEXEC); }
191 int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); }
193 void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); }
194 int get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); }
196 int get_need_fork_fixup () { return FHISSETF (FFIXUP); }
197 void set_need_fork_fixup () { FHSETF (FFIXUP); }
199 virtual void set_close_on_exec (int val);
200 virtual void fixup_after_fork (HANDLE parent);
202 int get_symlink_p () { return FHISSETF (SYMLINK); }
203 void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); }
204 void set_symlink_p () { FHSETF (SYMLINK); }
206 int get_socket_p () { return FHISSETF (LOCAL); }
207 void set_socket_p (int val) { FHCONDSETF (val, LOCAL); }
208 void set_socket_p () { FHSETF (LOCAL); }
210 int get_execable_p () { return FHISSETF (EXECABL); }
211 void set_execable_p (int val) { FHCONDSETF (val, EXECABL); }
212 void set_execable_p () { FHSETF (EXECABL); }
214 int get_append_p () { return FHISSETF (APPEND); }
215 void set_append_p (int val) { FHCONDSETF (val, APPEND); }
216 void set_append_p () { FHSETF (APPEND); }
218 int get_readahead_valid () { return raixget < ralen; }
219 int puts_readahead (const char *s, size_t len = (size_t) -1);
220 int put_readahead (char value);
222 int get_readahead ();
223 int peek_readahead (int queryput = 0);
225 int eat_readahead (int n);
227 void set_readahead_valid (int val, int ch = -1);
229 int get_readahead_into_buffer (char *buf, size_t buflen);
231 int has_acls () { return FHISSETF (HASACLS); }
232 void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
234 int no_free_names () { return FHISSETF (NOFRNAME); }
235 void set_no_free_names (int val) { FHCONDSETF (val, NOFRNAME); }
236 void set_no_free_names () { FHSETF (NOFRNAME); }
238 const char *get_name () { return unix_path_name_; }
239 const char *get_win32_name () { return win32_path_name_; }
240 unsigned long get_namehash () { return namehash_; }
242 virtual void hclose (HANDLE h) {CloseHandle (h);}
243 virtual void set_inheritance (HANDLE &h, int not_inheriting,
244 const char *name = NULL);
246 /* fixup fd possibly non-inherited handles after fork */
247 void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
249 /* Potentially overridden virtual functions. */
250 virtual int open (const char *, int flags, mode_t mode = 0)
252 return open (flags, mode);
254 virtual int open (int flags, mode_t mode = 0);
255 virtual int close ();
256 virtual int fstat (struct stat *buf);
257 virtual int ioctl (unsigned int cmd, void *);
258 virtual char const * ttyname () { return get_name(); }
259 virtual int read (void *ptr, size_t len);
260 virtual int write (const void *ptr, size_t len);
261 virtual off_t lseek (off_t offset, int whence);
262 virtual int lock (int, struct flock *);
263 virtual void dump ();
264 virtual int dup (fhandler_base *child);
266 void *operator new (size_t, void *p) {return p;}
268 virtual void init (HANDLE, DWORD, mode_t);
270 virtual int tcflush (int);
271 virtual int tcsendbreak (int);
272 virtual int tcdrain ();
273 virtual int tcflow (int);
274 virtual int tcsetattr (int a, const struct termios *t);
275 virtual int tcgetattr (struct termios *t);
276 virtual int tcsetpgrp (const pid_t pid);
277 virtual int tcgetpgrp ();
278 virtual int is_tty () { return 0; }
279 virtual BOOL is_device () { return TRUE; }
280 virtual char *ptsname () { return NULL;}
281 virtual class fhandler_socket *is_socket () { return 0; }
282 virtual class fhandler_console *is_console () { return 0; }
283 virtual int is_windows () {return 0; }
285 virtual int raw_read (void *ptr, size_t ulen);
286 virtual int raw_write (const void *ptr, size_t ulen);
288 virtual void fixup_after_exec (HANDLE) {}
290 /* Virtual accessor functions to hide the fact
291 that some fd's have two handles. */
292 virtual HANDLE get_handle () const { return io_handle; }
293 virtual HANDLE get_io_handle () const { return io_handle; }
294 virtual HANDLE get_output_handle () const { return io_handle; }
295 virtual BOOL hit_eof () {return FALSE;}
296 virtual select_record *select_read (select_record *s);
297 virtual select_record *select_write (select_record *s);
298 virtual select_record *select_except (select_record *s);
299 virtual int ready_for_read (int fd, DWORD howlong, int ignra);
300 virtual const char * get_native_name ()
302 return windows_device_names[FHDEVN (status)];
304 virtual int bg_check (int) {return 1;}
305 void clear_readahead ()
307 raixput = raixget = ralen = rabuflen = 0;
310 void operator delete (void *);
313 class fhandler_socket: public fhandler_base
318 fhandler_socket (const char *name = 0);
319 fhandler_socket (unsigned int, const char *name = 0);
320 int get_socket () const { return (int) get_handle(); }
321 fhandler_socket * is_socket () { return this; }
322 int write (const void *ptr, size_t len);
323 int read (void *ptr, size_t len);
324 int ioctl (unsigned int cmd, void *);
325 off_t lseek (off_t, int) { return 0; }
327 void hclose (HANDLE) {close ();}
329 select_record *select_read (select_record *s);
330 select_record *select_write (select_record *s);
331 select_record *select_except (select_record *s);
332 int ready_for_read (int fd, DWORD howlong, int ignra);
333 int get_addr_family () {return addr_family;}
334 void set_addr_family (int af) {addr_family = af;}
337 class fhandler_pipe: public fhandler_base
340 fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE);
341 off_t lseek (off_t offset, int whence);
342 /* This strange test is due to the fact that we can't rely on
343 Windows shells to "do the right thing" with pipes. Apparently
344 the can keep one end of the pipe open when it shouldn't be. */
345 BOOL is_slow () {return os_being_run == winNT;}
346 select_record *select_read (select_record *s);
347 select_record *select_write (select_record *s);
348 select_record *select_except (select_record *s);
349 int ready_for_read (int fd, DWORD howlong, int ignra);
352 class fhandler_dev_raw: public fhandler_base
359 int eom_detected : 1;
360 int eof_detected : 1;
361 int lastblk_to_read : 1;
367 virtual void clear (void);
368 virtual int writebuf (void);
370 /* returns not null, if `win_error' determines an end of media condition */
371 virtual int is_eom(int win_error) = 0;
372 /* returns not null, if `win_error' determines an end of file condition */
373 virtual int is_eof(int win_error) = 0;
375 fhandler_dev_raw (DWORD dev, const char *name, int unit);
378 ~fhandler_dev_raw (void);
380 int open (const char *path, int flags, mode_t mode = 0);
383 int raw_read (void *ptr, size_t ulen);
384 int raw_write (const void *ptr, size_t ulen);
386 int fstat (struct stat *buf);
388 int dup (fhandler_base *child);
390 int ioctl (unsigned int cmd, void *buf);
393 class fhandler_dev_floppy: public fhandler_dev_raw
396 virtual int is_eom (int win_error);
397 virtual int is_eof (int win_error);
400 fhandler_dev_floppy (const char *name, int unit);
402 virtual int open (const char *path, int flags, mode_t mode = 0);
403 virtual int close (void);
405 virtual off_t lseek (off_t offset, int whence);
407 virtual int ioctl (unsigned int cmd, void *buf);
410 class fhandler_dev_tape: public fhandler_dev_raw
416 virtual void clear (void);
418 virtual int is_eom (int win_error);
419 virtual int is_eof (int win_error);
422 fhandler_dev_tape (const char *name, int unit);
424 virtual int open (const char *path, int flags, mode_t mode = 0);
425 virtual int close (void);
427 virtual off_t lseek (off_t offset, int whence);
429 virtual int fstat (struct stat *buf);
431 virtual int dup (fhandler_base *child);
433 virtual int ioctl (unsigned int cmd, void *buf);
436 int tape_write_marks (int marktype, DWORD len);
437 int tape_get_pos (unsigned long *ret);
438 int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
439 int tape_erase (int mode);
440 int tape_prepare (int action);
441 BOOLEAN tape_get_feature (DWORD parm);
442 int tape_get_blocksize (long *min, long *def, long *max, long *cur);
443 int tape_set_blocksize (long count);
444 int tape_status (struct mtget *get);
445 int tape_compression (long count);
448 /* Standard disk file */
450 class fhandler_disk_file: public fhandler_base
453 int check_execable_p (const char *path);
456 fhandler_disk_file (const char *name);
458 int open (const char *path, int flags, mode_t mode = 0);
459 int open (path_conv& real_path, int flags, mode_t mode);
461 int lock (int, struct flock *);
462 BOOL is_device () { return FALSE; }
463 int fstat (struct stat *buf);
466 class fhandler_serial: public fhandler_base
469 unsigned int vmin_; /* from termios */
470 unsigned int vtime_; /* from termios */
474 int overlapped_armed;
475 OVERLAPPED io_status;
478 fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
480 int open (const char *path, int flags, mode_t mode);
482 void init (HANDLE h, DWORD a, mode_t flags);
483 void overlapped_setup ();
484 int dup (fhandler_base *child);
485 int raw_read (void *ptr, size_t ulen);
486 int raw_write (const void *ptr, size_t ulen);
487 int tcsendbreak (int);
490 int tcsetattr (int a, const struct termios *t);
491 int tcgetattr (struct termios *t);
492 off_t lseek (off_t, int) { return 0; }
495 int is_tty () { return 1; }
496 void fixup_after_fork (HANDLE parent);
497 void fixup_after_exec (HANDLE);
499 /* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
500 don't use it for permissions checking. fhandler_tty_slave does
501 permission checking on pgrps. */
502 virtual int tcgetpgrp () { return pgrp_; }
503 virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
504 select_record *select_read (select_record *s);
505 select_record *select_write (select_record *s);
506 select_record *select_except (select_record *s);
507 int ready_for_read (int fd, DWORD howlong, int ignra);
510 #define acquire_output_mutex(ms) \
511 __acquire_output_mutex (__PRETTY_FUNCTION__, __LINE__, ms);
513 #define release_output_mutex() \
514 __release_output_mutex (__PRETTY_FUNCTION__, __LINE__);
518 class fhandler_termios: public fhandler_base
521 HANDLE output_handle;
522 virtual void doecho (const void *, DWORD) {};
523 virtual int accept_input () {return 1;};
526 fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
527 fhandler_base (dev, name, unit)
531 HANDLE get_output_handle () const { return output_handle; }
532 int line_edit (const char *rptr, int nread, int always_accept = 0);
533 void set_output_handle (HANDLE h) { output_handle = h; }
534 void tcinit (tty_min *this_tc, int force = FALSE);
535 virtual int is_tty () { return 1; }
537 int tcsetpgrp (int pid);
538 void set_ctty (int ttynum, int flags);
539 int bg_check (int sig);
540 virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
541 virtual void __release_output_mutex (const char *fn, int ln) {}
544 /* This is a input and output console handle */
545 class fhandler_console: public fhandler_termios
551 // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
570 void clear_screen (int, int, int, int);
571 void scroll_screen (int, int, int, int, int, int);
572 void cursor_set (BOOL, int, int);
573 void cursor_get (int *, int *);
574 void cursor_rel (int, int);
575 const unsigned char * write_normal (unsigned const char*, unsigned const char *);
576 void char_command (char);
577 int output_tcsetattr (int a, const struct termios *t);
580 int igncr_enabled ();
581 int input_tcsetattr (int a, const struct termios *t);
582 void set_cursor_maybe ();
586 fhandler_console (const char *name);
588 fhandler_console* is_console () { return this; }
590 int open (const char *path, int flags, mode_t mode = 0);
592 int write (const void *ptr, size_t len);
593 void doecho (const void *str, DWORD len) { (void) write (str, len); }
594 int read (void *ptr, size_t len);
598 int tcsetattr (int a, const struct termios *t);
599 int tcgetattr (struct termios *t);
601 int tcsetpgrp (const pid_t pid);
603 /* Special dup as we must dup two handles */
604 int dup (fhandler_base *child);
606 int ioctl (unsigned int cmd, void *);
607 void init (HANDLE, DWORD, mode_t);
609 select_record *select_read (select_record *s);
610 select_record *select_write (select_record *s);
611 select_record *select_except (select_record *s);
612 int ready_for_read (int fd, DWORD howlong, int ignra);
613 void fixup_after_exec (HANDLE);
614 void set_close_on_exec (int val);
615 void fixup_after_fork (HANDLE parent);
616 void set_input_state ();
619 class fhandler_tty_common: public fhandler_termios
622 fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
623 fhandler_termios (dev, name, unit),
628 HANDLE output_done_event; // Raised by master when tty's output buffer
629 // written. Write status in tty::write_retval.
630 HANDLE ioctl_request_event; // Raised by slave to perform ioctl() request.
631 // Ioctl() request in tty::cmd/arg.
632 HANDLE ioctl_done_event; // Raised by master on ioctl() completion.
633 // Ioctl() status in tty::ioctl_retval.
635 HANDLE inuse; // used to indicate that a tty is in use
638 DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
639 void __release_output_mutex (const char *fn, int ln);
641 int ttynum; // Master tty num.
642 virtual int dup (fhandler_base *child);
644 tty *get_ttyp () { return (tty *)tc; }
645 int get_unit () { return ttynum; }
648 void set_close_on_exec (int val);
649 void fixup_after_fork (HANDLE parent);
650 select_record *select_read (select_record *s);
651 select_record *select_write (select_record *s);
652 select_record *select_except (select_record *s);
653 int ready_for_read (int fd, DWORD howlong, int ignra);
656 class fhandler_tty_slave: public fhandler_tty_common
660 fhandler_tty_slave (const char *name);
661 fhandler_tty_slave (int, const char *name);
663 int open (const char *path, int flags, mode_t mode = 0);
664 int write (const void *ptr, size_t len);
665 int read (void *ptr, size_t len);
666 void init (HANDLE, DWORD, mode_t);
668 int tcsetattr (int a, const struct termios *t);
669 int tcgetattr (struct termios *t);
671 int ioctl (unsigned int cmd, void *);
673 off_t lseek (off_t, int) { return 0; }
676 class fhandler_pty_master: public fhandler_tty_common
678 int pktmode; // non-zero if pty in a packet mode.
680 int need_nl; // Next read should start with \n
683 fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
685 int process_slave_output (char *buf, size_t len, int pktmode_on);
686 void doecho (const void *str, DWORD len);
688 int open (const char *path, int flags, mode_t mode = 0);
689 int write (const void *ptr, size_t len);
690 int read (void *ptr, size_t len);
693 int tcsetattr (int a, const struct termios *t);
694 int tcgetattr (struct termios *t);
696 int ioctl (unsigned int cmd, void *);
698 off_t lseek (off_t, int) { return 0; }
701 void set_close_on_exec (int val);
705 class fhandler_tty_master: public fhandler_pty_master
709 fhandler_tty_master (const char *name, int unit);
710 fhandler_console *console; // device handler to perform real i/o.
711 HANDLE hThread; // process_output thread handle.
715 void fixup_after_fork (HANDLE parent);
716 void fixup_after_exec (HANDLE);
719 class fhandler_dev_null: public fhandler_base
722 fhandler_dev_null (const char *name);
725 select_record *select_read (select_record *s);
726 select_record *select_write (select_record *s);
727 select_record *select_except (select_record *s);
730 class fhandler_dev_zero: public fhandler_base
733 fhandler_dev_zero (const char *name);
734 int open (const char *path, int flags, mode_t mode = 0);
735 int write (const void *ptr, size_t len);
736 int read (void *ptr, size_t len);
737 off_t lseek (off_t offset, int whence);
743 class fhandler_dev_random: public fhandler_base
747 HCRYPTPROV crypt_prov;
750 BOOL crypt_gen_random (void *ptr, size_t len);
751 int pseudo_write (const void *ptr, size_t len);
752 int pseudo_read (void *ptr, size_t len);
755 fhandler_dev_random (const char *name, int unit);
756 int get_unit () { return unit; }
757 int open (const char *path, int flags, mode_t mode = 0);
758 int write (const void *ptr, size_t len);
759 int read (void *ptr, size_t len);
760 off_t lseek (off_t offset, int whence);
762 int dup (fhandler_base *child);
767 class fhandler_dev_mem: public fhandler_base
773 fhandler_dev_mem (const char *name, int unit);
774 ~fhandler_dev_mem (void);
776 int open (const char *path, int flags, mode_t mode = 0);
777 int write (const void *ptr, size_t ulen);
778 int read (void *ptr, size_t ulen);
779 off_t lseek (off_t offset, int whence);
781 int fstat (struct stat *buf);
782 int dup (fhandler_base *child);
787 class fhandler_windows: public fhandler_base
790 HWND hWnd_; // the window whose messages are to be retrieved by read() call
791 int method_; // write method (Post or Send)
793 fhandler_windows (const char *name = 0);
794 int is_windows (void) { return 1; }
795 int open (const char *path, int flags, mode_t mode = 0);
796 int write (const void *ptr, size_t len);
797 int read (void *ptr, size_t len);
798 int ioctl (unsigned int cmd, void *);
799 off_t lseek (off_t, int) { return 0; }
800 int close (void) { return 0; }
802 void set_close_on_exec (int val);
803 void fixup_after_fork (HANDLE parent);
804 select_record *select_read (select_record *s);
805 select_record *select_write (select_record *s);
806 select_record *select_except (select_record *s);
807 int ready_for_read (int fd, DWORD howlong, int ignra);
811 /* You can't do this */
814 fhandler_normal normal;
815 fhandler_dev_null dev_null;
820 #define fhandler_union fhandler_console
829 BOOL read_ready, write_ready, except_ready;
830 BOOL read_selected, write_selected, except_selected;
831 int (*startup) (select_record *me, class select_stuff *stuff);
832 int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
834 int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
836 void (*cleanup) (select_record *me, class select_stuff *stuff);
837 struct select_record *next;
839 select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
840 fh (in_fh), saw_error (0), windows_handle (0),
841 read_ready (0), write_ready (0), except_ready (0),
842 read_selected (0), write_selected (0), except_selected (0),
843 startup (NULL), poll (NULL), verify (NULL), cleanup (NULL),
851 select_stuff (): always_ready (0), windows_used (0), start (0)
853 memset (device_specific, 0, sizeof (device_specific));
855 BOOL always_ready, windows_used;
857 void *device_specific[FH_NDEV];
859 int test_and_set (int i, fd_set *readfds, fd_set *writefds,
861 int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
862 int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
865 uid_t __stdcall get_file_owner (int, const char *);
866 gid_t __stdcall get_file_group (int, const char *);
867 int __stdcall set_console_state_for_spawn ();
869 #endif /* _FHANDLER_H_ */