1 /* base.cc. Base functions, inherited by all fhandlers.
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
13 #include <cygwin/acl.h>
14 #include <sys/param.h>
16 #include "perprocess.h"
18 #include "cygwin/version.h"
29 #include "shared_info.h"
30 #include <asm/socket.h>
33 static const int CHUNK_SIZE
= 1024; /* Used for crlf conversions */
35 struct __cygwin_perfile
*perfile_table
;
38 fhandler_base::puts_readahead (const char *s
, size_t len
)
41 while ((len
== (size_t) -1 ? *s
: len
--)
42 && (success
= put_readahead (*s
++) > 0))
48 fhandler_base::put_readahead (char value
)
51 if (raixput () < rabuflen ())
53 else if ((newrabuf
= (char *) realloc (rabuf (), rabuflen () += 32)))
58 rabuf ()[raixput ()++] = value
;
64 fhandler_base::get_readahead ()
67 if (raixget () < ralen ())
68 chret
= ((unsigned char) rabuf ()[raixget ()++]) & 0xff;
69 /* FIXME - not thread safe */
70 if (raixget () >= ralen ())
71 raixget () = raixput () = ralen () = 0;
76 fhandler_base::peek_readahead (int queryput
)
79 if (!queryput
&& raixget () < ralen ())
80 chret
= ((unsigned char) rabuf ()[raixget ()]) & 0xff;
81 else if (queryput
&& raixput () > 0)
82 chret
= ((unsigned char) rabuf ()[raixput () - 1]) & 0xff;
87 fhandler_base::set_readahead_valid (int val
, int ch
)
90 ralen () = raixget () = raixput () = 0;
96 fhandler_base::get_readahead_into_buffer (char *buf
, size_t buflen
)
102 if ((ch
= get_readahead ()) < 0)
106 buf
[copied_chars
++] = (unsigned char)(ch
& 0xff);
113 /* Record the file name. and name hash */
115 fhandler_base::set_name (path_conv
&in_pc
)
120 char *fhandler_base::get_proc_fd_name (char *buf
)
123 FILE_STANDARD_INFORMATION fsi
;
125 /* If the file had been opened with O_TMPFILE, don't expose the filename. */
126 if ((get_flags () & O_TMPFILE
)
127 || (get_device () == FH_FS
128 && NT_SUCCESS (NtQueryInformationFile (get_handle (), &io
,
130 FileStandardInformation
))
131 && fsi
.DeletePending
))
133 stpcpy (stpcpy (buf
, get_name ()), " (deleted)");
137 return strcpy (buf
, get_name ());
139 return strcpy (buf
, dev ().name ());
140 return strcpy (buf
, "");
143 /* Detect if we are sitting at EOF for conditions where Windows
144 returns an error but UNIX doesn't. */
149 FILE_POSITION_INFORMATION fpi
;
150 FILE_STANDARD_INFORMATION fsi
;
152 if (NT_SUCCESS (NtQueryInformationFile (h
, &io
, &fsi
, sizeof fsi
,
153 FileStandardInformation
))
154 && NT_SUCCESS (NtQueryInformationFile (h
, &io
, &fpi
, sizeof fpi
,
155 FilePositionInformation
))
156 && fsi
.EndOfFile
.QuadPart
== fpi
.CurrentByteOffset
.QuadPart
)
162 fhandler_base::set_flags (int flags
, int supplied_bin
)
166 debug_printf ("flags %y, supplied_bin %y", flags
, supplied_bin
);
167 if ((bin
= flags
& (O_BINARY
| O_TEXT
)))
168 debug_printf ("O_TEXT/O_BINARY set in flags %y", bin
);
169 else if (rbinset () && wbinset ())
170 bin
= rbinary () ? O_BINARY
: O_TEXT
; // FIXME: Not quite right
171 else if ((fmode
= get_default_fmode (flags
)) & O_BINARY
)
173 else if (fmode
& O_TEXT
)
175 else if (supplied_bin
)
178 bin
= wbinary () || rbinary () ? O_BINARY
: O_TEXT
;
180 openflags
= flags
| bin
;
183 rbinary (bin
? true : false);
184 wbinary (bin
? true : false);
185 syscall_printf ("filemode set to %s", bin
? "binary" : "text");
188 /* Normal file i/o handlers. */
190 /* Cover function to ReadFile to achieve (as much as possible) Posix style
191 semantics and use of errno. */
193 fhandler_base::raw_read (void *ptr
, size_t& len
)
197 int try_noreserve
= 1;
200 status
= NtReadFile (get_handle (), NULL
, NULL
, NULL
, &io
, ptr
, len
,
202 if (NT_SUCCESS (status
))
203 len
= io
.Information
;
206 /* Some errors are not really errors. Detect such cases here. */
209 case STATUS_END_OF_FILE
:
210 case STATUS_PIPE_BROKEN
:
211 /* This is really EOF. */
214 case STATUS_MORE_ENTRIES
:
215 case STATUS_BUFFER_OVERFLOW
:
216 /* `io.Information' is supposedly valid. */
217 len
= io
.Information
;
219 case STATUS_ACCESS_VIOLATION
:
220 if (is_at_eof (get_handle ()))
228 switch (mmap_is_attached_or_noreserve (ptr
, len
))
230 case MMAP_NORESERVE_COMMITED
:
232 case MMAP_RAISE_SIGBUS
:
239 case STATUS_INVALID_DEVICE_REQUEST
:
240 case STATUS_INVALID_PARAMETER
:
241 case STATUS_INVALID_HANDLE
:
250 __seterrno_from_nt_status (status
);
257 /* Cover function to WriteFile to provide Posix interface and semantics
258 (as much as possible). */
260 fhandler_base::raw_write (const void *ptr
, size_t len
)
264 static _RDATA LARGE_INTEGER off_current
=
265 { QuadPart
:FILE_USE_FILE_POINTER_POSITION
};
266 static _RDATA LARGE_INTEGER off_append
=
267 { QuadPart
:FILE_WRITE_TO_END_OF_FILE
};
269 status
= NtWriteFile (get_output_handle (), NULL
, NULL
, NULL
, &io
,
271 (get_flags () & O_APPEND
) ? &off_append
: &off_current
,
273 if (!NT_SUCCESS (status
))
275 __seterrno_from_nt_status (status
);
276 if (get_errno () == EPIPE
)
280 return io
.Information
;
284 fhandler_base::get_default_fmode (int flags
)
289 size_t nlen
= strlen (get_name ());
290 unsigned accflags
= (flags
& O_ACCMODE
);
291 for (__cygwin_perfile
*pf
= perfile_table
; pf
->name
; pf
++)
292 if (!*pf
->name
&& (pf
->flags
& O_ACCMODE
) == accflags
)
294 fmode
= pf
->flags
& ~O_ACCMODE
;
299 size_t pflen
= strlen (pf
->name
);
300 const char *stem
= get_name () + nlen
- pflen
;
301 if (pflen
> nlen
|| (stem
!= get_name () && !isdirsep (stem
[-1])))
303 else if ((pf
->flags
& O_ACCMODE
) == accflags
304 && pathmatch (stem
, pf
->name
, !!pc
.objcaseinsensitive ()))
306 fmode
= pf
->flags
& ~O_ACCMODE
;
315 fhandler_base::device_access_denied (int flags
)
324 if (flags
& (O_WRONLY
| O_APPEND
))
329 return fhaccess (mode
, true);
333 fhandler_base::fhaccess (int flags
, bool effective
)
338 set_errno (error ());
348 if (!(flags
& (R_OK
| W_OK
| X_OK
)))
351 if (is_fs_special ())
353 else if (has_attribute (FILE_ATTRIBUTE_READONLY
) && (flags
& W_OK
)
356 else if (has_acls ())
358 res
= check_file_access (pc
, flags
, effective
);
361 else if (get_device () == FH_REGISTRY
&& open (O_RDONLY
, 0) && get_handle ())
363 res
= check_registry_access (get_handle (), flags
, effective
);
374 if (st
.st_uid
== (effective
? myself
->uid
: cygheap
->user
.real_uid
))
376 if (!(st
.st_mode
& S_IRUSR
))
379 else if (st
.st_gid
== (effective
? myself
->gid
: cygheap
->user
.real_gid
))
381 if (!(st
.st_mode
& S_IRGRP
))
384 else if (!(st
.st_mode
& S_IROTH
))
390 if (st
.st_uid
== (effective
? myself
->uid
: cygheap
->user
.real_uid
))
392 if (!(st
.st_mode
& S_IWUSR
))
395 else if (st
.st_gid
== (effective
? myself
->gid
: cygheap
->user
.real_gid
))
397 if (!(st
.st_mode
& S_IWGRP
))
400 else if (!(st
.st_mode
& S_IWOTH
))
406 if (st
.st_uid
== (effective
? myself
->uid
: cygheap
->user
.real_uid
))
408 if (!(st
.st_mode
& S_IXUSR
))
411 else if (st
.st_gid
== (effective
? myself
->gid
: cygheap
->user
.real_gid
))
413 if (!(st
.st_mode
& S_IXGRP
))
416 else if (!(st
.st_mode
& S_IXOTH
))
426 if (!res
&& (flags
& W_OK
) && get_device () == FH_FS
427 && (pc
.fs_flags () & FILE_READ_ONLY_VOLUME
))
432 debug_printf ("returning %d", res
);
437 fhandler_base::open_with_arch (int flags
, mode_t mode
)
440 if (!(res
= (archetype
&& archetype
->io_handle
)
441 || open (flags
, mode
& 07777)))
443 if (archetype
&& archetype
->usecount
== 0)
444 cygheap
->fdtab
.delete_archetype (archetype
);
448 if (!archetype
->get_handle ())
450 archetype
->copy_from (this);
451 archetype_usecount (1);
452 archetype
->archetype
= NULL
;
458 /* Preserve any name (like /dev/tty) derived from build_fh_pc. */
463 name
= (char *) alloca (strlen (get_name ()) + 1);
464 strcpy (name
, get_name ());
466 fhandler_base
*arch
= archetype
;
467 copy_from (archetype
);
471 archetype_usecount (1);
474 if (!open_setup (flags
))
475 api_fatal ("open_setup failed, %E");
478 close_on_exec (flags
& O_CLOEXEC
);
479 /* A unique ID is necessary to recognize fhandler entries which are
480 duplicated by dup(2) or fork(2). This is used in BSD flock calls
481 to identify the descriptor. Skip nohandle fhandlers since advisory
482 locking is unusable for those anyway. */
488 /* Open a fake handle to \\Device\\Null. This is a helper function for
489 fhandlers which just need some handle to keep track of BSD flock locks. */
491 fhandler_base::open_null (int flags
)
495 OBJECT_ATTRIBUTES attr
;
499 InitializeObjectAttributes (&attr
, &ro_u_null
, OBJ_CASE_INSENSITIVE
|
500 ((flags
& O_CLOEXEC
) ? 0 : OBJ_INHERIT
),
502 status
= NtCreateFile (&fh
, GENERIC_READ
| SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
503 FILE_SHARE_READ
| FILE_SHARE_WRITE
, FILE_OPEN
,
504 FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
505 if (!NT_SUCCESS (status
))
507 __seterrno_from_nt_status (status
);
511 set_flags (flags
, pc
.binmode ());
515 debug_printf ("%y = NtCreateFile (%p, ... %S ...)", status
, fh
, &ro_u_null
);
516 syscall_printf ("%d = fhandler_base::open_null (%y)", res
, flags
);
520 /* Open system call handler function. */
522 fhandler_base::open (int flags
, mode_t mode
)
526 ULONG file_attributes
= 0;
527 ULONG shared
= (get_major () == DEV_TAPE_MAJOR
? 0 : FILE_SHARE_VALID_FLAGS
);
528 ULONG create_disposition
;
529 OBJECT_ATTRIBUTES attr
;
532 PFILE_FULL_EA_INFORMATION p
= NULL
;
535 syscall_printf ("(%S, %y)%s", pc
.get_nt_native_path (), flags
,
536 get_handle () ? " by handle" : "");
539 query_open (query_read_attributes
);
541 /* Allow to reopen from handle. This is utilized by
542 open ("/proc/PID/fd/DESCRIPTOR", ...); */
545 pc
.init_reopen_attr (attr
, get_handle ());
546 if (!(flags
& O_CLOEXEC
))
547 attr
.Attributes
|= OBJ_INHERIT
;
548 if (pc
.has_buggy_reopen ())
549 debug_printf ("Reopen by handle requested but FS doesn't support it");
552 pc
.get_object_attr (attr
, *sec_none_cloexec (flags
));
554 options
= FILE_OPEN_FOR_BACKUP_INTENT
;
555 switch (query_open ())
557 case query_read_control
:
558 access
= READ_CONTROL
;
560 case query_read_attributes
:
561 access
= READ_CONTROL
| FILE_READ_ATTRIBUTES
;
563 case query_write_control
:
564 access
= READ_CONTROL
| WRITE_OWNER
| WRITE_DAC
| FILE_WRITE_ATTRIBUTES
;
566 case query_write_dac
:
567 access
= READ_CONTROL
| WRITE_DAC
| FILE_WRITE_ATTRIBUTES
;
569 case query_write_attributes
:
570 access
= READ_CONTROL
| FILE_WRITE_ATTRIBUTES
;
573 switch (flags
& O_ACCMODE
)
576 access
= GENERIC_READ
;
579 access
= GENERIC_WRITE
| READ_CONTROL
| FILE_READ_ATTRIBUTES
;
582 access
= GENERIC_READ
| GENERIC_WRITE
;
586 options
|= FILE_WRITE_THROUGH
;
587 if (flags
& O_DIRECT
)
588 options
|= FILE_NO_INTERMEDIATE_BUFFERING
;
589 if (get_major () != DEV_SERIAL_MAJOR
&& get_major () != DEV_TAPE_MAJOR
)
591 options
|= FILE_SYNCHRONOUS_IO_NONALERT
;
592 access
|= SYNCHRONIZE
;
597 /* Don't use the FILE_OVERWRITE{_IF} flags here. See below for an
598 explanation, why that's not such a good idea. */
599 if (((flags
& O_EXCL
) && (flags
& O_CREAT
)) || (flags
& O_TMPFILE
))
600 create_disposition
= FILE_CREATE
;
602 create_disposition
= (flags
& O_CREAT
) ? FILE_OPEN_IF
: FILE_OPEN
;
604 if (get_device () == FH_FS
605 #ifdef __WITH_AF_UNIX
606 || get_device () == FH_UNIX
610 /* Add the reparse point flag to known reparse points, otherwise we
611 open the target, not the reparse point. This would break lstat. */
612 if (pc
.is_known_reparse_point ())
613 options
|= FILE_OPEN_REPARSE_POINT
;
616 /* If the file is a FIFO, open has been called for an operation on the file
617 constituting the FIFO, e. g., chmod or statvfs. Handle it like a normal
618 file. Eespecially the access flags have to be set correctly. */
619 if (get_device () == FH_FS
|| get_device () == FH_FIFO
)
621 /* O_TMPFILE files are created with delete-on-close semantics, as well
622 as with FILE_ATTRIBUTE_TEMPORARY. The latter speeds up file access,
623 because the OS tries to keep the file in memory as much as possible.
624 In conjunction with FILE_DELETE_ON_CLOSE, ideally the OS never has
625 to write to the disk at all.
626 Note that O_TMPFILE_FILE_ATTRS also sets the DOS HIDDEN attribute
627 to help telling Cygwin O_TMPFILE files apart from other files
628 accidentally setting FILE_ATTRIBUTE_TEMPORARY. */
629 if (flags
& O_TMPFILE
)
632 file_attributes
|= O_TMPFILE_FILE_ATTRS
;
633 options
|= FILE_DELETE_ON_CLOSE
;
638 /* Make sure we can read EAs of files on an NFS share. Also make
639 sure that we're going to act on the file itself, even if it's a
641 access
|= FILE_READ_EA
;
644 if (query_open () >= query_write_control
)
645 access
|= FILE_WRITE_EA
;
646 plen
= sizeof nfs_aol_ffei
;
647 p
= (PFILE_FULL_EA_INFORMATION
) &nfs_aol_ffei
;
651 if (flags
& (O_CREAT
| O_TMPFILE
))
653 file_attributes
|= FILE_ATTRIBUTE_NORMAL
;
657 /* When creating a file on an NFS share, we have to set the
658 file mode by writing a NFS fattr3 structure with the
659 correct mode bits set. */
660 access
|= FILE_WRITE_EA
;
661 plen
= sizeof (FILE_FULL_EA_INFORMATION
) + sizeof (NFS_V3_ATTR
)
663 p
= (PFILE_FULL_EA_INFORMATION
) alloca (plen
);
664 p
->NextEntryOffset
= 0;
666 p
->EaNameLength
= sizeof (NFS_V3_ATTR
) - 1;
667 p
->EaValueLength
= sizeof (fattr3
);
668 strcpy (p
->EaName
, NFS_V3_ATTR
);
669 fattr3
*nfs_attr
= (fattr3
*) (p
->EaName
670 + p
->EaNameLength
+ 1);
671 memset (nfs_attr
, 0, sizeof (fattr3
));
672 nfs_attr
->type
= NF3REG
;
673 nfs_attr
->mode
= (mode
& 07777) & ~cygheap
->umask
;
675 else if (!has_acls ()
676 && !(mode
& ~cygheap
->umask
& (S_IWUSR
| S_IWGRP
| S_IWOTH
)))
677 /* If mode has no write bits set, and ACLs are not used, we set
678 the DOS R/O attribute. */
679 file_attributes
|= FILE_ATTRIBUTE_READONLY
;
680 /* Never set the WRITE_DAC flag here. Calls to fstat may return
681 wrong st_ctime information after calls to fchmod, fchown, etc
682 because Windows only guarantees the update of metadata when
683 the handle is closed or flushed. However, flushing the file
684 on every fstat to enforce POSIXy stat behaviour is excessivly
685 slow, compared to an extra open/close to change the file's
686 security descriptor. */
690 status
= NtCreateFile (&fh
, access
, &attr
, &io
, NULL
, file_attributes
, shared
,
691 create_disposition
, options
, p
, plen
);
692 /* Pre-W10, we can't reopen a file by handle with delete disposition
693 set, so we have to lie our ass off. */
694 if (get_handle () && status
== STATUS_DELETE_PENDING
)
696 BOOL ret
= DuplicateHandle (GetCurrentProcess (), get_handle (),
697 GetCurrentProcess (), &fh
,
698 access
, !(flags
& O_CLOEXEC
), 0);
700 ret
= DuplicateHandle (GetCurrentProcess (), get_handle (),
701 GetCurrentProcess (), &fh
,
702 0, !(flags
& O_CLOEXEC
),
703 DUPLICATE_SAME_ACCESS
);
705 debug_printf ("DuplicateHandle after STATUS_DELETE_PENDING, %E");
707 status
= STATUS_SUCCESS
;
709 if (!NT_SUCCESS (status
))
711 /* Trying to create a directory should return EISDIR, not ENOENT. */
712 PUNICODE_STRING upath
= pc
.get_nt_native_path ();
713 if (status
== STATUS_OBJECT_NAME_INVALID
&& (flags
& O_CREAT
)
714 && upath
->Buffer
[upath
->Length
/ sizeof (WCHAR
) - 1] == '\\')
717 __seterrno_from_nt_status (status
);
722 if (io
.Information
== FILE_CREATED
)
724 /* Correct file attributes are needed for later use in, e.g. fchmod. */
725 FILE_BASIC_INFORMATION fbi
;
727 if (!NT_SUCCESS (NtQueryInformationFile (fh
, &io
, &fbi
, sizeof fbi
,
728 FileBasicInformation
)))
729 fbi
.FileAttributes
= file_attributes
| FILE_ATTRIBUTE_ARCHIVE
;
730 pc
.file_attributes (fbi
.FileAttributes
);
732 /* Always create files using a NULL SD. Create correct permission bits
733 afterwards, maintaining the owner and group information just like
734 chmod. This is done for two reasons.
736 On Windows filesystems we need to create the file with default
737 permissions to allow inheriting ACEs. When providing an explicit DACL
738 in calls to [Nt]CreateFile, the created file will not inherit default
739 permissions from the parent object. This breaks not only Windows
740 inheritance, but also POSIX ACL inheritance.
742 Another reason to do this are remote shares. Files on a remote share
743 are created as the user used for authentication. In a domain that's
744 usually the user you're logged in as. Outside of a domain you're
745 authenticating using a local user account on the sharing machine.
746 If the SIDs of the client machine are used, that's entirely unexpected
747 behaviour. Doing it like we do here creates the expected SD in a
748 domain as well as on standalone servers. This is the result of a
749 discussion on the samba-technical list, starting at
750 http://lists.samba.org/archive/samba-technical/2008-July/060247.html */
752 set_created_file_access (fh
, pc
, mode
);
755 /* If you O_TRUNC a file on Linux, the data is truncated, but the EAs are
756 preserved. If you open a file on Windows with FILE_OVERWRITE{_IF} or
757 FILE_SUPERSEDE, all streams are truncated, including the EAs. So we don't
758 use the FILE_OVERWRITE{_IF} flags, but instead just open the file and set
759 the size of the data stream explicitely to 0. Apart from being more Linux
760 compatible, this implementation has the pleasant side-effect to be more
761 than 5% faster than using FILE_OVERWRITE{_IF} (tested on W7 32 bit). */
762 if ((flags
& O_TRUNC
)
763 && (flags
& O_ACCMODE
) != O_RDONLY
764 && io
.Information
!= FILE_CREATED
765 && get_device () == FH_FS
)
767 FILE_END_OF_FILE_INFORMATION feofi
= { EndOfFile
:{ QuadPart
:0 } };
768 status
= NtSetInformationFile (fh
, &io
, &feofi
, sizeof feofi
,
769 FileEndOfFileInformation
);
770 /* In theory, truncating the file should never fail, since the opened
771 handle has FILE_WRITE_DATA permissions, which is all you need to
772 be allowed to truncate a file. Better safe than sorry. */
773 if (!NT_SUCCESS (status
))
775 __seterrno_from_nt_status (status
);
779 /* Drop sparseness */
780 if (pc
.file_attributes () & FILE_ATTRIBUTE_SPARSE_FILE
)
782 FILE_SET_SPARSE_BUFFER fssb
= { SetSparse
: FALSE
};
783 status
= NtFsControlFile (fh
, NULL
, NULL
, NULL
, &io
,
784 FSCTL_SET_SPARSE
, &fssb
, sizeof fssb
, NULL
, 0);
785 if (NT_SUCCESS (status
))
786 pc
.file_attributes (pc
.file_attributes () & ~FILE_ATTRIBUTE_SPARSE_FILE
);
791 set_flags (flags
, pc
.binmode ());
796 debug_printf ("%y = NtCreateFile "
797 "(%p, %y, %S, io, NULL, %y, %y, %y, %y, NULL, 0)",
798 status
, fh
, access
, pc
.get_nt_native_path (), file_attributes
,
799 shared
, create_disposition
, options
);
801 syscall_printf ("%d = fhandler_base::open(%S, %y)",
802 res
, pc
.get_nt_native_path (), flags
);
807 fhandler_base::fd_reopen (int, mode_t
)
809 /* This is implemented in fhandler_process only. */
814 fhandler_base::open_setup (int)
820 open buffer in binary mode? Just do the read.
822 open buffer in text mode? Scan buffer for control zs and handle
823 the first one found. Then scan buffer, converting every \r\n into
824 an \n. If last char is an \r, look ahead one more char, if \n then
825 modify \r, if not, remember char.
828 fhandler_base::read (void *in_ptr
, size_t& len
)
830 char *ptr
= (char *) in_ptr
;
831 ssize_t copied_chars
= get_readahead_into_buffer (ptr
, len
);
833 if (copied_chars
|| !len
)
835 len
= (size_t) copied_chars
;
841 if (rbinary () || (ssize_t
) len
<= 0)
844 /* Scan buffer and turn \r\n into \n */
845 char *src
, *dst
, *end
;
850 /* Read up to the last but one char - the last char needs special handling */
853 if (*src
== '\r' && src
[1] == '\n')
858 /* If not beyond end and last char is a '\r' then read one more
859 to see if we should translate this one too */
862 else if (*src
!= '\r')
868 raw_read (&c1
, c1len
);
875 set_readahead_valid (1, c1
);
880 len
= dst
- (char *) ptr
;
883 debug_printf ("returning %d, %s mode", len
, rbinary () ? "binary" : "text");
887 fhandler_base::write (const void *ptr
, size_t len
)
894 FILE_POSITION_INFORMATION fpi
;
895 FILE_STANDARD_INFORMATION fsi
;
897 did_lseek (false); /* don't do it again */
899 /* If the file system supports sparse files and the application is
900 writing after a long seek beyond EOF spanning more than one
901 sparsifiable chunk, convert the file to a sparse file. */
902 if (!(get_flags () & O_APPEND
)
903 && !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE
)
904 && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
905 &io
, &fsi
, sizeof fsi
,
906 FileStandardInformation
))
907 && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
908 &io
, &fpi
, sizeof fpi
,
909 FilePositionInformation
))
910 && span_sparse_chunk (fpi
.CurrentByteOffset
.QuadPart
,
911 fsi
.EndOfFile
.QuadPart
))
914 status
= NtFsControlFile (get_output_handle (), NULL
, NULL
, NULL
,
915 &io
, FSCTL_SET_SPARSE
, NULL
, 0, NULL
, 0);
916 if (NT_SUCCESS (status
))
917 pc
.file_attributes (pc
.file_attributes ()
918 | FILE_ATTRIBUTE_SPARSE_FILE
);
919 debug_printf ("%y = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
920 status
, pc
.get_nt_native_path ());
925 res
= raw_write (ptr
, len
);
928 debug_printf ("text write");
929 /* This is the Microsoft/DJGPP way. Still not ideal, but it's
931 Modified slightly by CGF 2000-10-07 */
933 int left_in_data
= len
;
934 char *data
= (char *)ptr
;
937 while (left_in_data
> 0)
939 char buf
[CHUNK_SIZE
+ 1], *buf_ptr
= buf
;
940 int left_in_buf
= CHUNK_SIZE
;
942 while (left_in_buf
> 0 && left_in_data
> 0)
953 if (left_in_data
> 0 && ch
== '\r' && *data
== '\n')
955 *buf_ptr
++ = *data
++;
961 /* We've got a buffer-full, or we're out of data. Write it out */
963 ptrdiff_t want
= buf_ptr
- buf
;
964 if ((nbytes
= raw_write (buf
, (size_t) want
)) == want
)
966 /* Keep track of how much written not counting additional \r's */
967 res
= data
- (char *)ptr
;
972 res
= -1; /* Error */
974 res
+= nbytes
; /* Partial write. Return total bytes written. */
975 break; /* All done */
983 fhandler_base::readv (const struct iovec
*const iov
, const int iovcnt
,
987 assert (iovcnt
>= 1);
993 read (iov
->iov_base
, len
);
997 if (tot
== -1) // i.e. if not pre-calculated by the caller.
1000 const struct iovec
*iovptr
= iov
+ iovcnt
;
1004 len
+= iovptr
->iov_len
;
1006 while (iovptr
!= iov
);
1012 char *buf
= (char *) malloc (len
);
1021 ssize_t nbytes
= (ssize_t
) len
;
1023 const struct iovec
*iovptr
= iov
;
1028 const int frag
= MIN (nbytes
, (ssize_t
) iovptr
->iov_len
);
1029 memcpy (iovptr
->iov_base
, p
, frag
);
1040 fhandler_base::writev (const struct iovec
*const iov
, const int iovcnt
,
1044 assert (iovcnt
>= 1);
1047 return write (iov
->iov_base
, iov
->iov_len
);
1049 if (tot
== -1) // i.e. if not pre-calculated by the caller.
1052 const struct iovec
*iovptr
= iov
+ iovcnt
;
1056 tot
+= iovptr
->iov_len
;
1058 while (iovptr
!= iov
);
1066 char *const buf
= (char *) malloc (tot
);
1075 const struct iovec
*iovptr
= iov
;
1080 const int frag
= MIN (nbytes
, (ssize_t
) iovptr
->iov_len
);
1081 memcpy (bufptr
, iovptr
->iov_base
, frag
);
1086 ssize_t ret
= write (buf
, tot
);
1092 fhandler_base::lseek (off_t offset
, int whence
)
1096 FILE_POSITION_INFORMATION fpi
;
1097 FILE_STANDARD_INFORMATION fsi
;
1099 /* Seeks on text files is tough, we rewind and read till we get to the
1102 if (whence
!= SEEK_CUR
|| offset
!= 0)
1104 if (whence
== SEEK_CUR
)
1105 offset
-= ralen () - raixget ();
1106 set_readahead_valid (0);
1112 fpi
.CurrentByteOffset
.QuadPart
= offset
;
1115 status
= NtQueryInformationFile (get_handle (), &io
, &fpi
, sizeof fpi
,
1116 FilePositionInformation
);
1117 if (!NT_SUCCESS (status
))
1119 __seterrno_from_nt_status (status
);
1122 fpi
.CurrentByteOffset
.QuadPart
+= offset
;
1125 status
= NtQueryInformationFile (get_handle (), &io
, &fsi
, sizeof fsi
,
1126 FileStandardInformation
);
1127 if (!NT_SUCCESS (status
))
1129 __seterrno_from_nt_status (status
);
1132 fpi
.CurrentByteOffset
.QuadPart
= fsi
.EndOfFile
.QuadPart
+ offset
;
1137 FILE_ALLOCATED_RANGE_BUFFER inp
, out
;
1139 status
= NtQueryInformationFile (get_handle (), &io
, &fsi
, sizeof fsi
,
1140 FileStandardInformation
);
1141 if (!NT_SUCCESS (status
))
1143 __seterrno_from_nt_status (status
);
1146 /* Per Linux man page, ENXIO if offset is beyond EOF */
1147 if (offset
> fsi
.EndOfFile
.QuadPart
)
1152 if (!has_attribute (FILE_ATTRIBUTE_SPARSE_FILE
))
1154 /* Default behaviour if sparse files are not supported:
1155 SEEK_DATA: seek to offset
1156 SEEK_HOLE: seek to EOF */
1157 fpi
.CurrentByteOffset
.QuadPart
= (whence
== SEEK_DATA
)
1159 : fsi
.EndOfFile
.QuadPart
;
1162 inp
.FileOffset
.QuadPart
= offset
;
1163 inp
.Length
.QuadPart
= fsi
.EndOfFile
.QuadPart
- offset
;
1164 /* Note that we only fetch a single region, so we expect the
1165 function to fail with STATUS_BUFFER_OVERFLOW. It still
1166 returns the data region containing offset, or the next
1167 region after offset, if offset is within a hole. */
1168 status
= NtFsControlFile (get_output_handle (), NULL
, NULL
, NULL
,
1169 &io
, FSCTL_QUERY_ALLOCATED_RANGES
,
1172 if (!NT_SUCCESS (status
) && status
!= STATUS_BUFFER_OVERFLOW
)
1174 /* On error, fall back to default behaviour, see above. */
1175 fpi
.CurrentByteOffset
.QuadPart
= (whence
== SEEK_DATA
)
1177 : fsi
.EndOfFile
.QuadPart
;
1180 if (io
.Information
== 0)
1182 /* No valid region, so offset is within a hole at EOF.
1184 SEEK_HOLE: seek to offset */
1185 if (whence
== SEEK_DATA
)
1190 fpi
.CurrentByteOffset
.QuadPart
= offset
;
1192 else if (out
.FileOffset
.QuadPart
== offset
)
1194 /* offset within valid data range? In that case, that region
1195 supposedly starts at offset, and the region length is corrected
1196 accordingly. That's quite helpful.
1197 SEEK_DATA: seek to offset
1198 SEEK_HOLE: seek to end of range */
1199 fpi
.CurrentByteOffset
.QuadPart
= offset
;
1200 if (whence
== SEEK_HOLE
)
1201 fpi
.CurrentByteOffset
.QuadPart
+= out
.Length
.QuadPart
;
1205 /* Is range beyond offset?
1206 SEEK_DATA: seek to start of range
1207 SEEK_HOLE: seek to offset */
1208 fpi
.CurrentByteOffset
.QuadPart
= (whence
== SEEK_DATA
)
1209 ? out
.FileOffset
.QuadPart
1214 default: /* Should never be reached */
1219 debug_printf ("setting file pointer to %U", fpi
.CurrentByteOffset
.QuadPart
);
1220 status
= NtSetInformationFile (get_handle (), &io
, &fpi
, sizeof fpi
,
1221 FilePositionInformation
);
1222 if (!NT_SUCCESS (status
))
1224 __seterrno_from_nt_status (status
);
1227 off_t res
= fpi
.CurrentByteOffset
.QuadPart
;
1229 /* When next we write(), we will check to see if *this* seek went beyond
1230 the end of the file and if so, potentially sparsify the file. */
1231 if (pc
.support_sparse ())
1234 /* If this was a SEEK_CUR with offset 0, we still might have
1235 readahead that we have to take into account when calculating
1236 the actual position for the application. */
1237 if (whence
== SEEK_CUR
)
1238 res
-= ralen () - raixget ();
1244 fhandler_base::pread (void *, size_t, off_t
, void *)
1251 fhandler_base::pwrite (void *, size_t, off_t
, void *)
1258 fhandler_base::close_with_arch ()
1264 /* This was the archetype itself. */
1267 debug_printf ("not closing passed in archetype %p, usecount %d", archetype
, usecount
);
1270 debug_printf ("closing passed in archetype %p, usecount %d", archetype
, usecount
);
1271 /* Set archetype temporarily so that it will eventually be deleted. */
1272 archetype
= fh
= this;
1274 else if (!archetype
)
1276 else if (archetype_usecount (-1) == 0)
1278 debug_printf ("closing archetype");
1283 debug_printf ("not closing archetype");
1291 cygheap
->fdtab
.delete_archetype (archetype
);
1298 fhandler_base::cleanup ()
1300 /* Delete all POSIX locks on the file. Delete all flock locks on the
1301 file if this is the last reference to this file. */
1303 del_my_locks (on_close
);
1307 fhandler_base::close ()
1311 syscall_printf ("closing '%s' handle %p", get_name (), get_handle ());
1312 if (nohandle () || CloseHandle (get_handle ()))
1316 paranoid_printf ("CloseHandle failed, %E");
1324 fhandler_base::ioctl (unsigned int cmd
, void *buf
)
1331 set_nonblocking (*(int *) buf
);
1345 syscall_printf ("%d = ioctl(%x, %p)", res
, cmd
, buf
);
1350 fhandler_base::fstat (struct stat
*buf
)
1352 if (is_fs_special ())
1353 return fstat_fs (buf
);
1355 switch (get_device ())
1358 buf
->st_mode
= S_IFIFO
| S_IRUSR
| S_IWUSR
;
1361 buf
->st_mode
= S_IFIFO
| S_IWUSR
;
1364 buf
->st_mode
= S_IFIFO
| S_IRUSR
;
1367 buf
->st_mode
= S_IFCHR
| STD_RBITS
| STD_WBITS
| S_IWGRP
| S_IWOTH
;
1371 buf
->st_uid
= geteuid ();
1372 buf
->st_gid
= getegid ();
1374 buf
->st_blksize
= PREFERRED_IO_BLKSIZE
;
1376 buf
->st_ctim
.tv_sec
= 1164931200L; /* Arbitrary value: 2006-12-01 */
1377 buf
->st_ctim
.tv_nsec
= 0L;
1378 buf
->st_birthtim
= buf
->st_ctim
;
1379 buf
->st_mtim
.tv_sec
= time (NULL
); /* Arbitrary value: current time,
1381 buf
->st_mtim
.tv_nsec
= 0L;
1382 buf
->st_atim
= buf
->st_mtim
;
1388 fhandler_base::fstatvfs (struct statvfs
*sfs
)
1390 /* If we hit this base implementation, it's some device in /dev.
1391 Just call statvfs on /dev for simplicity. */
1392 path_conv
pc ("/dev", PC_KEEP_HANDLE
);
1393 fhandler_disk_file
fh (pc
);
1394 return fh
.fstatvfs (sfs
);
1398 fhandler_base::init (HANDLE f
, DWORD a
, mode_t bin
)
1402 a
&= GENERIC_READ
| GENERIC_WRITE
;
1404 if (a
== GENERIC_READ
)
1406 else if (a
== GENERIC_WRITE
)
1408 else if (a
== (GENERIC_READ
| GENERIC_WRITE
))
1410 set_flags (flags
| bin
);
1412 debug_printf ("created new fhandler_base for handle %p, bin %d", f
, rbinary ());
1417 fhandler_base::dup (fhandler_base
*child
, int flags
)
1419 debug_printf ("in fhandler_base dup");
1422 if (!nohandle () && !archetype
)
1424 if (!DuplicateHandle (GetCurrentProcess (), get_handle (),
1425 GetCurrentProcess (), &nh
,
1426 0, !(flags
& O_CLOEXEC
), DUPLICATE_SAME_ACCESS
))
1428 debug_printf ("dup(%s) failed, handle %p, %E",
1429 get_name (), get_handle ());
1435 child
->set_handle (nh
);
1436 /* Just set to NULL, the struct is potentially still valid
1437 in the parent fhandler. */
1439 child
->getdents_dir (NULL
);
1443 int fhandler_base::fcntl (int cmd
, intptr_t arg
)
1450 res
= close_on_exec () ? FD_CLOEXEC
: 0;
1453 set_close_on_exec ((arg
& FD_CLOEXEC
) ? 1 : 0);
1458 debug_printf ("GETFL: %y", res
);
1462 /* Only O_APPEND, O_ASYNC and O_NONBLOCK are allowed.
1463 Each other flag will be ignored.
1464 Since O_ASYNC isn't defined in fcntl.h it's currently
1466 const int allowed_flags
= O_APPEND
| O_NONBLOCK
;
1467 int new_flags
= arg
& allowed_flags
;
1468 set_flags ((get_flags () & ~allowed_flags
) | new_flags
);
1476 struct flock
*fl
= (struct flock
*) arg
;
1477 fl
->l_type
&= F_RDLCK
| F_WRLCK
| F_UNLCK
;
1478 res
= mandatory_locking () ? mand_lock (cmd
, fl
) : lock (cmd
, fl
);
1489 /* Base terminal handlers. These just return errors. */
1492 fhandler_base::tcflush (int)
1499 fhandler_base::tcsendbreak (int)
1506 fhandler_base::tcdrain ()
1513 fhandler_base::tcflow (int)
1520 fhandler_base::tcsetattr (int, const struct termios
*)
1527 fhandler_base::tcgetattr (struct termios
*)
1534 fhandler_base::tcsetpgrp (const pid_t
)
1541 fhandler_base::tcgetpgrp ()
1548 fhandler_base::tcgetsid ()
1555 fhandler_base::ptsname_r (char *, size_t)
1561 /* Normal I/O constructor */
1562 fhandler_base::fhandler_base () :
1583 /* Normal I/O destructor */
1584 fhandler_base::~fhandler_base ()
1591 fhandler_base::set_no_inheritance (HANDLE
&h
, bool not_inheriting
)
1593 if (!SetHandleInformation (h
, HANDLE_FLAG_INHERIT
,
1594 not_inheriting
? 0 : HANDLE_FLAG_INHERIT
))
1595 debug_printf ("SetHandleInformation failed, %E");
1596 #ifdef DEBUGGING_AND_FDS_PROTECTED
1598 setclexec (oh
, h
, not_inheriting
);
1603 fhandler_base::fork_fixup (HANDLE parent
, HANDLE
&h
, const char *name
)
1607 if (!close_on_exec ())
1608 debug_printf ("handle %p already opened", h
);
1609 else if (!DuplicateHandle (parent
, h
, GetCurrentProcess (), &h
,
1610 0, !close_on_exec (), DUPLICATE_SAME_ACCESS
))
1611 system_printf ("%s - %E, handle %s<%p>", get_name (), name
, h
);
1622 fhandler_base::set_close_on_exec (bool val
)
1625 set_no_inheritance (io_handle
, val
);
1626 close_on_exec (val
);
1627 debug_printf ("set close_on_exec for %s to %d", get_name (), val
);
1631 fhandler_base::fixup_after_fork (HANDLE parent
)
1633 debug_printf ("inheriting '%s' from parent", get_name ());
1635 fork_fixup (parent
, io_handle
, "io_handle");
1636 /* POSIX locks are not inherited across fork. */
1638 del_my_locks (after_fork
);
1643 fhandler_base::fixup_after_exec ()
1645 debug_printf ("here for '%s'", get_name ());
1646 if (unique_id
&& close_on_exec ())
1647 del_my_locks (after_exec
);
1648 getdents_dir (NULL
);
1649 mandatory_locking (false);
1653 fhandler_base::is_nonblocking ()
1655 return (openflags
& O_NONBLOCK
) != 0;
1659 fhandler_base::set_nonblocking (int yes
)
1661 int current
= openflags
& O_NONBLOCK
;
1662 int new_flags
= yes
? (!current
? O_NONBLOCK
: current
) : 0;
1663 openflags
= (openflags
& ~O_NONBLOCK
) | new_flags
;
1667 fhandler_base::mkdir (mode_t
)
1677 fhandler_base::rmdir ()
1681 else if (!pc
.isdir ())
1682 set_errno (ENOTDIR
);
1689 fhandler_base::opendir (int fd
)
1691 set_errno (ENOTDIR
);
1696 fhandler_base::readdir (DIR *, dirent
*)
1702 fhandler_base::telldir (DIR *)
1704 set_errno (ENOTDIR
);
1709 fhandler_base::seekdir (DIR *, long)
1711 set_errno (ENOTDIR
);
1715 fhandler_base::rewinddir (DIR *)
1717 set_errno (ENOTDIR
);
1721 fhandler_base::closedir (DIR *)
1723 set_errno (ENOTDIR
);
1728 fhandler_base::fchmod (mode_t mode
)
1730 if (pc
.is_fs_special ())
1732 fhandler_disk_file
fh (pc
);
1733 return fh
.fchmod (mode
);
1735 /* By default, just succeeds. */
1740 fhandler_base::fchown (uid_t uid
, gid_t gid
)
1742 if (pc
.is_fs_special ())
1744 fhandler_disk_file
fh (pc
);
1745 return fh
.fchown (uid
, gid
);
1747 /* By default, just succeeds. */
1752 fhandler_base::facl (int cmd
, int nentries
, aclent_t
*aclbufp
)
1758 /* By default, just succeeds. */
1764 else if (nentries
< MIN_ACL_ENTRIES
)
1768 aclbufp
[0].a_type
= USER_OBJ
;
1769 aclbufp
[0].a_id
= myself
->uid
;
1770 aclbufp
[0].a_perm
= (S_IRUSR
| S_IWUSR
) >> 6;
1771 aclbufp
[1].a_type
= GROUP_OBJ
;
1772 aclbufp
[1].a_id
= myself
->gid
;
1773 aclbufp
[1].a_perm
= (S_IRGRP
| S_IWGRP
) >> 3;
1774 aclbufp
[2].a_type
= OTHER_OBJ
;
1775 aclbufp
[2].a_id
= ILLEGAL_GID
;
1776 aclbufp
[2].a_perm
= S_IROTH
| S_IWOTH
;
1777 res
= MIN_ACL_ENTRIES
;
1781 res
= MIN_ACL_ENTRIES
;
1791 fhandler_base::fgetxattr (const char *name
, void *value
, size_t size
)
1793 set_errno (ENOTSUP
);
1798 fhandler_base::fsetxattr (const char *name
, const void *value
, size_t size
,
1801 set_errno (ENOTSUP
);
1806 fhandler_base::fadvise (off_t offset
, off_t length
, int advice
)
1813 fhandler_base::fallocate (int mode
, off_t offset
, off_t length
)
1819 fhandler_base::link (const char *newpath
)
1826 fhandler_base::utimens (const struct timespec
*tvp
)
1828 if (is_fs_special ())
1829 return utimens_fs (tvp
);
1836 fhandler_base::fsync ()
1838 if (!get_handle () || nohandle ()
1839 || (pc
.isspecial () && !S_ISBLK (pc
.dev
.mode ())))
1844 if (pc
.isdir ()) /* Just succeed. */
1846 if (FlushFileBuffers (get_handle ()))
1849 /* Ignore ERROR_INVALID_FUNCTION because FlushFileBuffers() always fails
1850 with this code on raw devices which are unbuffered by default. */
1851 DWORD errcode
= GetLastError();
1852 if (errcode
== ERROR_INVALID_FUNCTION
)
1855 __seterrno_from_win_error (errcode
);
1860 fhandler_base::fpathconf (int v
)
1867 return pc
.fs_is_ntfs () || pc
.fs_is_samba () || pc
.fs_is_nfs ()
1880 /* NAME_MAX is without trailing \0 */
1883 ret
= NT_MAX_PATH
- strlen (get_name ()) - 2;
1884 return ret
< 0 ? 0 : ret
> NAME_MAX
? NAME_MAX
: ret
;
1886 /* PATH_MAX is with trailing \0 */
1889 ret
= NT_MAX_PATH
- strlen (get_name ()) - 1;
1890 return ret
< 0 ? 0 : ret
> PATH_MAX
? PATH_MAX
: ret
;
1893 || get_device () == FH_FIFO
|| get_device () == FH_PIPE
1894 || get_device () == FH_PIPER
|| get_device () == FH_PIPEW
)
1898 case _PC_CHOWN_RESTRICTED
:
1904 return _POSIX_VDISABLE
;
1913 case _PC_FILESIZEBITS
:
1914 return FILESIZEBITS
;
1915 case _PC_2_SYMLINKS
:
1917 case _PC_SYMLINK_MAX
:
1919 case _PC_POSIX_PERMISSIONS
:
1920 case _PC_POSIX_SECURITY
:
1921 if (get_device () == FH_FS
)
1922 return pc
.has_acls () || pc
.fs_is_nfs ();
1925 case _PC_CASE_INSENSITIVE
:
1926 return !!pc
.objcaseinsensitive ();
1935 fhandler_base::npfs_handle (HANDLE
&nph
)
1937 static NO_COPY SRWLOCK npfs_lock
;
1938 static NO_COPY HANDLE npfs_dirh
;
1940 NTSTATUS status
= STATUS_SUCCESS
;
1941 OBJECT_ATTRIBUTES attr
;
1944 /* Lockless after first call. */
1948 return STATUS_SUCCESS
;
1950 AcquireSRWLockExclusive (&npfs_lock
);
1953 InitializeObjectAttributes (&attr
, &ro_u_npfs
, 0, NULL
, NULL
);
1954 status
= NtOpenFile (&npfs_dirh
, FILE_READ_ATTRIBUTES
| SYNCHRONIZE
,
1955 &attr
, &io
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1958 ReleaseSRWLockExclusive (&npfs_lock
);
1959 if (NT_SUCCESS (status
))