1 /* fhandler.cc. See console.cc for fhandler_console functions.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
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
15 #include <sys/cygwin.h>
19 #include "perprocess.h"
21 #include "cygwin/version.h"
26 #include "shared_info.h"
31 static NO_COPY
const int CHUNK_SIZE
= 1024; /* Used for crlf conversions */
33 struct __cygwin_perfile
*perfile_table
;
38 fhandler_base::operator =(fhandler_base
&x
)
40 memcpy (this, &x
, sizeof *this);
41 unix_path_name
= x
.unix_path_name
? cstrdup (x
.unix_path_name
) : NULL
;
42 win32_path_name
= x
.win32_path_name
? cstrdup (x
.win32_path_name
) : NULL
;
52 fhandler_base::puts_readahead (const char *s
, size_t len
)
55 while ((*s
|| (len
!= (size_t) -1 && len
--))
56 && (success
= put_readahead (*s
++) > 0))
62 fhandler_base::put_readahead (char value
)
65 if (raixput
< rabuflen
)
67 else if ((newrabuf
= (char *) realloc (rabuf
, rabuflen
+= 32)))
72 rabuf
[raixput
++] = value
;
78 fhandler_base::get_readahead ()
82 chret
= ((unsigned char) rabuf
[raixget
++]) & 0xff;
83 /* FIXME - not thread safe */
85 raixget
= raixput
= ralen
= 0;
90 fhandler_base::peek_readahead (int queryput
)
93 if (!queryput
&& raixget
< ralen
)
94 chret
= ((unsigned char) rabuf
[raixget
]) & 0xff;
95 else if (queryput
&& raixput
> 0)
96 chret
= ((unsigned char) rabuf
[raixput
- 1]) & 0xff;
101 fhandler_base::set_readahead_valid (int val
, int ch
)
104 ralen
= raixget
= raixput
= 0;
110 fhandler_base::eat_readahead (int n
)
117 if ((int) (ralen
-= n
) < 0)
120 if (raixget
>= ralen
)
121 raixget
= raixput
= ralen
= 0;
122 else if (raixput
> ralen
)
130 fhandler_base::get_readahead_into_buffer (char *buf
, size_t buflen
)
133 int copied_chars
= 0;
136 if ((ch
= get_readahead ()) < 0)
140 buf
[copied_chars
++] = (unsigned char)(ch
& 0xff);
147 /* Record the file name.
148 Filenames are used mostly for debugging messages, and it's hoped that
149 in cases where the name is really required, the filename wouldn't ever
150 be too long (e.g. devices or some such).
151 The unix_path_name is also used by virtual fhandlers. */
153 fhandler_base::set_name (const char *unix_path
, const char *win32_path
, int unit
)
155 if (unix_path
== NULL
|| !*unix_path
)
159 win32_path_name
= cstrdup (win32_path
);
162 const char *fmt
= get_native_name ();
163 char *w
= (char *) cmalloc (HEAP_STR
, strlen (fmt
) + 16);
164 __small_sprintf (w
, fmt
, unit
);
168 if (win32_path_name
== NULL
)
170 system_printf ("fatal error. strdup failed");
174 assert (unix_path_name
== NULL
);
175 /* FIXME: This isn't really right. It ignores the first argument if we're
176 building names for a device and just converts the device name from the
177 win32 name since it has theoretically been previously detected by
178 path_conv. Ideally, we should pass in a format string and build the
180 if (!is_device () || *win32_path_name
!= '\\')
181 unix_path_name
= unix_path
;
184 char *p
= cstrdup (win32_path_name
);
186 while ((p
= strchr (p
, '\\')) != NULL
)
189 cfree ((void *) unix_path
);
192 if (unix_path_name
== NULL
)
194 system_printf ("fatal error. strdup failed");
197 namehash
= hash_path_name (0, win32_path_name
);
200 /* Detect if we are sitting at EOF for conditions where Windows
201 returns an error but UNIX doesn't. */
203 is_at_eof (HANDLE h
, DWORD err
)
205 DWORD size
, upper1
, curr
;
207 size
= GetFileSize (h
, &upper1
);
208 if (upper1
!= 0xffffffff || GetLastError () == NO_ERROR
)
211 curr
= SetFilePointer (h
, 0, &upper2
, FILE_CURRENT
);
212 if (curr
== size
&& upper1
== (DWORD
) upper2
)
221 fhandler_base::set_flags (int flags
, int supplied_bin
)
225 debug_printf ("flags %p, supplied_bin %p", flags
, supplied_bin
);
226 if ((bin
= flags
& (O_BINARY
| O_TEXT
)))
227 debug_printf ("O_TEXT/O_BINARY set in flags %p", bin
);
228 else if (get_r_binset () && get_w_binset ())
229 bin
= get_r_binary () ? O_BINARY
: O_TEXT
; // FIXME: Not quite right
230 else if ((fmode
= get_default_fmode (flags
)) & O_BINARY
)
232 else if (fmode
& O_TEXT
)
234 else if (supplied_bin
)
237 bin
= get_w_binary () || get_r_binary () || (binmode
!= O_TEXT
)
240 openflags
= flags
| bin
;
245 syscall_printf ("filemode set to %s", bin
? "binary" : "text");
248 /* Normal file i/o handlers. */
250 /* Cover function to ReadFile to achieve (as much as possible) Posix style
251 semantics and use of errno. */
253 fhandler_base::raw_read (void *ptr
, size_t ulen
)
257 if (!ReadFile (get_handle (), ptr
, ulen
, &bytes_read
, 0))
261 /* Some errors are not really errors. Detect such cases here. */
263 errcode
= GetLastError ();
266 case ERROR_BROKEN_PIPE
:
267 /* This is really EOF. */
270 case ERROR_MORE_DATA
:
271 /* `bytes_read' is supposedly valid. */
274 if (is_at_eof (get_handle (), errcode
))
276 case ERROR_INVALID_FUNCTION
:
277 case ERROR_INVALID_PARAMETER
:
278 case ERROR_INVALID_HANDLE
:
279 if (openflags
& O_DIROPEN
)
285 syscall_printf ("ReadFile %s failed, %E", unix_path_name
);
286 __seterrno_from_win_error (errcode
);
295 /* Cover function to WriteFile to provide Posix interface and semantics
296 (as much as possible). */
298 fhandler_base::raw_write (const void *ptr
, size_t len
)
302 if (!WriteFile (get_handle (), ptr
, len
, &bytes_written
, 0))
304 if (GetLastError () == ERROR_DISK_FULL
&& bytes_written
> 0)
305 return bytes_written
;
307 if (get_errno () == EPIPE
)
311 return bytes_written
;
314 #define ACCFLAGS(x) (x & (O_RDONLY | O_WRONLY | O_RDWR))
316 fhandler_base::get_default_fmode (int flags
)
321 size_t nlen
= strlen (get_name ());
322 unsigned accflags
= ACCFLAGS (flags
);
323 for (__cygwin_perfile
*pf
= perfile_table
; pf
->name
; pf
++)
324 if (!*pf
->name
&& ACCFLAGS (pf
->flags
) == accflags
)
326 fmode
= pf
->flags
& ~(O_RDONLY
| O_WRONLY
| O_RDWR
);
331 size_t pflen
= strlen (pf
->name
);
332 const char *stem
= get_name () + nlen
- pflen
;
333 if (pflen
> nlen
|| (stem
!= get_name () && !isdirsep (stem
[-1])))
335 else if (ACCFLAGS (pf
->flags
) == accflags
&& strcasematch (stem
, pf
->name
))
337 fmode
= pf
->flags
& ~(O_RDONLY
| O_WRONLY
| O_RDWR
);
345 /* Open system call handler function. */
347 fhandler_base::open (path_conv
*pc
, int flags
, mode_t mode
)
353 int creation_distribution
;
354 SECURITY_ATTRIBUTES sa
= sec_none
;
356 syscall_printf ("(%s, %p) query_open %d", get_win32_name (), flags
, get_query_open ());
358 if (get_win32_name () == NULL
)
364 if (get_query_open ())
366 else if (get_device () == FH_TAPE
)
367 access
= GENERIC_READ
| GENERIC_WRITE
;
368 else if ((flags
& (O_RDONLY
| O_WRONLY
| O_RDWR
)) == O_RDONLY
)
369 access
= GENERIC_READ
;
370 else if ((flags
& (O_RDONLY
| O_WRONLY
| O_RDWR
)) == O_WRONLY
)
371 access
= GENERIC_WRITE
;
373 access
= GENERIC_READ
| GENERIC_WRITE
;
375 /* Allow reliable lseek on disk devices. */
376 if (get_device () == FH_FLOPPY
)
377 access
|= GENERIC_READ
;
379 /* FIXME: O_EXCL handling? */
381 if ((flags
& O_TRUNC
) && ((flags
& O_ACCMODE
) != O_RDONLY
))
384 creation_distribution
= CREATE_ALWAYS
;
386 creation_distribution
= TRUNCATE_EXISTING
;
388 else if (flags
& O_CREAT
)
389 creation_distribution
= OPEN_ALWAYS
;
391 creation_distribution
= OPEN_EXISTING
;
393 if ((flags
& O_EXCL
) && (flags
& O_CREAT
))
394 creation_distribution
= CREATE_NEW
;
396 if (flags
& O_APPEND
)
399 /* These flags are host dependent. */
400 shared
= wincap
.shared ();
402 file_attributes
= FILE_ATTRIBUTE_NORMAL
;
403 if (flags
& O_DIROPEN
)
404 file_attributes
|= FILE_FLAG_BACKUP_SEMANTICS
;
405 if (get_device () == FH_SERIAL
)
406 file_attributes
|= FILE_FLAG_OVERLAPPED
;
408 #ifdef HIDDEN_DOT_FILES
409 if (flags
& O_CREAT
&& get_device () == FH_DISK
)
411 char *c
= strrchr (get_win32_name (), '\\');
412 if ((c
&& c
[1] == '.') || *get_win32_name () == '.')
413 file_attributes
|= FILE_ATTRIBUTE_HIDDEN
;
417 /* CreateFile() with dwDesiredAccess == 0 when called on remote
418 share returns some handle, even if file doesn't exist. This code
419 works around this bug. */
420 if (get_query_open () && isremote () &&
421 creation_distribution
== OPEN_EXISTING
&& pc
&& !pc
->exists ())
427 /* If mode has no write bits set, we set the R/O attribute. */
428 if (!(mode
& (S_IWUSR
| S_IWGRP
| S_IWOTH
)))
429 file_attributes
|= FILE_ATTRIBUTE_READONLY
;
431 /* If the file should actually be created and ntsec is on,
432 set files attributes. */
433 if (flags
& O_CREAT
&& get_device () == FH_DISK
&& allow_ntsec
&& has_acls ())
434 set_security_attribute (mode
, &sa
, alloca (4096), 4096);
436 x
= CreateFile (get_win32_name (), access
, shared
, &sa
, creation_distribution
,
439 syscall_printf ("%p = CreateFile (%s, %p, %p, %p, %p, %p, 0)",
440 x
, get_win32_name (), access
, shared
, &sa
,
441 creation_distribution
, file_attributes
);
443 if (x
== INVALID_HANDLE_VALUE
)
445 if (pc
->isdir () && !wincap
.can_open_directories ())
447 if (mode
& (O_CREAT
| O_EXCL
) == (O_CREAT
| O_EXCL
))
449 else if (mode
& (O_WRONLY
| O_RDWR
))
454 else if (GetLastError () == ERROR_INVALID_HANDLE
)
458 if (!get_nohandle ())
462 /* Attributes may be set only if a file is _really_ created.
463 This code is now only used for ntea here since the files
464 security attributes are set in CreateFile () now. */
465 if (flags
& O_CREAT
&& get_device () == FH_DISK
466 && GetLastError () != ERROR_ALREADY_EXISTS
467 && !allow_ntsec
&& allow_ntea
)
468 set_file_attribute (has_acls (), get_win32_name (), mode
);
471 set_flags (flags
, pc
? pc
->binmode () : 0);
476 syscall_printf ("%d = fhandler_base::open (%s, %p)", res
, get_win32_name (),
482 open buffer in binary mode? Just do the read.
484 open buffer in text mode? Scan buffer for control zs and handle
485 the first one found. Then scan buffer, converting every \r\n into
486 an \n. If last char is an \r, look ahead one more char, if \n then
487 modify \r, if not, remember char.
490 fhandler_base::read (void *in_ptr
, size_t in_len
)
492 int len
= (int) in_len
;
493 char *ptr
= (char *) in_ptr
;
496 int copied_chars
= 0;
499 if ((c
= get_readahead ()) < 0)
503 ptr
[copied_chars
++] = (unsigned char) (c
& 0xff);
507 if (copied_chars
&& is_slow ())
512 int readlen
= raw_read (ptr
+ copied_chars
, len
);
513 if (copied_chars
== 0)
514 copied_chars
= readlen
; /* Propagate error or EOF */
515 else if (readlen
> 0) /* FIXME: should flag EOF for next read */
516 copied_chars
+= readlen
;
519 if (copied_chars
<= 0)
523 debug_printf ("returning %d chars, binary mode", copied_chars
);
529 /* Scan buffer for a control-z and shorten the buffer to that length */
531 ctrlzpos
= (char *) memchr ((char *) ptr
, 0x1a, copied_chars
);
534 lseek ((ctrlzpos
- ((char *) ptr
+ copied_chars
)), SEEK_CUR
);
535 copied_chars
= ctrlzpos
- (char *) ptr
;
538 if (copied_chars
== 0)
540 debug_printf ("returning 0 chars, text mode, CTRL-Z found");
545 /* Scan buffer and turn \r\n into \n */
546 register char *src
= (char *) ptr
;
547 register char *dst
= (char *) ptr
;
548 register char *end
= src
+ copied_chars
- 1;
550 /* Read up to the last but one char - the last char needs special handling */
554 if (*dst
!= '\r' || *src
!= '\n')
559 /* if last char is a '\r' then read one more to see if we should
560 translate this one too */
564 len
= raw_read (&c1
, 1);
570 set_readahead_valid (1, c1
);
574 copied_chars
= dst
- (char *) ptr
;
579 char buf
[16 * 6 + 1];
582 for (int i
= 0; i
< copied_chars
&& i
< 16; ++i
)
584 unsigned char c
= ((unsigned char *) ptr
)[i
];
585 /* >= 33 so space prints in hex */
586 __small_sprintf (p
, c
>= 33 && c
<= 127 ? " %c" : " %p", c
);
589 debug_printf ("read %d bytes (%s%s)", copied_chars
, buf
,
590 copied_chars
> 16 ? " ..." : "");
594 debug_printf ("returning %d chars, text mode", copied_chars
);
599 fhandler_base::write (const void *ptr
, size_t len
)
604 SetFilePointer (get_handle (), 0, 0, FILE_END
);
605 else if (wincap
.has_lseek_bug () && get_check_win95_lseek_bug ())
607 /* Note: this bug doesn't happen on NT4, even though the documentation
608 for WriteFile() says that it *may* happen on any OS. */
609 int actual_length
, current_position
;
610 set_check_win95_lseek_bug (0); /* don't do it again */
611 actual_length
= GetFileSize (get_handle (), NULL
);
612 current_position
= SetFilePointer (get_handle (), 0, 0, FILE_CURRENT
);
613 if (current_position
> actual_length
)
615 /* Oops, this is the bug case - Win95 uses whatever is on the disk
616 instead of some known (safe) value, so we must seek back and
617 fill in the gap with zeros. - DJ */
619 int number_of_zeros_to_write
= current_position
- actual_length
;
620 memset (zeros
, 0, 512);
621 SetFilePointer (get_handle (), 0, 0, FILE_END
);
622 while (number_of_zeros_to_write
> 0)
624 DWORD zeros_this_time
= (number_of_zeros_to_write
> 512
625 ? 512 : number_of_zeros_to_write
);
627 if (!WriteFile (get_handle (), zeros
, zeros_this_time
, &written
,
631 if (get_errno () == EPIPE
)
633 /* This might fail, but it's the best we can hope for */
634 SetFilePointer (get_handle (), current_position
, 0, FILE_BEGIN
);
638 if (written
< zeros_this_time
) /* just in case */
641 /* This might fail, but it's the best we can hope for */
642 SetFilePointer (get_handle (), current_position
, 0, FILE_BEGIN
);
645 number_of_zeros_to_write
-= written
;
652 debug_printf ("binary write");
653 res
= raw_write (ptr
, len
);
657 debug_printf ("text write");
658 /* This is the Microsoft/DJGPP way. Still not ideal, but it's
660 Modified slightly by CGF 2000-10-07 */
662 int left_in_data
= len
;
663 char *data
= (char *)ptr
;
666 while (left_in_data
> 0)
668 char buf
[CHUNK_SIZE
+ 1], *buf_ptr
= buf
;
669 int left_in_buf
= CHUNK_SIZE
;
671 while (left_in_buf
> 0 && left_in_data
> 0)
682 if (left_in_data
> 0 && ch
== '\r' && *data
== '\n')
684 *buf_ptr
++ = *data
++;
690 /* We've got a buffer-full, or we're out of data. Write it out */
692 int want
= buf_ptr
- buf
;
693 if ((nbytes
= raw_write (buf
, want
)) == want
)
695 /* Keep track of how much written not counting additional \r's */
696 res
= data
- (char *)ptr
;
701 res
= -1; /* Error */
703 res
+= nbytes
; /* Partial write. Return total bytes written. */
704 break; /* All done */
708 debug_printf ("%d = write (%p, %d)", res
, ptr
, len
);
713 fhandler_base::readv (const struct iovec
*const iov
, const int iovcnt
,
717 assert (iovcnt
>= 1);
720 return read (iov
->iov_base
, iov
->iov_len
);
722 if (tot
== -1) // i.e. if not pre-calculated by the caller.
725 const struct iovec
*iovptr
= iov
+ iovcnt
;
729 tot
+= iovptr
->iov_len
;
731 while (iovptr
!= iov
);
739 char *buf
= (char *) alloca (tot
);
747 const ssize_t res
= read (buf
, tot
);
749 const struct iovec
*iovptr
= iov
;
754 const int frag
= min (nbytes
, (ssize_t
) iovptr
->iov_len
);
755 memcpy (iovptr
->iov_base
, buf
, frag
);
765 fhandler_base::writev (const struct iovec
*const iov
, const int iovcnt
,
769 assert (iovcnt
>= 1);
772 return write (iov
->iov_base
, iov
->iov_len
);
774 if (tot
== -1) // i.e. if not pre-calculated by the caller.
777 const struct iovec
*iovptr
= iov
+ iovcnt
;
781 tot
+= iovptr
->iov_len
;
783 while (iovptr
!= iov
);
791 char *const buf
= (char *) alloca (tot
);
800 const struct iovec
*iovptr
= iov
;
805 const int frag
= min (nbytes
, (ssize_t
) iovptr
->iov_len
);
806 memcpy (bufptr
, iovptr
->iov_base
, frag
);
812 return write (buf
, tot
);
816 fhandler_base::lseek (__off64_t offset
, int whence
)
820 /* 9x/Me doesn't support 64bit offsets. We trap that here and return
821 EINVAL. It doesn't make sense to simulate bigger offsets by a
822 SetFilePointer sequence since FAT and FAT32 don't support file
823 size >= 4GB anyway. */
824 if (!wincap
.has_64bit_file_access ()
825 && (offset
< LONG_MIN
|| offset
> LONG_MAX
))
827 debug_printf ("Win9x, offset not 32 bit.");
829 return (__off64_t
)-1;
832 /* Seeks on text files is tough, we rewind and read till we get to the
835 if (whence
!= SEEK_CUR
|| offset
!= 0)
837 if (whence
== SEEK_CUR
)
838 offset
-= ralen
- raixget
;
839 set_readahead_valid (0);
842 debug_printf ("lseek (%s, %D, %d)", unix_path_name
, offset
, whence
);
844 DWORD win32_whence
= whence
== SEEK_SET
? FILE_BEGIN
845 : (whence
== SEEK_CUR
? FILE_CURRENT
: FILE_END
);
847 LONG off_low
= offset
& 0xffffffff;
848 LONG
*poff_high
, off_high
;
849 if (!wincap
.has_64bit_file_access ())
853 off_high
= offset
>> 32;
854 poff_high
= &off_high
;
857 debug_printf ("setting file pointer to %u (high), %u (low)", off_high
, off_low
);
858 res
= SetFilePointer (get_handle (), off_low
, poff_high
, win32_whence
);
859 if (res
== INVALID_SET_FILE_POINTER
&& GetLastError ())
865 /* When next we write(), we will check to see if *this* seek went beyond
866 the end of the file, and back-seek and fill with zeros if so - DJ */
867 set_check_win95_lseek_bug ();
869 /* If this was a SEEK_CUR with offset 0, we still might have
870 readahead that we have to take into account when calculating
871 the actual position for the application. */
872 if (whence
== SEEK_CUR
)
873 res
-= ralen
- raixget
;
880 fhandler_base::close ()
884 syscall_printf ("closing '%s' handle %p", get_name (), get_handle ());
885 if (get_nohandle () || CloseHandle (get_handle ()))
889 paranoid_printf ("CloseHandle (%d <%s>) failed", get_handle (),
898 fhandler_base::ioctl (unsigned int cmd
, void *buf
)
901 syscall_printf ("ioctl (FIONBIO, %p)", buf
);
903 syscall_printf ("ioctl (%x, %p)", cmd
, buf
);
910 fhandler_base::lock (int, struct flock
*)
916 extern "C" char * __stdcall
917 rootdir (char *full_path
)
921 * \\server\share... -> \\server\share\
922 * else current drive.
924 char *root
= full_path
;
926 if (full_path
[1] == ':')
927 strcpy (full_path
+ 2, "\\");
928 else if (full_path
[0] == '\\' && full_path
[1] == '\\')
930 char *cp
= full_path
+ 2;
931 while (*cp
&& *cp
!= '\\')
939 while (*cp
&& *cp
!= '\\')
950 fhandler_base::fstat (struct __stat64
*buf
, path_conv
*)
952 debug_printf ("here");
953 switch (get_device ())
956 buf
->st_mode
= S_IFIFO
| STD_RBITS
| STD_WBITS
| S_IWGRP
| S_IWOTH
;
959 buf
->st_mode
= S_IFIFO
| STD_WBITS
| S_IWGRP
| S_IWOTH
;
962 buf
->st_mode
= S_IFIFO
| STD_RBITS
;
965 buf
->st_mode
= S_IFBLK
| STD_RBITS
| STD_WBITS
| S_IWGRP
| S_IWOTH
;
968 buf
->st_mode
= S_IFCHR
| STD_RBITS
| STD_WBITS
| S_IWGRP
| S_IWOTH
;
973 buf
->st_blksize
= S_BLKSIZE
;
974 time_as_timestruc_t (&buf
->st_ctim
);
975 buf
->st_atim
= buf
->st_mtim
= buf
->st_ctim
;
980 fhandler_base::init (HANDLE f
, DWORD a
, mode_t bin
)
984 a
&= GENERIC_READ
| GENERIC_WRITE
;
986 if (a
== GENERIC_READ
)
988 else if (a
== GENERIC_WRITE
)
990 else if (a
== (GENERIC_READ
| GENERIC_WRITE
))
992 set_flags (flags
| bin
);
994 debug_printf ("created new fhandler_base for handle %p, bin %d", f
, get_r_binary ());
998 fhandler_base::dump (void)
1000 paranoid_printf ("here");
1004 fhandler_base::dup (fhandler_base
*child
)
1006 debug_printf ("in fhandler_base dup");
1009 if (!get_nohandle ())
1011 if (!DuplicateHandle (hMainProc
, get_handle (), hMainProc
, &nh
, 0, TRUE
,
1012 DUPLICATE_SAME_ACCESS
))
1014 system_printf ("dup(%s) failed, handle %x, %E",
1015 get_name (), get_handle ());
1020 child
->set_io_handle (nh
);
1025 int fhandler_base::fcntl (int cmd
, void *arg
)
1032 res
= get_close_on_exec () ? FD_CLOEXEC
: 0;
1035 set_close_on_exec ((int) arg
);
1040 debug_printf ("GETFL: %d", res
);
1045 * Only O_APPEND, O_ASYNC and O_NONBLOCK/O_NDELAY are allowed.
1046 * Each other flag will be ignored.
1047 * Since O_ASYNC isn't defined in fcntl.h it's currently
1050 const int allowed_flags
= O_APPEND
| O_NONBLOCK_MASK
;
1051 int new_flags
= (int) arg
& allowed_flags
;
1052 /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
1053 Set only the flag that has been passed in. If both are set, just
1054 record O_NONBLOCK. */
1055 if ((new_flags
& OLD_O_NDELAY
) && (new_flags
& O_NONBLOCK
))
1056 new_flags
= O_NONBLOCK
;
1057 set_flags ((get_flags () & ~allowed_flags
) | new_flags
);
1064 res
= lock (cmd
, (struct flock
*) arg
);
1074 /* Base terminal handlers. These just return errors. */
1077 fhandler_base::tcflush (int)
1084 fhandler_base::tcsendbreak (int)
1091 fhandler_base::tcdrain (void)
1098 fhandler_base::tcflow (int)
1105 fhandler_base::tcsetattr (int, const struct termios
*)
1112 fhandler_base::tcgetattr (struct termios
*)
1119 fhandler_base::tcsetpgrp (const pid_t
)
1126 fhandler_base::tcgetpgrp (void)
1133 fhandler_base::operator delete (void *p
)
1139 /* Normal I/O constructor */
1140 fhandler_base::fhandler_base (DWORD devtype
, int unit
):
1151 unix_path_name (NULL
),
1152 win32_path_name (NULL
),
1157 /* Normal I/O destructor */
1158 fhandler_base::~fhandler_base (void)
1160 if (unix_path_name
!= NULL
)
1161 cfree ((void *) unix_path_name
);
1162 if (win32_path_name
!= NULL
)
1163 cfree ((void *) win32_path_name
);
1166 unix_path_name
= win32_path_name
= NULL
;
1169 /**********************************************************************/
1172 fhandler_dev_null::fhandler_dev_null () :
1173 fhandler_base (FH_NULL
)
1178 fhandler_dev_null::dump (void)
1180 paranoid_printf ("here");
1184 fhandler_base::set_inheritance (HANDLE
&h
, int not_inheriting
)
1186 #ifdef DEBUGGING_AND_FDS_PROTECTED
1189 /* Note that we could use SetHandleInformation here but it is not available
1190 on all platforms. Test cases seem to indicate that using DuplicateHandle
1191 in this fashion does not actually close the original handle, which is
1192 what we want. If this changes in the future, we may be forced to use
1193 SetHandleInformation on newer OS's */
1194 if (!DuplicateHandle (hMainProc
, h
, hMainProc
, &h
, 0, !not_inheriting
,
1195 DUPLICATE_SAME_ACCESS
| DUPLICATE_CLOSE_SOURCE
))
1196 debug_printf ("DuplicateHandle failed, %E");
1197 #ifdef DEBUGGING_AND_FDS_PROTECTED
1199 setclexec (oh
, h
, not_inheriting
);
1204 fhandler_base::fork_fixup (HANDLE parent
, HANDLE
&h
, const char *name
)
1206 if (/* !is_socket () && */ !get_close_on_exec ())
1207 debug_printf ("handle %p already opened", h
);
1208 else if (!DuplicateHandle (parent
, h
, hMainProc
, &h
, 0, !get_close_on_exec (),
1209 DUPLICATE_SAME_ACCESS
))
1210 system_printf ("%s - %E, handle %s<%p>", get_name (), name
, h
);
1211 #ifdef DEBUGGING_AND_FDS_PROTECTED
1212 else if (get_close_on_exec ())
1213 ProtectHandle (h
); /* would have to be fancier than this */
1215 /* ProtectHandleINH (h) */; /* Should already be protected */
1220 fhandler_base::set_close_on_exec (int val
)
1222 if (!get_nohandle ())
1223 set_inheritance (io_handle
, val
);
1224 set_close_on_exec_flag (val
);
1225 debug_printf ("set close_on_exec for %s to %d", get_name (), val
);
1229 fhandler_base::fixup_after_fork (HANDLE parent
)
1231 debug_printf ("inheriting '%s' from parent", get_name ());
1232 if (!get_nohandle ())
1233 fork_fixup (parent
, io_handle
, "io_handle");
1237 fhandler_base::is_nonblocking ()
1239 return (openflags
& O_NONBLOCK_MASK
) != 0;
1243 fhandler_base::set_nonblocking (int yes
)
1245 int current
= openflags
& O_NONBLOCK_MASK
;
1246 int new_flags
= yes
? (!current
? O_NONBLOCK
: current
) : 0;
1247 openflags
= (openflags
& ~O_NONBLOCK_MASK
) | new_flags
;
1251 fhandler_base::opendir (path_conv
&)
1253 set_errno (ENOTDIR
);
1258 fhandler_base::readdir (DIR *)
1260 set_errno (ENOTDIR
);
1265 fhandler_base::telldir (DIR *)
1267 set_errno (ENOTDIR
);
1272 fhandler_base::seekdir (DIR *, __off64_t
)
1274 set_errno (ENOTDIR
);
1279 fhandler_base::rewinddir (DIR *)
1281 set_errno (ENOTDIR
);
1286 fhandler_base::closedir (DIR *)
1288 set_errno (ENOTDIR
);