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"
32 #define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
33 #define MIN_OVERLAPPED_WRITE_LEN (1 * 1024 * 1024)
35 static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
37 struct __cygwin_perfile *perfile_table;
40 fhandler_base::operator =(fhandler_base& x)
42 memcpy (this, &x, sizeof *this);
53 fhandler_base::puts_readahead (const char *s, size_t len)
56 while ((len == (size_t) -1 ? *s : len--)
57 && (success = put_readahead (*s++) > 0))
63 fhandler_base::put_readahead (char value)
66 if (raixput < rabuflen)
68 else if ((newrabuf = (char *) realloc (rabuf, rabuflen += 32)))
73 rabuf[raixput++] = value;
79 fhandler_base::get_readahead ()
83 chret = ((unsigned char) rabuf[raixget++]) & 0xff;
84 /* FIXME - not thread safe */
86 raixget = raixput = ralen = 0;
91 fhandler_base::peek_readahead (int queryput)
94 if (!queryput && raixget < ralen)
95 chret = ((unsigned char) rabuf[raixget]) & 0xff;
96 else if (queryput && raixput > 0)
97 chret = ((unsigned char) rabuf[raixput - 1]) & 0xff;
102 fhandler_base::set_readahead_valid (int val, int ch)
105 ralen = raixget = raixput = 0;
111 fhandler_base::eat_readahead (int n)
118 if ((int) (ralen -= n) < 0)
121 if (raixget >= ralen)
122 raixget = raixput = ralen = 0;
123 else if (raixput > ralen)
131 fhandler_base::get_readahead_into_buffer (char *buf, size_t buflen)
134 int copied_chars = 0;
137 if ((ch = get_readahead ()) < 0)
141 buf[copied_chars++] = (unsigned char)(ch & 0xff);
148 /* Record the file name. and name hash */
150 fhandler_base::set_name (path_conv &in_pc)
155 char *fhandler_base::get_proc_fd_name (char *buf)
158 return strcpy (buf, get_name ());
160 return strcpy (buf, dev ().name);
161 return strcpy (buf, "");
164 /* Detect if we are sitting at EOF for conditions where Windows
165 returns an error but UNIX doesn't. */
167 is_at_eof (HANDLE h, DWORD err)
170 FILE_POSITION_INFORMATION fpi;
171 FILE_STANDARD_INFORMATION fsi;
173 if (NT_SUCCESS (NtQueryInformationFile (h, &io, &fsi, sizeof fsi,
174 FileStandardInformation))
175 && NT_SUCCESS (NtQueryInformationFile (h, &io, &fpi, sizeof fpi,
176 FilePositionInformation))
177 && fsi.EndOfFile.QuadPart == fpi.CurrentByteOffset.QuadPart)
184 fhandler_base::set_flags (int flags, int supplied_bin)
188 debug_printf ("flags %p, supplied_bin %p", flags, supplied_bin);
189 if ((bin = flags & (O_BINARY | O_TEXT)))
190 debug_printf ("O_TEXT/O_BINARY set in flags %p", bin);
191 else if (rbinset () && wbinset ())
192 bin = rbinary () ? O_BINARY : O_TEXT; // FIXME: Not quite right
193 else if ((fmode = get_default_fmode (flags)) & O_BINARY)
195 else if (fmode & O_TEXT)
197 else if (supplied_bin)
200 bin = wbinary () || rbinary () ? O_BINARY : O_TEXT;
202 openflags = flags | bin;
205 rbinary (bin ? true : false);
206 wbinary (bin ? true : false);
207 syscall_printf ("filemode set to %s", bin ? "binary" : "text");
210 /* Normal file i/o handlers. */
212 /* Cover function to ReadFile to achieve (as much as possible) Posix style
213 semantics and use of errno. */
215 fhandler_base::raw_read (void *ptr, size_t& ulen)
217 #define bytes_read ulen
219 int try_noreserve = 1;
224 BOOL res = ReadFile (get_handle (), ptr, len, (DWORD *) &ulen, NULL);
227 /* Some errors are not really errors. Detect such cases here. */
229 DWORD errcode = GetLastError ();
232 case ERROR_BROKEN_PIPE:
233 /* This is really EOF. */
236 case ERROR_MORE_DATA:
237 /* `bytes_read' is supposedly valid. */
240 if (is_at_eof (get_handle (), errcode))
248 switch (mmap_is_attached_or_noreserve (ptr, len))
250 case MMAP_NORESERVE_COMMITED:
252 case MMAP_RAISE_SIGBUS:
259 case ERROR_INVALID_FUNCTION:
260 case ERROR_INVALID_PARAMETER:
261 case ERROR_INVALID_HANDLE:
265 bytes_read = (size_t) -1;
269 syscall_printf ("ReadFile %s(%p) failed, %E", get_name (), get_handle ());
270 __seterrno_from_win_error (errcode);
271 bytes_read = (size_t) -1;
278 /* Cover function to WriteFile to provide Posix interface and semantics
279 (as much as possible). */
280 static LARGE_INTEGER off_current = { QuadPart:FILE_USE_FILE_POINTER_POSITION };
281 static LARGE_INTEGER off_append = { QuadPart:FILE_WRITE_TO_END_OF_FILE };
284 fhandler_base::raw_write (const void *ptr, size_t len)
289 status = NtWriteFile (get_output_handle (), NULL, NULL, NULL, &io,
291 (get_flags () & O_APPEND) ? &off_append : &off_current,
293 if (!NT_SUCCESS (status))
295 __seterrno_from_nt_status (status);
296 if (get_errno () == EPIPE)
300 return io.Information;
304 fhandler_base::get_default_fmode (int flags)
309 size_t nlen = strlen (get_name ());
310 unsigned accflags = (flags & O_ACCMODE);
311 for (__cygwin_perfile *pf = perfile_table; pf->name; pf++)
312 if (!*pf->name && (pf->flags & O_ACCMODE) == accflags)
314 fmode = pf->flags & ~O_ACCMODE;
319 size_t pflen = strlen (pf->name);
320 const char *stem = get_name () + nlen - pflen;
321 if (pflen > nlen || (stem != get_name () && !isdirsep (stem[-1])))
323 else if ((pf->flags & O_ACCMODE) == accflags
324 && pathmatch (stem, pf->name, !!pc.objcaseinsensitive ()))
326 fmode = pf->flags & ~O_ACCMODE;
335 fhandler_base::device_access_denied (int flags)
341 if (flags & (O_WRONLY | O_APPEND))
346 return fhaccess (mode, true);
350 fhandler_base::fhaccess (int flags, bool effective)
355 set_errno (error ());
365 if (!(flags & (R_OK | W_OK | X_OK)))
368 if (is_fs_special ())
370 else if (has_attribute (FILE_ATTRIBUTE_READONLY) && (flags & W_OK)
373 else if (has_acls ())
375 res = check_file_access (pc, flags, effective);
378 else if (get_device () == FH_REGISTRY && open (O_RDONLY, 0) && get_handle ())
380 res = check_registry_access (get_handle (), flags, effective);
391 if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
393 if (!(st.st_mode & S_IRUSR))
396 else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
398 if (!(st.st_mode & S_IRGRP))
401 else if (!(st.st_mode & S_IROTH))
407 if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
409 if (!(st.st_mode & S_IWUSR))
412 else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
414 if (!(st.st_mode & S_IWGRP))
417 else if (!(st.st_mode & S_IWOTH))
423 if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
425 if (!(st.st_mode & S_IXUSR))
428 else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
430 if (!(st.st_mode & S_IXGRP))
433 else if (!(st.st_mode & S_IXOTH))
443 if (!res && (flags & W_OK) && get_device () == FH_FS
444 && (pc.fs_flags () & FILE_READ_ONLY_VOLUME))
449 debug_printf ("returning %d", res);
453 /* Open system call handler function. */
455 fhandler_base::open (int flags, mode_t mode)
459 ULONG file_attributes = 0;
460 ULONG shared = (get_major () == DEV_TAPE_MAJOR ? 0 : FILE_SHARE_VALID_FLAGS);
461 ULONG create_disposition;
462 ULONG create_options = FILE_OPEN_FOR_BACKUP_INTENT;
463 OBJECT_ATTRIBUTES attr;
466 PFILE_FULL_EA_INFORMATION p = NULL;
469 syscall_printf ("(%S, %p)", pc.get_nt_native_path (), flags);
471 pc.get_object_attr (attr, *sec_none_cloexec (flags));
473 switch (query_open ())
475 case query_read_control:
476 access = READ_CONTROL;
478 case query_read_attributes:
479 access = READ_CONTROL | FILE_READ_ATTRIBUTES;
481 case query_write_control:
482 access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
484 case query_write_dac:
485 access = READ_CONTROL | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
487 case query_write_attributes:
488 access = READ_CONTROL | FILE_WRITE_ATTRIBUTES;
491 if ((flags & O_ACCMODE) == O_RDONLY)
492 access = GENERIC_READ;
493 else if ((flags & O_ACCMODE) == O_WRONLY)
494 access = GENERIC_WRITE | READ_CONTROL | FILE_READ_ATTRIBUTES;
496 access = GENERIC_READ | GENERIC_WRITE;
498 create_options |= FILE_WRITE_THROUGH;
499 if (flags & O_DIRECT)
500 create_options |= FILE_NO_INTERMEDIATE_BUFFERING;
501 if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR)
503 create_options |= FILE_SYNCHRONOUS_IO_NONALERT;
504 access |= SYNCHRONIZE;
511 /* Make sure we can read EAs of files on an NFS share. Also make
512 sure that we're going to act on the file itself, even if it's a
514 access |= FILE_READ_EA;
517 if (query_open () >= query_write_control)
518 access |= FILE_WRITE_EA;
519 plen = sizeof nfs_aol_ffei;
520 p = (PFILE_FULL_EA_INFORMATION) &nfs_aol_ffei;
524 if ((flags & O_TRUNC) && ((flags & O_ACCMODE) != O_RDONLY))
527 create_disposition = FILE_OVERWRITE_IF;
529 create_disposition = FILE_OVERWRITE;
531 else if (flags & O_CREAT)
532 create_disposition = FILE_OPEN_IF;
534 create_disposition = FILE_OPEN;
536 if ((flags & O_EXCL) && (flags & O_CREAT))
537 create_disposition = FILE_CREATE;
539 if (get_device () == FH_FS)
541 /* Add the reparse point flag to native symlinks, otherwise we open the
542 target, not the symlink. This would break lstat. */
543 if (pc.is_rep_symlink ())
544 create_options |= FILE_OPEN_REPARSE_POINT;
546 /* Starting with Windows 2000, when trying to overwrite an already
547 existing file with FILE_ATTRIBUTE_HIDDEN and/or FILE_ATTRIBUTE_SYSTEM
548 attribute set, CreateFile fails with ERROR_ACCESS_DENIED.
549 Per MSDN you have to create the file with the same attributes as
550 already specified for the file. */
551 if (((flags & O_CREAT) || create_disposition == FILE_OVERWRITE)
552 && has_attribute (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
553 file_attributes |= pc.file_attributes ();
557 file_attributes |= FILE_ATTRIBUTE_NORMAL;
561 /* When creating a file on an NFS share, we have to set the
562 file mode by writing a NFS fattr3 structure with the
563 correct mode bits set. */
564 access |= FILE_WRITE_EA;
565 plen = sizeof (FILE_FULL_EA_INFORMATION) + sizeof (NFS_V3_ATTR)
567 p = (PFILE_FULL_EA_INFORMATION) alloca (plen);
568 p->NextEntryOffset = 0;
570 p->EaNameLength = sizeof (NFS_V3_ATTR) - 1;
571 p->EaValueLength = sizeof (fattr3);
572 strcpy (p->EaName, NFS_V3_ATTR);
573 fattr3 *nfs_attr = (fattr3 *) (p->EaName
574 + p->EaNameLength + 1);
575 memset (nfs_attr, 0, sizeof (fattr3));
576 nfs_attr->type = NF3REG;
577 nfs_attr->mode = mode;
579 else if (!has_acls () && !(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
580 /* If mode has no write bits set, and ACLs are not used, we set
581 the DOS R/O attribute. */
582 file_attributes |= FILE_ATTRIBUTE_READONLY;
583 else if (!exists () && has_acls ())
584 /* If we are about to create the file and the filesystem supports
585 ACLs, we will overwrite the DACL after the call to NtCreateFile.
586 This requires a handle with additional WRITE_DAC access,
587 otherwise set_file_sd has to open the file again. */
590 /* The file attributes are needed for later use in, e.g. fchmod. */
591 pc.file_attributes (file_attributes);
595 status = NtCreateFile (&fh, access, &attr, &io, NULL, file_attributes, shared,
596 create_disposition, create_options, p, plen);
597 if (!NT_SUCCESS (status))
599 /* Trying to create a directory should return EISDIR, not ENOENT. */
600 PUNICODE_STRING upath = pc.get_nt_native_path ();
601 if (status == STATUS_OBJECT_NAME_INVALID && (flags & O_CREAT)
602 && upath->Buffer[upath->Length / sizeof (WCHAR) - 1] == '\\')
605 __seterrno_from_nt_status (status);
610 /* Always create files using a NULL SD. Create correct permission bits
611 afterwards, maintaining the owner and group information just like chmod.
613 This is done for two reasons.
615 On Windows filesystems we need to create the file with default
616 permissions to allow inheriting ACEs. When providing an explicit DACL
617 in calls to [Nt]CreateFile, the created file will not inherit default
618 permissions from the parent object. This breaks not only Windows
619 inheritance, but also POSIX ACL inheritance.
621 Another reason to do this are remote shares. Files on a remote share
622 are created as the user used for authentication. In a domain that's
623 usually the user you're logged in as. Outside of a domain you're
624 authenticating using a local user account on the sharing machine.
625 If the SIDs of the client machine are used, that's entirely
626 unexpected behaviour. Doing it like we do here creates the expected SD
627 in a domain as well as on standalone servers.
628 This is the result of a discussion on the samba-technical list, starting at
629 http://lists.samba.org/archive/samba-technical/2008-July/060247.html */
630 if (io.Information == FILE_CREATED && has_acls ())
631 set_file_attribute (fh, pc, ILLEGAL_UID, ILLEGAL_GID, S_JUSTCREATED | mode);
634 set_flags (flags, pc.binmode ());
639 debug_printf ("%x = NtCreateFile "
640 "(%p, %x, %S, io, NULL, %x, %x, %x, %x, NULL, 0)",
641 status, fh, access, pc.get_nt_native_path (), file_attributes,
642 shared, create_disposition, create_options);
644 syscall_printf ("%d = fhandler_base::open (%S, %p)",
645 res, pc.get_nt_native_path (), flags);
650 open buffer in binary mode? Just do the read.
652 open buffer in text mode? Scan buffer for control zs and handle
653 the first one found. Then scan buffer, converting every \r\n into
654 an \n. If last char is an \r, look ahead one more char, if \n then
655 modify \r, if not, remember char.
658 fhandler_base::read (void *in_ptr, size_t& len)
660 char *ptr = (char *) in_ptr;
661 ssize_t copied_chars = get_readahead_into_buffer (ptr, len);
663 if (copied_chars && is_slow ())
665 len = (size_t) copied_chars;
672 len = (size_t) copied_chars;
676 raw_read (ptr + copied_chars, len);
679 else if ((ssize_t) len > 0)
684 if (rbinary () || (ssize_t) len <= 0)
687 /* Scan buffer and turn \r\n into \n */
688 char *src, *dst, *end;
693 /* Read up to the last but one char - the last char needs special handling */
696 if (*src == '\r' && src[1] == '\n')
701 /* If not beyond end and last char is a '\r' then read one more
702 to see if we should translate this one too */
705 else if (*src != '\r')
711 raw_read (&c1, c1len);
718 set_readahead_valid (1, c1);
723 len = dst - (char *) ptr;
726 if (strace.active ())
728 char buf[16 * 6 + 1];
731 for (int i = 0; i < copied_chars && i < 16; ++i)
733 unsigned char c = ((unsigned char *) ptr)[i];
734 __small_sprintf (p, " %c", c);
738 debug_printf ("read %d bytes (%s%s)", copied_chars, buf,
739 copied_chars > 16 ? " ..." : "");
744 debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text");
748 fhandler_base::write (const void *ptr, size_t len)
752 FILE_POSITION_INFORMATION fpi;
753 FILE_STANDARD_INFORMATION fsi;
757 did_lseek (false); /* don't do it again */
759 if (!(get_flags () & O_APPEND)
760 && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
761 &io, &fsi, sizeof fsi,
762 FileStandardInformation))
763 && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
764 &io, &fpi, sizeof fpi,
765 FilePositionInformation))
766 && fpi.CurrentByteOffset.QuadPart
767 >= fsi.EndOfFile.QuadPart + (128 * 1024)
768 && (pc.fs_flags () & FILE_SUPPORTS_SPARSE_FILES))
770 /* If the file system supports sparse files and the application
771 is writing after a long seek beyond EOF, convert the file to
774 status = NtFsControlFile (get_output_handle (), NULL, NULL, NULL,
775 &io, FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
776 syscall_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
777 status, pc.get_nt_native_path ());
783 debug_printf ("binary write");
784 res = raw_write (ptr, len);
788 debug_printf ("text write");
789 /* This is the Microsoft/DJGPP way. Still not ideal, but it's
791 Modified slightly by CGF 2000-10-07 */
793 int left_in_data = len;
794 char *data = (char *)ptr;
797 while (left_in_data > 0)
799 char buf[CHUNK_SIZE + 1], *buf_ptr = buf;
800 int left_in_buf = CHUNK_SIZE;
802 while (left_in_buf > 0 && left_in_data > 0)
813 if (left_in_data > 0 && ch == '\r' && *data == '\n')
815 *buf_ptr++ = *data++;
821 /* We've got a buffer-full, or we're out of data. Write it out */
823 int want = buf_ptr - buf;
824 if ((nbytes = raw_write (buf, want)) == want)
826 /* Keep track of how much written not counting additional \r's */
827 res = data - (char *)ptr;
832 res = -1; /* Error */
834 res += nbytes; /* Partial write. Return total bytes written. */
835 break; /* All done */
843 fhandler_base::readv (const struct iovec *const iov, const int iovcnt,
847 assert (iovcnt >= 1);
853 read (iov->iov_base, len);
857 if (tot == -1) // i.e. if not pre-calculated by the caller.
860 const struct iovec *iovptr = iov + iovcnt;
864 len += iovptr->iov_len;
866 while (iovptr != iov);
872 char *buf = (char *) malloc (len);
881 ssize_t nbytes = (ssize_t) len;
883 const struct iovec *iovptr = iov;
888 const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
889 memcpy (iovptr->iov_base, p, frag);
900 fhandler_base::writev (const struct iovec *const iov, const int iovcnt,
904 assert (iovcnt >= 1);
907 return write (iov->iov_base, iov->iov_len);
909 if (tot == -1) // i.e. if not pre-calculated by the caller.
912 const struct iovec *iovptr = iov + iovcnt;
916 tot += iovptr->iov_len;
918 while (iovptr != iov);
926 char *const buf = (char *) malloc (tot);
935 const struct iovec *iovptr = iov;
940 const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
941 memcpy (bufptr, iovptr->iov_base, frag);
946 ssize_t ret = write (buf, tot);
952 fhandler_base::lseek (_off64_t offset, int whence)
956 FILE_POSITION_INFORMATION fpi;
957 FILE_STANDARD_INFORMATION fsi;
959 /* Seeks on text files is tough, we rewind and read till we get to the
962 if (whence != SEEK_CUR || offset != 0)
964 if (whence == SEEK_CUR)
965 offset -= ralen - raixget;
966 set_readahead_valid (0);
972 fpi.CurrentByteOffset.QuadPart = offset;
975 status = NtQueryInformationFile (get_handle (), &io, &fpi, sizeof fpi,
976 FilePositionInformation);
977 if (!NT_SUCCESS (status))
979 __seterrno_from_nt_status (status);
982 fpi.CurrentByteOffset.QuadPart += offset;
984 default: /* SEEK_END */
985 status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
986 FileStandardInformation);
987 if (!NT_SUCCESS (status))
989 __seterrno_from_nt_status (status);
992 fpi.CurrentByteOffset.QuadPart = fsi.EndOfFile.QuadPart + offset;
996 debug_printf ("setting file pointer to %U", fpi.CurrentByteOffset.QuadPart);
997 status = NtSetInformationFile (get_handle (), &io, &fpi, sizeof fpi,
998 FilePositionInformation);
999 if (!NT_SUCCESS (status))
1001 __seterrno_from_nt_status (status);
1004 _off64_t res = fpi.CurrentByteOffset.QuadPart;
1006 /* When next we write(), we will check to see if *this* seek went beyond
1007 the end of the file and if so, potentially sparsify the file. */
1010 /* If this was a SEEK_CUR with offset 0, we still might have
1011 readahead that we have to take into account when calculating
1012 the actual position for the application. */
1013 if (whence == SEEK_CUR)
1014 res -= ralen - raixget;
1020 fhandler_base::pread (void *, size_t, _off64_t)
1027 fhandler_base::pwrite (void *, size_t, _off64_t)
1034 fhandler_base::close ()
1038 syscall_printf ("closing '%s' handle %p", get_name (), get_handle ());
1039 /* Delete all POSIX locks on the file. Delete all flock locks on the
1040 file if this is the last reference to this file. */
1042 del_my_locks (on_close);
1043 if (nohandle () || CloseHandle (get_handle ()))
1047 paranoid_printf ("CloseHandle (%d <%s>) failed", get_handle (),
1057 fhandler_base_overlapped::close ()
1059 if (is_nonblocking () && io_pending)
1062 wait_overlapped (1, !!(get_access () & GENERIC_WRITE), &bytes, false);
1064 destroy_overlapped ();
1065 return fhandler_base::close ();
1069 fhandler_base::ioctl (unsigned int cmd, void *buf)
1076 set_nonblocking (*(int *) buf);
1085 syscall_printf ("%d = ioctl (%x, %p)", res, cmd, buf);
1090 fhandler_base::lock (int, struct __flock64 *)
1097 fhandler_base::fstat (struct __stat64 *buf)
1099 debug_printf ("here");
1101 if (is_fs_special ())
1102 return fstat_fs (buf);
1104 switch (get_device ())
1107 buf->st_mode = S_IFIFO | S_IRUSR | S_IWUSR;
1110 buf->st_mode = S_IFIFO | S_IWUSR;
1113 buf->st_mode = S_IFIFO | S_IRUSR;
1116 buf->st_mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
1119 buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
1123 buf->st_uid = geteuid32 ();
1124 buf->st_gid = getegid32 ();
1126 buf->st_blksize = PREFERRED_IO_BLKSIZE;
1128 buf->st_ctim.tv_sec = 1164931200L; /* Arbitrary value: 2006-12-01 */
1129 buf->st_ctim.tv_nsec = 0L;
1130 buf->st_birthtim = buf->st_ctim;
1131 buf->st_mtim.tv_sec = time (NULL); /* Arbitrary value: current time,
1133 buf->st_mtim.tv_nsec = 0L;
1134 buf->st_atim = buf->st_mtim;
1140 fhandler_base::fstatvfs (struct statvfs *sfs)
1142 /* If we hit this base implementation, it's some device in /dev.
1143 Just call statvfs on /dev for simplicity. */
1144 path_conv pc ("/dev", PC_KEEP_HANDLE);
1145 fhandler_disk_file fh (pc);
1146 return fh.fstatvfs (sfs);
1150 fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
1154 a &= GENERIC_READ | GENERIC_WRITE;
1156 if (a == GENERIC_READ)
1158 else if (a == GENERIC_WRITE)
1160 else if (a == (GENERIC_READ | GENERIC_WRITE))
1162 set_flags (flags | bin);
1164 debug_printf ("created new fhandler_base for handle %p, bin %d", f, rbinary ());
1169 fhandler_base::dup (fhandler_base *child)
1171 debug_printf ("in fhandler_base dup");
1176 if (!DuplicateHandle (GetCurrentProcess (), get_handle (),
1177 GetCurrentProcess (), &nh,
1178 0, TRUE, DUPLICATE_SAME_ACCESS))
1180 debug_printf ("dup(%s) failed, handle %x, %E",
1181 get_name (), get_handle ());
1187 child->set_io_handle (nh);
1193 fhandler_base_overlapped::dup (fhandler_base *child)
1195 int res = fhandler_base::dup (child) ||
1196 ((fhandler_base_overlapped *) child)->setup_overlapped ();
1200 int fhandler_base::fcntl (int cmd, void *arg)
1207 res = close_on_exec () ? FD_CLOEXEC : 0;
1210 set_close_on_exec (((int) arg & FD_CLOEXEC) ? 1 : 0);
1215 debug_printf ("GETFL: %p", res);
1219 /* Only O_APPEND, O_ASYNC and O_NONBLOCK/O_NDELAY are allowed.
1220 Each other flag will be ignored.
1221 Since O_ASYNC isn't defined in fcntl.h it's currently
1223 const int allowed_flags = O_APPEND | O_NONBLOCK_MASK;
1224 int new_flags = (int) arg & allowed_flags;
1225 /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
1226 Set only the flag that has been passed in. If both are set, just
1227 record O_NONBLOCK. */
1228 if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
1229 new_flags &= ~OLD_O_NDELAY;
1230 set_flags ((get_flags () & ~allowed_flags) | new_flags);
1242 /* Base terminal handlers. These just return errors. */
1245 fhandler_base::tcflush (int)
1252 fhandler_base::tcsendbreak (int)
1259 fhandler_base::tcdrain ()
1266 fhandler_base::tcflow (int)
1273 fhandler_base::tcsetattr (int, const struct termios *)
1280 fhandler_base::tcgetattr (struct termios *)
1287 fhandler_base::tcsetpgrp (const pid_t)
1294 fhandler_base::tcgetpgrp ()
1301 fhandler_base::operator delete (void *p)
1306 /* Normal I/O constructor */
1307 fhandler_base::fhandler_base () :
1325 /* Normal I/O destructor */
1326 fhandler_base::~fhandler_base ()
1332 /**********************************************************************/
1335 fhandler_dev_null::fhandler_dev_null () :
1341 fhandler_base::set_no_inheritance (HANDLE &h, bool not_inheriting)
1343 if (!SetHandleInformation (h, HANDLE_FLAG_INHERIT,
1344 not_inheriting ? 0 : HANDLE_FLAG_INHERIT))
1345 debug_printf ("SetHandleInformation failed, %E");
1346 #ifdef DEBUGGING_AND_FDS_PROTECTED
1348 setclexec (oh, h, not_inheriting);
1353 fhandler_base::fork_fixup (HANDLE parent, HANDLE &h, const char *name)
1357 if (/* !is_socket () && */ !close_on_exec ())
1358 debug_printf ("handle %p already opened", h);
1359 else if (!DuplicateHandle (parent, h, GetCurrentProcess (), &h,
1360 0, !close_on_exec (), DUPLICATE_SAME_ACCESS))
1361 system_printf ("%s - %E, handle %s<%p>", get_name (), name, h);
1372 fhandler_base::set_close_on_exec (bool val)
1375 set_no_inheritance (io_handle, val);
1376 close_on_exec (val);
1377 debug_printf ("set close_on_exec for %s to %d", get_name (), val);
1381 fhandler_base::fixup_after_fork (HANDLE parent)
1383 debug_printf ("inheriting '%s' from parent", get_name ());
1385 fork_fixup (parent, io_handle, "io_handle");
1386 /* POSIX locks are not inherited across fork. */
1388 del_my_locks (after_fork);
1392 fhandler_base_overlapped::fixup_after_fork (HANDLE parent)
1394 setup_overlapped ();
1395 fhandler_base::fixup_after_fork (parent);
1399 fhandler_base::fixup_after_exec ()
1401 debug_printf ("here for '%s'", get_name ());
1402 if (unique_id && close_on_exec ())
1403 del_my_locks (after_exec);
1406 fhandler_base_overlapped::fixup_after_exec ()
1408 setup_overlapped ();
1409 fhandler_base::fixup_after_exec ();
1413 fhandler_base::is_nonblocking ()
1415 return (openflags & O_NONBLOCK_MASK) != 0;
1419 fhandler_base::set_nonblocking (int yes)
1421 int current = openflags & O_NONBLOCK_MASK;
1422 int new_flags = yes ? (!current ? O_NONBLOCK : current) : 0;
1423 openflags = (openflags & ~O_NONBLOCK_MASK) | new_flags;
1427 fhandler_base::mkdir (mode_t)
1437 fhandler_base::rmdir ()
1441 else if (!pc.isdir ())
1442 set_errno (ENOTDIR);
1449 fhandler_base::opendir (int fd)
1451 set_errno (ENOTDIR);
1456 fhandler_base::readdir (DIR *, dirent *)
1462 fhandler_base::telldir (DIR *)
1464 set_errno (ENOTDIR);
1469 fhandler_base::seekdir (DIR *, long)
1471 set_errno (ENOTDIR);
1475 fhandler_base::rewinddir (DIR *)
1477 set_errno (ENOTDIR);
1481 fhandler_base::closedir (DIR *)
1483 set_errno (ENOTDIR);
1488 fhandler_base::fchmod (mode_t mode)
1490 extern int chmod_device (path_conv& pc, mode_t mode);
1491 if (pc.is_fs_special ())
1492 return chmod_device (pc, mode);
1493 /* By default, just succeeds. */
1498 fhandler_base::fchown (__uid32_t uid, __gid32_t gid)
1500 if (pc.is_fs_special ())
1501 return ((fhandler_disk_file *) this)->fhandler_disk_file::fchown (uid, gid);
1502 /* By default, just succeeds. */
1507 fhandler_base::facl (int cmd, int nentries, __aclent32_t *aclbufp)
1513 /* By default, just succeeds. */
1519 else if (nentries < MIN_ACL_ENTRIES)
1523 aclbufp[0].a_type = USER_OBJ;
1524 aclbufp[0].a_id = myself->uid;
1525 aclbufp[0].a_perm = (S_IRUSR | S_IWUSR) >> 6;
1526 aclbufp[1].a_type = GROUP_OBJ;
1527 aclbufp[1].a_id = myself->gid;
1528 aclbufp[1].a_perm = (S_IRGRP | S_IWGRP) >> 3;
1529 aclbufp[2].a_type = OTHER_OBJ;
1530 aclbufp[2].a_id = ILLEGAL_GID;
1531 aclbufp[2].a_perm = S_IROTH | S_IWOTH;
1532 aclbufp[3].a_type = CLASS_OBJ;
1533 aclbufp[3].a_id = ILLEGAL_GID;
1534 aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
1535 res = MIN_ACL_ENTRIES;
1539 res = MIN_ACL_ENTRIES;
1549 fhandler_base::fgetxattr (const char *name, void *value, size_t size)
1551 set_errno (ENOTSUP);
1556 fhandler_base::fsetxattr (const char *name, const void *value, size_t size,
1559 set_errno (ENOTSUP);
1564 fhandler_base::fadvise (_off64_t offset, _off64_t length, int advice)
1571 fhandler_base::ftruncate (_off64_t length, bool allow_truncate)
1578 fhandler_base::link (const char *newpath)
1585 fhandler_base::utimens (const struct timespec *tvp)
1587 if (is_fs_special ())
1588 return utimens_fs (tvp);
1595 fhandler_base::fsync ()
1597 if (!get_handle () || nohandle ())
1602 if (pc.isdir ()) /* Just succeed. */
1604 if (FlushFileBuffers (get_handle ()))
1607 /* Ignore ERROR_INVALID_FUNCTION because FlushFileBuffers() always fails
1608 with this code on raw devices which are unbuffered by default. */
1609 DWORD errcode = GetLastError();
1610 if (errcode == ERROR_INVALID_FUNCTION)
1613 __seterrno_from_win_error (errcode);
1618 fhandler_base::fpathconf (int v)
1625 return pc.fs_is_ntfs () || pc.fs_is_samba () || pc.fs_is_nfs ()
1638 /* NAME_MAX is without trailing \0 */
1641 ret = NT_MAX_PATH - strlen (get_name ()) - 2;
1642 return ret < 0 ? 0 : ret > NAME_MAX ? NAME_MAX : ret;
1644 /* PATH_MAX is with trailing \0 */
1647 ret = NT_MAX_PATH - strlen (get_name ()) - 1;
1648 return ret < 0 ? 0 : ret > PATH_MAX ? PATH_MAX : ret;
1651 || get_device () == FH_FIFO || get_device () == FH_PIPE
1652 || get_device () == FH_PIPER || get_device () == FH_PIPEW)
1656 case _PC_CHOWN_RESTRICTED:
1662 return _POSIX_VDISABLE;
1670 case _PC_FILESIZEBITS:
1671 return FILESIZEBITS;
1672 case _PC_2_SYMLINKS:
1674 case _PC_SYMLINK_MAX:
1676 case _PC_POSIX_PERMISSIONS:
1677 case _PC_POSIX_SECURITY:
1678 if (get_device () == FH_FS)
1679 return pc.has_acls () || pc.fs_is_nfs ();
1689 /* Overlapped I/O */
1691 int __stdcall __attribute__ ((regparm (1)))
1692 fhandler_base_overlapped::setup_overlapped ()
1694 OVERLAPPED *ov = get_overlapped_buffer ();
1695 memset (ov, 0, sizeof (*ov));
1696 set_overlapped (ov);
1697 ov->hEvent = CreateEvent (&sec_none_nih, true, true, NULL);
1698 return ov->hEvent ? 0 : -1;
1701 void __stdcall __attribute__ ((regparm (1)))
1702 fhandler_base_overlapped::destroy_overlapped ()
1704 OVERLAPPED *ov = get_overlapped ();
1705 if (ov && ov->hEvent)
1707 CloseHandle (ov->hEvent);
1711 get_overlapped () = NULL;
1714 bool __stdcall __attribute__ ((regparm (1)))
1715 fhandler_base_overlapped::has_ongoing_io ()
1719 if (WaitForSingleObject (get_overlapped ()->hEvent, 0) != WAIT_OBJECT_0)
1728 fhandler_base_overlapped::wait_return __stdcall __attribute__ ((regparm (3)))
1729 fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *bytes, bool nonblocking, DWORD len)
1731 if (!get_overlapped ())
1732 return inres ? overlapped_success : overlapped_error;
1735 DWORD err = GetLastError ();
1736 if (err == ERROR_NO_SYSTEM_RESOURCES)
1737 res = overlapped_fallback;
1738 else if (nonblocking)
1740 if (!inres && err != ERROR_IO_PENDING)
1741 res = overlapped_error;
1744 io_pending = err == ERROR_IO_PENDING;
1745 if (writing && !inres)
1747 res = overlapped_success;
1751 else if (!inres && err != ERROR_IO_PENDING)
1752 res = overlapped_error;
1756 if (!get_overlapped ()->hEvent)
1757 system_printf ("hEvent is zero?");
1761 w4[0] = get_overlapped ()->hEvent;
1762 if (&_my_tls == _main_tls)
1763 w4[n++] = signal_arrived;
1764 HANDLE h = writing ? get_output_handle () : get_handle ();
1765 DWORD wfres = WaitForMultipleObjects (n, w4, false, INFINITE);
1766 if (wfres != WAIT_OBJECT_0)
1769 BOOL wores = GetOverlappedResult (h, get_overlapped (), bytes, false);
1770 bool signalled = !wores && (wfres == WAIT_OBJECT_0 + 1);
1773 debug_printf ("got a signal");
1774 if (_my_tls.call_signal_handler ())
1775 res = overlapped_signal;
1779 res = overlapped_error;
1781 *bytes = (DWORD) -1;
1786 err = GetLastError ();
1787 debug_printf ("GetOverLappedResult failed, bytes %u", *bytes);
1788 res = overlapped_error;
1793 debug_printf ("normal %s, %u bytes", writing ? "write" : "read", *bytes);
1794 res = overlapped_success;
1799 /* nothing to do */;
1800 else if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
1802 debug_printf ("EOF");
1804 res = overlapped_success;
1808 debug_printf ("err %u", err);
1809 __seterrno_from_win_error (err);
1810 *bytes = (DWORD) -1;
1813 if (writing && (err == ERROR_NO_DATA || err == ERROR_BROKEN_PIPE))
1818 void __stdcall __attribute__ ((regparm (3)))
1819 fhandler_base_overlapped::read_overlapped (void *ptr, size_t& len)
1822 if (has_ongoing_io ())
1823 nbytes = (DWORD) -1;
1829 bool res = ReadFile (get_handle (), ptr, len, &nbytes,
1831 switch (wait_overlapped (res, false, &nbytes, is_nonblocking ()))
1833 case overlapped_signal:
1834 keep_looping = true;
1836 default: /* Added to quiet gcc */
1837 case overlapped_success:
1838 case overlapped_error:
1839 case overlapped_fallback:
1840 keep_looping = false;
1844 while (keep_looping);
1846 len = (size_t) nbytes;
1849 ssize_t __stdcall __attribute__ ((regparm (3)))
1850 fhandler_base_overlapped::write_overlapped (const void *ptr, size_t len)
1853 if (has_ongoing_io ())
1854 nbytes = (DWORD) -1;
1857 int last_errno = get_errno ();
1859 if (is_nonblocking () && max_atomic_write && len > max_atomic_write)
1860 len = max_atomic_write;
1863 bool res = WriteFile (get_output_handle (), ptr, len, &nbytes,
1865 switch (wait_overlapped (res, true, &nbytes, is_nonblocking (), (size_t) len))
1867 case overlapped_signal:
1868 keep_looping = true;
1870 case overlapped_fallback:
1871 set_errno (last_errno); /* Avoid setting a random EFBIG errno */
1872 nbytes = write_overlapped_fallback (ptr, len);
1873 /* fall through intentionally */;
1874 default: /* Added to quiet gcc */
1875 case overlapped_success:
1876 case overlapped_error:
1877 keep_looping = false;
1881 while (keep_looping);
1883 debug_printf ("returning %u", nbytes);
1887 /* On XP (at least) the size of the buffer that can be used to write to a pipe
1888 (pipes are currently the only thing using the overlapped methods) is
1889 limited. This function is a fallback for when that problem is detected.
1890 It writes to the pipe using smaller buffers but masks this behavior
1892 ssize_t __stdcall __attribute__ ((regparm (3)))
1893 fhandler_base_overlapped::write_overlapped_fallback (const void *ptr, size_t orig_len)
1896 /* So far, in testing, only the first if test has been necessary */
1897 if (orig_len > MAX_OVERLAPPED_WRITE_LEN)
1898 chunk = MAX_OVERLAPPED_WRITE_LEN;
1899 else if (orig_len > MIN_OVERLAPPED_WRITE_LEN)
1900 chunk = MIN_OVERLAPPED_WRITE_LEN;
1902 chunk = orig_len / 4;
1904 DWORD nbytes_now = 0;
1905 /* Write to fd in smaller chunks, accumlating a total.
1906 If there's an error, just return the accumulated total
1907 unless the first write fails, in which case return value
1908 from wait_overlapped(). */
1909 while ((size_t) nbytes < orig_len)
1911 size_t left = orig_len - nbytes;
1917 bool res = WriteFile (get_output_handle (), ptr, len, &nbytes_now,
1919 /* The nonblocking case is not going to be used currently and may
1920 eventually disappear. */
1921 switch (wait_overlapped (res, true, &nbytes_now,
1922 left <= chunk ? is_nonblocking () : false,
1925 case overlapped_success:
1926 nbytes += nbytes_now;
1927 /* fall through intentionally */
1928 case overlapped_signal:
1929 break; /* keep looping */
1930 case overlapped_error:
1931 case overlapped_fallback: /* XXX Could make this more adaptive
1933 orig_len = 0; /* terminate loop */
1938 nbytes = nbytes_now;