1 /* fhandler.cc. See console.cc for fhandler_console functions.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
18 #include "perprocess.h"
20 #include "cygwin/version.h"
31 #include "shared_info.h"
32 #include <asm/socket.h>
34 #define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
35 #define MIN_OVERLAPPED_WRITE_LEN (1 * 1024 * 1024)
37 static const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
39 struct __cygwin_perfile *perfile_table;
41 HANDLE NO_COPY fhandler_base_overlapped::asio_done;
42 LONG NO_COPY fhandler_base_overlapped::asio_close_counter;
45 fhandler_base::reset (const fhandler_base *from)
56 fhandler_base::puts_readahead (const char *s, size_t len)
59 while ((len == (size_t) -1 ? *s : len--)
60 && (success = put_readahead (*s++) > 0))
66 fhandler_base::put_readahead (char value)
69 if (raixput < rabuflen)
71 else if ((newrabuf = (char *) realloc (rabuf, rabuflen += 32)))
76 rabuf[raixput++] = value;
82 fhandler_base::get_readahead ()
86 chret = ((unsigned char) rabuf[raixget++]) & 0xff;
87 /* FIXME - not thread safe */
89 raixget = raixput = ralen = 0;
94 fhandler_base::peek_readahead (int queryput)
97 if (!queryput && raixget < ralen)
98 chret = ((unsigned char) rabuf[raixget]) & 0xff;
99 else if (queryput && raixput > 0)
100 chret = ((unsigned char) rabuf[raixput - 1]) & 0xff;
105 fhandler_base::set_readahead_valid (int val, int ch)
108 ralen = raixget = raixput = 0;
114 fhandler_base::eat_readahead (int n)
121 if ((int) (ralen -= n) < 0)
124 if (raixget >= ralen)
125 raixget = raixput = ralen = 0;
126 else if (raixput > ralen)
134 fhandler_base::get_readahead_into_buffer (char *buf, size_t buflen)
137 int copied_chars = 0;
140 if ((ch = get_readahead ()) < 0)
144 buf[copied_chars++] = (unsigned char)(ch & 0xff);
151 /* Record the file name. and name hash */
153 fhandler_base::set_name (path_conv &in_pc)
158 char *fhandler_base::get_proc_fd_name (char *buf)
161 return strcpy (buf, get_name ());
163 return strcpy (buf, dev ().name);
164 return strcpy (buf, "");
167 /* Detect if we are sitting at EOF for conditions where Windows
168 returns an error but UNIX doesn't. */
173 FILE_POSITION_INFORMATION fpi;
174 FILE_STANDARD_INFORMATION fsi;
176 if (NT_SUCCESS (NtQueryInformationFile (h, &io, &fsi, sizeof fsi,
177 FileStandardInformation))
178 && NT_SUCCESS (NtQueryInformationFile (h, &io, &fpi, sizeof fpi,
179 FilePositionInformation))
180 && fsi.EndOfFile.QuadPart == fpi.CurrentByteOffset.QuadPart)
186 fhandler_base::set_flags (int flags, int supplied_bin)
190 debug_printf ("flags %p, supplied_bin %p", flags, supplied_bin);
191 if ((bin = flags & (O_BINARY | O_TEXT)))
192 debug_printf ("O_TEXT/O_BINARY set in flags %p", bin);
193 else if (rbinset () && wbinset ())
194 bin = rbinary () ? O_BINARY : O_TEXT; // FIXME: Not quite right
195 else if ((fmode = get_default_fmode (flags)) & O_BINARY)
197 else if (fmode & O_TEXT)
199 else if (supplied_bin)
202 bin = wbinary () || rbinary () ? O_BINARY : O_TEXT;
204 openflags = flags | bin;
207 rbinary (bin ? true : false);
208 wbinary (bin ? true : false);
209 syscall_printf ("filemode set to %s", bin ? "binary" : "text");
212 /* Normal file i/o handlers. */
214 /* Cover function to ReadFile to achieve (as much as possible) Posix style
215 semantics and use of errno. */
217 fhandler_base::raw_read (void *ptr, size_t& ulen)
219 #define bytes_read ulen
221 int try_noreserve = 1;
226 BOOL res = ReadFile (get_handle (), ptr, len, (DWORD *) &ulen, NULL);
229 /* Some errors are not really errors. Detect such cases here. */
231 DWORD errcode = GetLastError ();
234 case ERROR_BROKEN_PIPE:
235 /* This is really EOF. */
238 case ERROR_MORE_DATA:
239 /* `bytes_read' is supposedly valid. */
242 if (is_at_eof (get_handle ()))
250 switch (mmap_is_attached_or_noreserve (ptr, len))
252 case MMAP_NORESERVE_COMMITED:
254 case MMAP_RAISE_SIGBUS:
261 case ERROR_INVALID_FUNCTION:
262 case ERROR_INVALID_PARAMETER:
263 case ERROR_INVALID_HANDLE:
267 bytes_read = (size_t) -1;
271 syscall_printf ("ReadFile %s(%p) failed, %E", get_name (), get_handle ());
272 __seterrno_from_win_error (errcode);
273 bytes_read = (size_t) -1;
280 /* Cover function to WriteFile to provide Posix interface and semantics
281 (as much as possible). */
283 fhandler_base::raw_write (const void *ptr, size_t len)
287 static _RDATA LARGE_INTEGER off_current =
288 { QuadPart:FILE_USE_FILE_POINTER_POSITION };
289 static _RDATA LARGE_INTEGER off_append =
290 { QuadPart:FILE_WRITE_TO_END_OF_FILE };
292 status = NtWriteFile (get_output_handle (), NULL, NULL, NULL, &io,
294 (get_flags () & O_APPEND) ? &off_append : &off_current,
296 if (!NT_SUCCESS (status))
298 __seterrno_from_nt_status (status);
299 if (get_errno () == EPIPE)
303 return io.Information;
307 fhandler_base::get_default_fmode (int flags)
312 size_t nlen = strlen (get_name ());
313 unsigned accflags = (flags & O_ACCMODE);
314 for (__cygwin_perfile *pf = perfile_table; pf->name; pf++)
315 if (!*pf->name && (pf->flags & O_ACCMODE) == accflags)
317 fmode = pf->flags & ~O_ACCMODE;
322 size_t pflen = strlen (pf->name);
323 const char *stem = get_name () + nlen - pflen;
324 if (pflen > nlen || (stem != get_name () && !isdirsep (stem[-1])))
326 else if ((pf->flags & O_ACCMODE) == accflags
327 && pathmatch (stem, pf->name, !!pc.objcaseinsensitive ()))
329 fmode = pf->flags & ~O_ACCMODE;
338 fhandler_base::device_access_denied (int flags)
344 if (flags & (O_WRONLY | O_APPEND))
349 return fhaccess (mode, true);
353 fhandler_base::fhaccess (int flags, bool effective)
358 set_errno (error ());
368 if (!(flags & (R_OK | W_OK | X_OK)))
371 if (is_fs_special ())
373 else if (has_attribute (FILE_ATTRIBUTE_READONLY) && (flags & W_OK)
376 else if (has_acls ())
378 res = check_file_access (pc, flags, effective);
381 else if (get_device () == FH_REGISTRY && open (O_RDONLY, 0) && get_handle ())
383 res = check_registry_access (get_handle (), flags, effective);
394 if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
396 if (!(st.st_mode & S_IRUSR))
399 else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
401 if (!(st.st_mode & S_IRGRP))
404 else if (!(st.st_mode & S_IROTH))
410 if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
412 if (!(st.st_mode & S_IWUSR))
415 else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
417 if (!(st.st_mode & S_IWGRP))
420 else if (!(st.st_mode & S_IWOTH))
426 if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
428 if (!(st.st_mode & S_IXUSR))
431 else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
433 if (!(st.st_mode & S_IXGRP))
436 else if (!(st.st_mode & S_IXOTH))
446 if (!res && (flags & W_OK) && get_device () == FH_FS
447 && (pc.fs_flags () & FILE_READ_ONLY_VOLUME))
452 debug_printf ("returning %d", res);
457 fhandler_base::open_with_arch (int flags, mode_t mode)
460 if (!(res = (archetype && archetype->io_handle)
461 || open (flags, (mode & 07777) & ~cygheap->umask)))
468 if (!archetype->get_io_handle ())
471 archetype_usecount (1);
472 archetype->archetype = NULL;
478 /* Preserve any name (like /dev/tty) derived from build_fh_pc. */
483 name = (char *) alloca (strlen (get_name ()) + 1);
484 strcpy (name, get_name ());
486 fhandler_base *arch = archetype;
487 archetype->copyto (this);
491 archetype_usecount (1);
497 close_on_exec (flags & O_CLOEXEC);
501 /* Open system call handler function. */
503 fhandler_base::open (int flags, mode_t mode)
507 ULONG file_attributes = 0;
508 ULONG shared = (get_major () == DEV_TAPE_MAJOR ? 0 : FILE_SHARE_VALID_FLAGS);
509 ULONG create_disposition;
510 OBJECT_ATTRIBUTES attr;
513 PFILE_FULL_EA_INFORMATION p = NULL;
516 syscall_printf ("(%S, %p)", pc.get_nt_native_path (), flags);
518 pc.get_object_attr (attr, *sec_none_cloexec (flags));
520 options = FILE_OPEN_FOR_BACKUP_INTENT;
521 switch (query_open ())
523 case query_read_control:
524 access = READ_CONTROL;
526 case query_read_attributes:
527 access = READ_CONTROL | FILE_READ_ATTRIBUTES;
529 case query_write_control:
530 access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
532 case query_write_dac:
533 access = READ_CONTROL | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
535 case query_write_attributes:
536 access = READ_CONTROL | FILE_WRITE_ATTRIBUTES;
539 if ((flags & O_ACCMODE) == O_RDONLY)
540 access = GENERIC_READ;
541 else if ((flags & O_ACCMODE) == O_WRONLY)
542 access = GENERIC_WRITE | READ_CONTROL | FILE_READ_ATTRIBUTES;
544 access = GENERIC_READ | GENERIC_WRITE;
546 options |= FILE_WRITE_THROUGH;
547 if (flags & O_DIRECT)
548 options |= FILE_NO_INTERMEDIATE_BUFFERING;
549 if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR)
551 options |= FILE_SYNCHRONOUS_IO_NONALERT;
552 access |= SYNCHRONIZE;
557 /* Don't use the FILE_OVERWRITE{_IF} flags here. See below for an
558 explanation, why that's not such a good idea. */
559 if ((flags & O_EXCL) && (flags & O_CREAT))
560 create_disposition = FILE_CREATE;
562 create_disposition = (flags & O_CREAT) ? FILE_OPEN_IF : FILE_OPEN;
564 if (get_device () == FH_FS)
566 /* Add the reparse point flag to native symlinks, otherwise we open the
567 target, not the symlink. This would break lstat. */
568 if (pc.is_rep_symlink ())
569 options |= FILE_OPEN_REPARSE_POINT;
573 /* Make sure we can read EAs of files on an NFS share. Also make
574 sure that we're going to act on the file itself, even if it's a
576 access |= FILE_READ_EA;
579 if (query_open () >= query_write_control)
580 access |= FILE_WRITE_EA;
581 plen = sizeof nfs_aol_ffei;
582 p = (PFILE_FULL_EA_INFORMATION) &nfs_aol_ffei;
586 /* Starting with Windows 2000, when trying to overwrite an already
587 existing file with FILE_ATTRIBUTE_HIDDEN and/or FILE_ATTRIBUTE_SYSTEM
588 attribute set, CreateFile fails with ERROR_ACCESS_DENIED.
589 Per MSDN you have to create the file with the same attributes as
590 already specified for the file. */
591 if (((flags & O_CREAT) || create_disposition == FILE_OVERWRITE)
592 && has_attribute (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
593 file_attributes |= pc.file_attributes ();
597 file_attributes |= FILE_ATTRIBUTE_NORMAL;
601 /* When creating a file on an NFS share, we have to set the
602 file mode by writing a NFS fattr3 structure with the
603 correct mode bits set. */
604 access |= FILE_WRITE_EA;
605 plen = sizeof (FILE_FULL_EA_INFORMATION) + sizeof (NFS_V3_ATTR)
607 p = (PFILE_FULL_EA_INFORMATION) alloca (plen);
608 p->NextEntryOffset = 0;
610 p->EaNameLength = sizeof (NFS_V3_ATTR) - 1;
611 p->EaValueLength = sizeof (fattr3);
612 strcpy (p->EaName, NFS_V3_ATTR);
613 fattr3 *nfs_attr = (fattr3 *) (p->EaName
614 + p->EaNameLength + 1);
615 memset (nfs_attr, 0, sizeof (fattr3));
616 nfs_attr->type = NF3REG;
617 nfs_attr->mode = mode;
619 else if (!has_acls () && !(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
620 /* If mode has no write bits set, and ACLs are not used, we set
621 the DOS R/O attribute. */
622 file_attributes |= FILE_ATTRIBUTE_READONLY;
623 /* The file attributes are needed for later use in, e.g. fchmod. */
624 pc.file_attributes (file_attributes);
625 /* Never set the WRITE_DAC flag here. Calls to fstat may return
626 wrong st_ctime information after calls to fchmod, fchown, etc
627 because Windows only gurantees to update the metadata when
628 the handle is closed or flushed. However, flushing the file
629 on every fstat to enforce POSIXy stat behaviour is exceessivly
630 slow, compared to open/close the file when changing the file's
631 security descriptor. */
635 status = NtCreateFile (&fh, access, &attr, &io, NULL, file_attributes, shared,
636 create_disposition, options, p, plen);
637 if (!NT_SUCCESS (status))
639 /* Trying to create a directory should return EISDIR, not ENOENT. */
640 PUNICODE_STRING upath = pc.get_nt_native_path ();
641 if (status == STATUS_OBJECT_NAME_INVALID && (flags & O_CREAT)
642 && upath->Buffer[upath->Length / sizeof (WCHAR) - 1] == '\\')
645 __seterrno_from_nt_status (status);
650 /* Always create files using a NULL SD. Create correct permission bits
651 afterwards, maintaining the owner and group information just like chmod.
653 This is done for two reasons.
655 On Windows filesystems we need to create the file with default
656 permissions to allow inheriting ACEs. When providing an explicit DACL
657 in calls to [Nt]CreateFile, the created file will not inherit default
658 permissions from the parent object. This breaks not only Windows
659 inheritance, but also POSIX ACL inheritance.
661 Another reason to do this are remote shares. Files on a remote share
662 are created as the user used for authentication. In a domain that's
663 usually the user you're logged in as. Outside of a domain you're
664 authenticating using a local user account on the sharing machine.
665 If the SIDs of the client machine are used, that's entirely
666 unexpected behaviour. Doing it like we do here creates the expected SD
667 in a domain as well as on standalone servers.
668 This is the result of a discussion on the samba-technical list, starting at
669 http://lists.samba.org/archive/samba-technical/2008-July/060247.html */
670 if (io.Information == FILE_CREATED && has_acls ())
671 set_file_attribute (fh, pc, ILLEGAL_UID, ILLEGAL_GID, S_JUSTCREATED | mode);
673 /* If you O_TRUNC a file on Linux, the data is truncated, but the EAs are
674 preserved. If you open a file on Windows with FILE_OVERWRITE{_IF} or
675 FILE_SUPERSEDE, all streams are truncated, including the EAs. So we don't
676 use the FILE_OVERWRITE{_IF} flags, but instead just open the file and set
677 the size of the data stream explicitely to 0. Apart from being more Linux
678 compatible, this implementation has the pleasant side-effect to be more
679 than 5% faster than using FILE_OVERWRITE{_IF} (tested on W7 32 bit). */
680 if ((flags & O_TRUNC)
681 && (flags & O_ACCMODE) != O_RDONLY
682 && io.Information != FILE_CREATED
683 && get_device () == FH_FS)
685 FILE_END_OF_FILE_INFORMATION feofi = { EndOfFile:{ QuadPart:0 } };
686 status = NtSetInformationFile (fh, &io, &feofi, sizeof feofi,
687 FileEndOfFileInformation);
688 /* In theory, truncating the file should never fail, since the opened
689 handle has FILE_WRITE_DATA permissions, which is all you need to
690 be allowed to truncate a file. Better safe than sorry. */
691 if (!NT_SUCCESS (status))
693 __seterrno_from_nt_status (status);
700 set_flags (flags, pc.binmode ());
705 debug_printf ("%x = NtCreateFile "
706 "(%p, %x, %S, io, NULL, %x, %x, %x, %x, NULL, 0)",
707 status, fh, access, pc.get_nt_native_path (), file_attributes,
708 shared, create_disposition, options);
710 syscall_printf ("%d = fhandler_base::open (%S, %p)",
711 res, pc.get_nt_native_path (), flags);
716 open buffer in binary mode? Just do the read.
718 open buffer in text mode? Scan buffer for control zs and handle
719 the first one found. Then scan buffer, converting every \r\n into
720 an \n. If last char is an \r, look ahead one more char, if \n then
721 modify \r, if not, remember char.
724 fhandler_base::read (void *in_ptr, size_t& len)
726 char *ptr = (char *) in_ptr;
727 ssize_t copied_chars = get_readahead_into_buffer (ptr, len);
731 len = (size_t) copied_chars;
738 len = (size_t) copied_chars;
742 raw_read (ptr + copied_chars, len);
745 else if ((ssize_t) len > 0)
750 if (rbinary () || (ssize_t) len <= 0)
753 /* Scan buffer and turn \r\n into \n */
754 char *src, *dst, *end;
759 /* Read up to the last but one char - the last char needs special handling */
762 if (*src == '\r' && src[1] == '\n')
767 /* If not beyond end and last char is a '\r' then read one more
768 to see if we should translate this one too */
771 else if (*src != '\r')
777 raw_read (&c1, c1len);
784 set_readahead_valid (1, c1);
789 len = dst - (char *) ptr;
792 if (strace.active ())
794 char buf[16 * 6 + 1];
797 for (int i = 0; i < copied_chars && i < 16; ++i)
799 unsigned char c = ((unsigned char *) ptr)[i];
800 __small_sprintf (p, " %c", c);
804 debug_printf ("read %d bytes (%s%s)", copied_chars, buf,
805 copied_chars > 16 ? " ..." : "");
810 debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text");
814 fhandler_base::write (const void *ptr, size_t len)
818 FILE_POSITION_INFORMATION fpi;
819 FILE_STANDARD_INFORMATION fsi;
823 did_lseek (false); /* don't do it again */
825 if (!(get_flags () & O_APPEND)
826 && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
827 &io, &fsi, sizeof fsi,
828 FileStandardInformation))
829 && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
830 &io, &fpi, sizeof fpi,
831 FilePositionInformation))
832 && fpi.CurrentByteOffset.QuadPart
833 >= fsi.EndOfFile.QuadPart + (128 * 1024)
834 && (pc.fs_flags () & FILE_SUPPORTS_SPARSE_FILES))
836 /* If the file system supports sparse files and the application
837 is writing after a long seek beyond EOF, convert the file to
840 status = NtFsControlFile (get_output_handle (), NULL, NULL, NULL,
841 &io, FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
842 syscall_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
843 status, pc.get_nt_native_path ());
849 debug_printf ("binary write");
850 res = raw_write (ptr, len);
854 debug_printf ("text write");
855 /* This is the Microsoft/DJGPP way. Still not ideal, but it's
857 Modified slightly by CGF 2000-10-07 */
859 int left_in_data = len;
860 char *data = (char *)ptr;
863 while (left_in_data > 0)
865 char buf[CHUNK_SIZE + 1], *buf_ptr = buf;
866 int left_in_buf = CHUNK_SIZE;
868 while (left_in_buf > 0 && left_in_data > 0)
879 if (left_in_data > 0 && ch == '\r' && *data == '\n')
881 *buf_ptr++ = *data++;
887 /* We've got a buffer-full, or we're out of data. Write it out */
889 int want = buf_ptr - buf;
890 if ((nbytes = raw_write (buf, want)) == want)
892 /* Keep track of how much written not counting additional \r's */
893 res = data - (char *)ptr;
898 res = -1; /* Error */
900 res += nbytes; /* Partial write. Return total bytes written. */
901 break; /* All done */
909 fhandler_base::readv (const struct iovec *const iov, const int iovcnt,
913 assert (iovcnt >= 1);
919 read (iov->iov_base, len);
923 if (tot == -1) // i.e. if not pre-calculated by the caller.
926 const struct iovec *iovptr = iov + iovcnt;
930 len += iovptr->iov_len;
932 while (iovptr != iov);
938 char *buf = (char *) malloc (len);
947 ssize_t nbytes = (ssize_t) len;
949 const struct iovec *iovptr = iov;
954 const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
955 memcpy (iovptr->iov_base, p, frag);
966 fhandler_base::writev (const struct iovec *const iov, const int iovcnt,
970 assert (iovcnt >= 1);
973 return write (iov->iov_base, iov->iov_len);
975 if (tot == -1) // i.e. if not pre-calculated by the caller.
978 const struct iovec *iovptr = iov + iovcnt;
982 tot += iovptr->iov_len;
984 while (iovptr != iov);
992 char *const buf = (char *) malloc (tot);
1001 const struct iovec *iovptr = iov;
1006 const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
1007 memcpy (bufptr, iovptr->iov_base, frag);
1012 ssize_t ret = write (buf, tot);
1018 fhandler_base::lseek (_off64_t offset, int whence)
1022 FILE_POSITION_INFORMATION fpi;
1023 FILE_STANDARD_INFORMATION fsi;
1025 /* Seeks on text files is tough, we rewind and read till we get to the
1028 if (whence != SEEK_CUR || offset != 0)
1030 if (whence == SEEK_CUR)
1031 offset -= ralen - raixget;
1032 set_readahead_valid (0);
1038 fpi.CurrentByteOffset.QuadPart = offset;
1041 status = NtQueryInformationFile (get_handle (), &io, &fpi, sizeof fpi,
1042 FilePositionInformation);
1043 if (!NT_SUCCESS (status))
1045 __seterrno_from_nt_status (status);
1048 fpi.CurrentByteOffset.QuadPart += offset;
1050 default: /* SEEK_END */
1051 status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
1052 FileStandardInformation);
1053 if (!NT_SUCCESS (status))
1055 __seterrno_from_nt_status (status);
1058 fpi.CurrentByteOffset.QuadPart = fsi.EndOfFile.QuadPart + offset;
1062 debug_printf ("setting file pointer to %U", fpi.CurrentByteOffset.QuadPart);
1063 status = NtSetInformationFile (get_handle (), &io, &fpi, sizeof fpi,
1064 FilePositionInformation);
1065 if (!NT_SUCCESS (status))
1067 __seterrno_from_nt_status (status);
1070 _off64_t res = fpi.CurrentByteOffset.QuadPart;
1072 /* When next we write(), we will check to see if *this* seek went beyond
1073 the end of the file and if so, potentially sparsify the file. */
1076 /* If this was a SEEK_CUR with offset 0, we still might have
1077 readahead that we have to take into account when calculating
1078 the actual position for the application. */
1079 if (whence == SEEK_CUR)
1080 res -= ralen - raixget;
1086 fhandler_base::pread (void *, size_t, _off64_t)
1093 fhandler_base::pwrite (void *, size_t, _off64_t)
1100 fhandler_base::close_with_arch ()
1107 debug_printf ("closing passed in archetype, usecount %d", usecount);
1110 debug_printf ("not closing passed in archetype, usecount %d", usecount);
1115 else if (!archetype)
1120 if (archetype_usecount (-1) == 0)
1122 debug_printf ("closing archetype");
1127 debug_printf ("not closing archetype");
1135 cygheap->fdtab.delete_archetype (archetype);
1142 fhandler_base::close ()
1146 syscall_printf ("closing '%s' handle %p", get_name (), get_handle ());
1147 if (nohandle () || CloseHandle (get_handle ()))
1151 paranoid_printf ("CloseHandle (%d <%s>) failed", get_handle (),
1160 flush_async_io (void *arg)
1162 fhandler_base_overlapped *fh = (fhandler_base_overlapped *) arg;
1163 debug_only_printf ("waiting for %s I/O for %s",
1164 (fh->get_access () & GENERIC_WRITE) ? "write" : "read",
1166 SetEvent (fh->get_overlapped ()->hEvent); /* force has_ongoing_io to block */
1167 bool res = fh->has_ongoing_io ();
1168 debug_printf ("finished waiting for I/O from %s, res %d", fh->get_name (),
1173 InterlockedDecrement (&fhandler_base_overlapped::asio_close_counter);
1174 SetEvent (fhandler_base_overlapped::asio_done);
1176 _my_tls._ctinfo->auto_release ();
1181 fhandler_base_overlapped::flush_all_async_io ()
1183 while (asio_close_counter > 0)
1184 if (WaitForSingleObject (asio_done, INFINITE) != WAIT_OBJECT_0)
1186 system_printf ("WaitForSingleObject failed, possible data loss in pipe, %E");
1189 asio_close_counter = 0;
1191 CloseHandle (asio_done);
1194 /* Start a thread to handle closing of overlapped asynchronous I/O since
1195 Windows amazingly does not seem to always flush I/O on close. */
1197 fhandler_base_overlapped::check_later ()
1199 set_close_on_exec (true);
1202 && !(asio_done = CreateEvent (&sec_none_nih, false, false,
1203 shared_name (buf, "asio",
1204 GetCurrentProcessId ()))))
1205 api_fatal ("CreateEvent failed, %E");
1207 InterlockedIncrement (&asio_close_counter);
1208 if (!new cygthread(flush_async_io, this, "flasio"))
1209 api_fatal ("couldn't create a thread to track async I/O, %E");
1210 debug_printf ("started thread to handle asynchronous closing for %s", get_name ());
1214 fhandler_base_overlapped::close ()
1217 /* Need to treat non-blocking I/O specially because Windows appears to
1219 if (is_nonblocking () && has_ongoing_io ())
1221 clone (HEAP_3_FHANDLER)->check_later ();
1226 destroy_overlapped ();
1227 res = fhandler_base::close ();
1233 fhandler_base::ioctl (unsigned int cmd, void *buf)
1240 set_nonblocking (*(int *) buf);
1254 syscall_printf ("%d = ioctl (%x, %p)", res, cmd, buf);
1259 fhandler_base::lock (int, struct __flock64 *)
1266 fhandler_base::fstat (struct __stat64 *buf)
1268 if (is_fs_special ())
1269 return fstat_fs (buf);
1271 switch (get_device ())
1274 buf->st_mode = S_IFIFO | S_IRUSR | S_IWUSR;
1277 buf->st_mode = S_IFIFO | S_IWUSR;
1280 buf->st_mode = S_IFIFO | S_IRUSR;
1283 buf->st_mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
1286 buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
1290 buf->st_uid = geteuid32 ();
1291 buf->st_gid = getegid32 ();
1293 buf->st_blksize = PREFERRED_IO_BLKSIZE;
1295 buf->st_ctim.tv_sec = 1164931200L; /* Arbitrary value: 2006-12-01 */
1296 buf->st_ctim.tv_nsec = 0L;
1297 buf->st_birthtim = buf->st_ctim;
1298 buf->st_mtim.tv_sec = time (NULL); /* Arbitrary value: current time,
1300 buf->st_mtim.tv_nsec = 0L;
1301 buf->st_atim = buf->st_mtim;
1307 fhandler_base::fstatvfs (struct statvfs *sfs)
1309 /* If we hit this base implementation, it's some device in /dev.
1310 Just call statvfs on /dev for simplicity. */
1311 path_conv pc ("/dev", PC_KEEP_HANDLE);
1312 fhandler_disk_file fh (pc);
1313 return fh.fstatvfs (sfs);
1317 fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
1321 a &= GENERIC_READ | GENERIC_WRITE;
1323 if (a == GENERIC_READ)
1325 else if (a == GENERIC_WRITE)
1327 else if (a == (GENERIC_READ | GENERIC_WRITE))
1329 set_flags (flags | bin);
1331 debug_printf ("created new fhandler_base for handle %p, bin %d", f, rbinary ());
1336 fhandler_base::dup (fhandler_base *child, int)
1338 debug_printf ("in fhandler_base dup");
1341 if (!nohandle () && !archetype)
1343 if (!DuplicateHandle (GetCurrentProcess (), get_handle (),
1344 GetCurrentProcess (), &nh,
1345 0, TRUE, DUPLICATE_SAME_ACCESS))
1347 debug_printf ("dup(%s) failed, handle %x, %E",
1348 get_name (), get_handle ());
1354 child->set_io_handle (nh);
1360 fhandler_base_overlapped::dup (fhandler_base *child, int flags)
1362 int res = fhandler_base::dup (child, flags) ||
1363 ((fhandler_base_overlapped *) child)->setup_overlapped ();
1367 int fhandler_base::fcntl (int cmd, void *arg)
1374 res = close_on_exec () ? FD_CLOEXEC : 0;
1377 set_close_on_exec (((int) arg & FD_CLOEXEC) ? 1 : 0);
1382 debug_printf ("GETFL: %p", res);
1386 /* Only O_APPEND, O_ASYNC and O_NONBLOCK/O_NDELAY are allowed.
1387 Each other flag will be ignored.
1388 Since O_ASYNC isn't defined in fcntl.h it's currently
1390 const int allowed_flags = O_APPEND | O_NONBLOCK_MASK;
1391 int new_flags = (int) arg & allowed_flags;
1392 /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
1393 Set only the flag that has been passed in. If both are set, just
1394 record O_NONBLOCK. */
1395 if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
1396 new_flags &= ~OLD_O_NDELAY;
1397 set_flags ((get_flags () & ~allowed_flags) | new_flags);
1409 /* Base terminal handlers. These just return errors. */
1412 fhandler_base::tcflush (int)
1419 fhandler_base::tcsendbreak (int)
1426 fhandler_base::tcdrain ()
1433 fhandler_base::tcflow (int)
1440 fhandler_base::tcsetattr (int, const struct termios *)
1447 fhandler_base::tcgetattr (struct termios *)
1454 fhandler_base::tcsetpgrp (const pid_t)
1461 fhandler_base::tcgetpgrp ()
1468 fhandler_base::tcgetsid ()
1475 fhandler_base::ptsname_r (char *, size_t)
1481 /* Normal I/O constructor */
1482 fhandler_base::fhandler_base () :
1500 /* Normal I/O destructor */
1501 fhandler_base::~fhandler_base ()
1507 /**********************************************************************/
1510 fhandler_dev_null::fhandler_dev_null () :
1516 fhandler_base::set_no_inheritance (HANDLE &h, bool not_inheriting)
1518 if (!SetHandleInformation (h, HANDLE_FLAG_INHERIT,
1519 not_inheriting ? 0 : HANDLE_FLAG_INHERIT))
1520 debug_printf ("SetHandleInformation failed, %E");
1521 #ifdef DEBUGGING_AND_FDS_PROTECTED
1523 setclexec (oh, h, not_inheriting);
1528 fhandler_base::fork_fixup (HANDLE parent, HANDLE &h, const char *name)
1532 if (/* !is_socket () && */ !close_on_exec ())
1533 debug_printf ("handle %p already opened", h);
1534 else if (!DuplicateHandle (parent, h, GetCurrentProcess (), &h,
1535 0, !close_on_exec (), DUPLICATE_SAME_ACCESS))
1536 system_printf ("%s - %E, handle %s<%p>", get_name (), name, h);
1547 fhandler_base::set_close_on_exec (bool val)
1550 set_no_inheritance (io_handle, val);
1551 close_on_exec (val);
1552 debug_printf ("set close_on_exec for %s to %d", get_name (), val);
1556 fhandler_base::fixup_after_fork (HANDLE parent)
1558 debug_printf ("inheriting '%s' from parent", get_name ());
1560 fork_fixup (parent, io_handle, "io_handle");
1561 /* POSIX locks are not inherited across fork. */
1563 del_my_locks (after_fork);
1567 fhandler_base_overlapped::fixup_after_fork (HANDLE parent)
1569 setup_overlapped ();
1570 fhandler_base::fixup_after_fork (parent);
1574 fhandler_base::fixup_after_exec ()
1576 debug_printf ("here for '%s'", get_name ());
1577 if (unique_id && close_on_exec ())
1578 del_my_locks (after_exec);
1581 fhandler_base_overlapped::fixup_after_exec ()
1583 setup_overlapped ();
1584 fhandler_base::fixup_after_exec ();
1588 fhandler_base::is_nonblocking ()
1590 return (openflags & O_NONBLOCK_MASK) != 0;
1594 fhandler_base::set_nonblocking (int yes)
1596 int current = openflags & O_NONBLOCK_MASK;
1597 int new_flags = yes ? (!current ? O_NONBLOCK : current) : 0;
1598 openflags = (openflags & ~O_NONBLOCK_MASK) | new_flags;
1602 fhandler_base::mkdir (mode_t)
1612 fhandler_base::rmdir ()
1616 else if (!pc.isdir ())
1617 set_errno (ENOTDIR);
1624 fhandler_base::opendir (int fd)
1626 set_errno (ENOTDIR);
1631 fhandler_base::readdir (DIR *, dirent *)
1637 fhandler_base::telldir (DIR *)
1639 set_errno (ENOTDIR);
1644 fhandler_base::seekdir (DIR *, long)
1646 set_errno (ENOTDIR);
1650 fhandler_base::rewinddir (DIR *)
1652 set_errno (ENOTDIR);
1656 fhandler_base::closedir (DIR *)
1658 set_errno (ENOTDIR);
1663 fhandler_base::fchmod (mode_t mode)
1665 extern int chmod_device (path_conv& pc, mode_t mode);
1666 if (pc.is_fs_special ())
1667 return chmod_device (pc, mode);
1668 /* By default, just succeeds. */
1673 fhandler_base::fchown (__uid32_t uid, __gid32_t gid)
1675 if (pc.is_fs_special ())
1676 return ((fhandler_disk_file *) this)->fhandler_disk_file::fchown (uid, gid);
1677 /* By default, just succeeds. */
1682 fhandler_base::facl (int cmd, int nentries, __aclent32_t *aclbufp)
1688 /* By default, just succeeds. */
1694 else if (nentries < MIN_ACL_ENTRIES)
1698 aclbufp[0].a_type = USER_OBJ;
1699 aclbufp[0].a_id = myself->uid;
1700 aclbufp[0].a_perm = (S_IRUSR | S_IWUSR) >> 6;
1701 aclbufp[1].a_type = GROUP_OBJ;
1702 aclbufp[1].a_id = myself->gid;
1703 aclbufp[1].a_perm = (S_IRGRP | S_IWGRP) >> 3;
1704 aclbufp[2].a_type = OTHER_OBJ;
1705 aclbufp[2].a_id = ILLEGAL_GID;
1706 aclbufp[2].a_perm = S_IROTH | S_IWOTH;
1707 aclbufp[3].a_type = CLASS_OBJ;
1708 aclbufp[3].a_id = ILLEGAL_GID;
1709 aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
1710 res = MIN_ACL_ENTRIES;
1714 res = MIN_ACL_ENTRIES;
1724 fhandler_base::fgetxattr (const char *name, void *value, size_t size)
1726 set_errno (ENOTSUP);
1731 fhandler_base::fsetxattr (const char *name, const void *value, size_t size,
1734 set_errno (ENOTSUP);
1739 fhandler_base::fadvise (_off64_t offset, _off64_t length, int advice)
1746 fhandler_base::ftruncate (_off64_t length, bool allow_truncate)
1753 fhandler_base::link (const char *newpath)
1760 fhandler_base::utimens (const struct timespec *tvp)
1762 if (is_fs_special ())
1763 return utimens_fs (tvp);
1770 fhandler_base::fsync ()
1772 if (!get_handle () || nohandle ())
1777 if (pc.isdir ()) /* Just succeed. */
1779 if (FlushFileBuffers (get_handle ()))
1782 /* Ignore ERROR_INVALID_FUNCTION because FlushFileBuffers() always fails
1783 with this code on raw devices which are unbuffered by default. */
1784 DWORD errcode = GetLastError();
1785 if (errcode == ERROR_INVALID_FUNCTION)
1788 __seterrno_from_win_error (errcode);
1793 fhandler_base::fpathconf (int v)
1800 return pc.fs_is_ntfs () || pc.fs_is_samba () || pc.fs_is_nfs ()
1813 /* NAME_MAX is without trailing \0 */
1816 ret = NT_MAX_PATH - strlen (get_name ()) - 2;
1817 return ret < 0 ? 0 : ret > NAME_MAX ? NAME_MAX : ret;
1819 /* PATH_MAX is with trailing \0 */
1822 ret = NT_MAX_PATH - strlen (get_name ()) - 1;
1823 return ret < 0 ? 0 : ret > PATH_MAX ? PATH_MAX : ret;
1826 || get_device () == FH_FIFO || get_device () == FH_PIPE
1827 || get_device () == FH_PIPER || get_device () == FH_PIPEW)
1831 case _PC_CHOWN_RESTRICTED:
1837 return _POSIX_VDISABLE;
1845 case _PC_FILESIZEBITS:
1846 return FILESIZEBITS;
1847 case _PC_2_SYMLINKS:
1849 case _PC_SYMLINK_MAX:
1851 case _PC_POSIX_PERMISSIONS:
1852 case _PC_POSIX_SECURITY:
1853 if (get_device () == FH_FS)
1854 return pc.has_acls () || pc.fs_is_nfs ();
1864 /* Overlapped I/O */
1866 int __stdcall __attribute__ ((regparm (1)))
1867 fhandler_base_overlapped::setup_overlapped ()
1869 OVERLAPPED *ov = get_overlapped_buffer ();
1870 memset (ov, 0, sizeof (*ov));
1871 set_overlapped (ov);
1872 ov->hEvent = CreateEvent (&sec_none_nih, true, true, NULL);
1874 return ov->hEvent ? 0 : -1;
1877 void __stdcall __attribute__ ((regparm (1)))
1878 fhandler_base_overlapped::destroy_overlapped ()
1880 OVERLAPPED *ov = get_overlapped ();
1881 if (ov && ov->hEvent)
1883 CloseHandle (ov->hEvent);
1887 get_overlapped () = NULL;
1890 bool __stdcall __attribute__ ((regparm (1)))
1891 fhandler_base_overlapped::has_ongoing_io ()
1896 if (!IsEventSignalled (get_overlapped ()->hEvent))
1900 GetOverlappedResult (get_output_handle (), get_overlapped (), &nbytes, true);
1904 fhandler_base_overlapped::wait_return __stdcall __attribute__ ((regparm (3)))
1905 fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *bytes, bool nonblocking, DWORD len)
1907 if (!get_overlapped ())
1908 return inres ? overlapped_success : overlapped_error;
1910 wait_return res = overlapped_unknown;
1914 else if ((err = GetLastError ()) != ERROR_IO_PENDING)
1915 res = overlapped_error;
1916 else if (!nonblocking)
1919 SetEvent (get_overlapped ()->hEvent); /* Force immediate WFMO return */
1922 *bytes = len; /* Assume that this worked */
1923 io_pending = true; /* but don't allow subsequent */
1924 res = overlapped_success; /* writes until completed */
1926 if (res == overlapped_unknown)
1928 HANDLE w4[3] = { get_overlapped ()->hEvent, signal_arrived,
1929 pthread::get_cancel_event () };
1930 DWORD n = w4[2] ? 3 : 2;
1931 HANDLE h = writing ? get_output_handle () : get_handle ();
1932 DWORD wfres = WaitForMultipleObjects (n, w4, false, INFINITE);
1933 /* Cancelling here to prevent races. It's possible that the I/O has
1934 completed already, in which case this is a no-op. Otherwise,
1935 WFMO returned because 1) This is a non-blocking call, 2) a signal
1936 arrived, or 3) the operation was cancelled. These cases may be
1937 overridden by the return of GetOverlappedResult which could detect
1938 that I/O completion occurred. */
1940 BOOL wores = GetOverlappedResult (h, get_overlapped (), bytes, false);
1941 err = GetLastError ();
1942 ResetEvent (get_overlapped ()->hEvent); /* Probably not needed but CYA */
1943 debug_printf ("wfres %d, wores %d, bytes %u", wfres, wores, *bytes);
1945 res = overlapped_success; /* operation succeeded */
1946 else if (wfres == WAIT_OBJECT_0 + 1)
1948 if (_my_tls.call_signal_handler ())
1949 res = overlapped_signal;
1952 err = ERROR_INVALID_AT_INTERRUPT_TIME; /* forces an EINTR below */
1953 debug_printf ("unhandled signal");
1954 res = overlapped_error;
1957 else if (nonblocking)
1958 res = overlapped_nonblocking_no_data; /* more handling below */
1959 else if (wfres == WAIT_OBJECT_0 + 2)
1960 pthread::static_cancel_self (); /* never returns */
1963 debug_printf ("GetOverLappedResult failed, h %p, bytes %u, w4: %p, %p, %p %E", h, *bytes, w4[0], w4[1], w4[2]);
1964 res = overlapped_error;
1968 if (res == overlapped_success)
1969 debug_printf ("normal %s, %u bytes", writing ? "write" : "read", *bytes);
1970 else if (res == overlapped_signal)
1971 debug_printf ("handled signal");
1972 else if (res == overlapped_nonblocking_no_data)
1974 *bytes = (DWORD) -1;
1976 debug_printf ("no data to read for nonblocking I/O");
1978 else if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
1980 debug_printf ("EOF, %E");
1982 res = overlapped_success;
1983 if (writing && err == ERROR_BROKEN_PIPE)
1988 debug_printf ("res %u, Win32 Error %u", (unsigned) res, err);
1989 *bytes = (DWORD) -1;
1990 __seterrno_from_win_error (err);
1991 if (writing && err == ERROR_NO_DATA)
1998 void __stdcall __attribute__ ((regparm (3)))
1999 fhandler_base_overlapped::raw_read (void *ptr, size_t& len)
2005 bool res = ReadFile (get_handle (), ptr, len, &nbytes,
2007 switch (wait_overlapped (res, false, &nbytes, is_nonblocking ()))
2009 case overlapped_signal:
2010 keep_looping = true;
2012 default: /* Added to quiet gcc */
2013 case overlapped_success:
2014 case overlapped_error:
2015 keep_looping = false;
2019 while (keep_looping);
2020 len = (size_t) nbytes;
2023 ssize_t __stdcall __attribute__ ((regparm (3)))
2024 fhandler_base_overlapped::raw_write (const void *ptr, size_t len)
2027 if (has_ongoing_io ())
2030 nbytes = (DWORD) -1;
2035 if (!max_atomic_write || len < max_atomic_write)
2037 else if (is_nonblocking ())
2038 chunk = len = max_atomic_write;
2040 chunk = max_atomic_write;
2043 DWORD nbytes_now = 0;
2044 /* Write to fd in smaller chunks, accumlating a total.
2045 If there's an error, just return the accumulated total
2046 unless the first write fails, in which case return value
2047 from wait_overlapped(). */
2048 while (nbytes < len)
2050 size_t left = len - nbytes;
2056 bool res = WriteFile (get_output_handle (), ptr, len1, &nbytes_now,
2058 switch (wait_overlapped (res, true, &nbytes_now,
2059 is_nonblocking (), len1))
2061 case overlapped_success:
2062 ptr = ((char *) ptr) + chunk;
2063 nbytes += nbytes_now;
2064 /* fall through intentionally */
2065 case overlapped_signal:
2066 break; /* keep looping */
2067 case overlapped_error:
2068 len = 0; /* terminate loop */
2069 case overlapped_unknown:
2070 case overlapped_nonblocking_no_data:
2075 nbytes = nbytes_now;