1 //===-- File.cpp ------------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Host/File.h"
19 #include "lldb/Host/windows/windows.h"
21 #include <sys/ioctl.h>
24 #include "llvm/Support/ConvertUTF.h"
25 #include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors()
27 #include "lldb/Core/DataBufferHeap.h"
28 #include "lldb/Core/Error.h"
29 #include "lldb/Core/Log.h"
30 #include "lldb/Host/Config.h"
31 #include "lldb/Host/FileSpec.h"
32 #include "lldb/Host/FileSystem.h"
35 using namespace lldb_private;
38 GetStreamOpenModeFromOptions (uint32_t options)
40 if (options & File::eOpenOptionAppend)
42 if (options & File::eOpenOptionRead)
44 if (options & File::eOpenOptionCanCreateNewOnly)
49 else if (options & File::eOpenOptionWrite)
51 if (options & File::eOpenOptionCanCreateNewOnly)
57 else if (options & File::eOpenOptionRead && options & File::eOpenOptionWrite)
59 if (options & File::eOpenOptionCanCreate)
61 if (options & File::eOpenOptionCanCreateNewOnly)
69 else if (options & File::eOpenOptionRead)
73 else if (options & File::eOpenOptionWrite)
80 int File::kInvalidDescriptor = -1;
81 FILE * File::kInvalidStream = NULL;
83 File::File(const char *path, uint32_t options, uint32_t permissions) :
84 IOObject(eFDTypeFile, false),
85 m_descriptor (kInvalidDescriptor),
86 m_stream (kInvalidStream),
89 m_is_interactive (eLazyBoolCalculate),
90 m_is_real_terminal (eLazyBoolCalculate)
92 Open (path, options, permissions);
95 File::File (const FileSpec& filespec,
97 uint32_t permissions) :
98 IOObject(eFDTypeFile, false),
99 m_descriptor (kInvalidDescriptor),
100 m_stream (kInvalidStream),
102 m_own_stream (false),
103 m_is_interactive (eLazyBoolCalculate),
104 m_is_real_terminal (eLazyBoolCalculate)
109 Open (filespec.GetPath().c_str(), options, permissions);
120 File::GetDescriptor() const
122 if (DescriptorIsValid())
125 // Don't open the file descriptor if we don't need to, just get it from the
126 // stream if we have one.
129 #if defined(LLVM_ON_WIN32)
130 return _fileno(m_stream);
132 return fileno(m_stream);
136 // Invalid descriptor and invalid stream, return invalid descriptor.
137 return kInvalidDescriptor;
140 IOObject::WaitableHandle
141 File::GetWaitableHandle()
148 File::SetDescriptor (int fd, bool transfer_ownership)
153 m_should_close_fd = transfer_ownership;
160 if (!StreamIsValid())
162 if (DescriptorIsValid())
164 const char *mode = GetStreamOpenModeFromOptions (m_options);
167 if (!m_should_close_fd)
169 // We must duplicate the file descriptor if we don't own it because
170 // when you call fdopen, the stream will own the fd
172 m_descriptor = ::_dup(GetDescriptor());
174 m_descriptor = dup(GetDescriptor());
176 m_should_close_fd = true;
181 m_stream = ::fdopen (m_descriptor, mode);
182 } while (m_stream == NULL && errno == EINTR);
184 // If we got a stream, then we own the stream and should no
185 // longer own the descriptor because fclose() will close it for us
190 m_should_close_fd = false;
199 File::SetStream (FILE *fh, bool transfer_ownership)
204 m_own_stream = transfer_ownership;
208 File::Open (const char *path, uint32_t options, uint32_t permissions)
215 const bool read = options & eOpenOptionRead;
216 const bool write = options & eOpenOptionWrite;
224 if (options & eOpenOptionAppend)
227 if (options & eOpenOptionTruncate)
230 if (options & eOpenOptionCanCreate)
233 if (options & eOpenOptionCanCreateNewOnly)
234 oflag |= O_CREAT | O_EXCL;
241 if (options & eOpenOptionDontFollowSymlinks)
247 if (options & eOpenOptionNonBlocking)
249 if (options & eOpenOptionCloseOnExec)
258 if (permissions & lldb::eFilePermissionsUserRead) mode |= S_IRUSR;
259 if (permissions & lldb::eFilePermissionsUserWrite) mode |= S_IWUSR;
260 if (permissions & lldb::eFilePermissionsUserExecute) mode |= S_IXUSR;
261 if (permissions & lldb::eFilePermissionsGroupRead) mode |= S_IRGRP;
262 if (permissions & lldb::eFilePermissionsGroupWrite) mode |= S_IWGRP;
263 if (permissions & lldb::eFilePermissionsGroupExecute) mode |= S_IXGRP;
264 if (permissions & lldb::eFilePermissionsWorldRead) mode |= S_IROTH;
265 if (permissions & lldb::eFilePermissionsWorldWrite) mode |= S_IWOTH;
266 if (permissions & lldb::eFilePermissionsWorldExecute) mode |= S_IXOTH;
273 if (!llvm::ConvertUTF8toWide(path, wpath))
276 error.SetErrorString("Error converting path to UTF-16");
279 ::_wsopen_s(&m_descriptor, wpath.c_str(), oflag, _SH_DENYNO, mode);
281 m_descriptor = ::open(path, oflag, mode);
283 } while (m_descriptor < 0 && errno == EINTR);
285 if (!DescriptorIsValid())
286 error.SetErrorToErrno();
289 m_should_close_fd = true;
297 File::GetPermissions(const FileSpec &file_spec, Error &error)
301 struct stat file_stats;
302 int stat_result = FileSystem::Stat(file_spec.GetCString(), &file_stats);
303 if (stat_result == -1)
304 error.SetErrorToErrno();
308 return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
312 error.SetErrorString ("empty file spec");
317 File::GetPermissions(Error &error) const
319 int fd = GetDescriptor();
320 if (fd != kInvalidDescriptor)
322 struct stat file_stats;
323 if (::fstat (fd, &file_stats) == -1)
324 error.SetErrorToErrno();
328 return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
333 error.SetErrorString ("invalid file descriptor");
343 if (StreamIsValid() && m_own_stream)
345 if (::fclose (m_stream) == EOF)
346 error.SetErrorToErrno();
349 if (DescriptorIsValid() && m_should_close_fd)
351 if (::close (m_descriptor) != 0)
352 error.SetErrorToErrno();
354 m_descriptor = kInvalidDescriptor;
355 m_stream = kInvalidStream;
357 m_own_stream = false;
358 m_should_close_fd = false;
359 m_is_interactive = eLazyBoolCalculate;
360 m_is_real_terminal = eLazyBoolCalculate;
370 m_own_stream = false;
371 m_is_interactive = m_supports_colors = m_is_real_terminal = eLazyBoolCalculate;
375 File::GetFileSpec (FileSpec &file_spec) const
378 #ifdef LLDB_CONFIG_FCNTL_GETPATH_SUPPORTED
382 if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1)
383 error.SetErrorToErrno();
385 file_spec.SetFile (path, false);
389 error.SetErrorString("invalid file handle");
391 #elif defined(__linux__)
394 if (::snprintf(proc, sizeof(proc), "/proc/self/fd/%d", GetDescriptor()) < 0)
395 error.SetErrorString ("cannot resolve file descriptor");
399 if ((len = ::readlink(proc, path, sizeof(path) - 1)) == -1)
400 error.SetErrorToErrno();
404 file_spec.SetFile (path, false);
408 error.SetErrorString ("File::GetFileSpec is not supported on this platform");
417 File::SeekFromStart (off_t offset, Error *error_ptr)
420 if (DescriptorIsValid())
422 result = ::lseek (m_descriptor, offset, SEEK_SET);
427 error_ptr->SetErrorToErrno();
432 else if (StreamIsValid ())
434 result = ::fseek(m_stream, offset, SEEK_SET);
439 error_ptr->SetErrorToErrno();
446 error_ptr->SetErrorString("invalid file handle");
452 File::SeekFromCurrent (off_t offset, Error *error_ptr)
455 if (DescriptorIsValid())
457 result = ::lseek (m_descriptor, offset, SEEK_CUR);
462 error_ptr->SetErrorToErrno();
467 else if (StreamIsValid ())
469 result = ::fseek(m_stream, offset, SEEK_CUR);
474 error_ptr->SetErrorToErrno();
481 error_ptr->SetErrorString("invalid file handle");
487 File::SeekFromEnd (off_t offset, Error *error_ptr)
490 if (DescriptorIsValid())
492 result = ::lseek (m_descriptor, offset, SEEK_END);
497 error_ptr->SetErrorToErrno();
502 else if (StreamIsValid ())
504 result = ::fseek(m_stream, offset, SEEK_END);
509 error_ptr->SetErrorToErrno();
516 error_ptr->SetErrorString("invalid file handle");
530 err = ::fflush (m_stream);
531 } while (err == EOF && errno == EINTR);
534 error.SetErrorToErrno();
536 else if (!DescriptorIsValid())
538 error.SetErrorString("invalid file handle");
548 if (DescriptorIsValid())
551 int err = FlushFileBuffers((HANDLE)_get_osfhandle(m_descriptor));
553 error.SetErrorToGenericError();
558 err = ::fsync (m_descriptor);
559 } while (err == -1 && errno == EINTR);
562 error.SetErrorToErrno();
567 error.SetErrorString("invalid file handle");
572 #if defined (__APPLE__)
573 // Darwin kernels only can read/write <= INT_MAX bytes
574 #define MAX_READ_SIZE INT_MAX
575 #define MAX_WRITE_SIZE INT_MAX
579 File::Read (void *buf, size_t &num_bytes)
583 #if defined (MAX_READ_SIZE)
584 if (num_bytes > MAX_READ_SIZE)
586 uint8_t *p = (uint8_t *)buf;
587 size_t bytes_left = num_bytes;
588 // Init the num_bytes read to zero
591 while (bytes_left > 0)
593 size_t curr_num_bytes;
594 if (bytes_left > MAX_READ_SIZE)
595 curr_num_bytes = MAX_READ_SIZE;
597 curr_num_bytes = bytes_left;
599 error = Read (p + num_bytes, curr_num_bytes);
601 // Update how many bytes were read
602 num_bytes += curr_num_bytes;
603 if (bytes_left < curr_num_bytes)
606 bytes_left -= curr_num_bytes;
615 ssize_t bytes_read = -1;
616 if (DescriptorIsValid())
620 bytes_read = ::read (m_descriptor, buf, num_bytes);
621 } while (bytes_read < 0 && errno == EINTR);
623 if (bytes_read == -1)
625 error.SetErrorToErrno();
629 num_bytes = bytes_read;
631 else if (StreamIsValid())
633 bytes_read = ::fread (buf, 1, num_bytes, m_stream);
637 if (::feof(m_stream))
638 error.SetErrorString ("feof");
639 else if (::ferror (m_stream))
640 error.SetErrorString ("ferror");
644 num_bytes = bytes_read;
649 error.SetErrorString("invalid file handle");
655 File::Write (const void *buf, size_t &num_bytes)
659 #if defined (MAX_WRITE_SIZE)
660 if (num_bytes > MAX_WRITE_SIZE)
662 const uint8_t *p = (const uint8_t *)buf;
663 size_t bytes_left = num_bytes;
664 // Init the num_bytes written to zero
667 while (bytes_left > 0)
669 size_t curr_num_bytes;
670 if (bytes_left > MAX_WRITE_SIZE)
671 curr_num_bytes = MAX_WRITE_SIZE;
673 curr_num_bytes = bytes_left;
675 error = Write (p + num_bytes, curr_num_bytes);
677 // Update how many bytes were read
678 num_bytes += curr_num_bytes;
679 if (bytes_left < curr_num_bytes)
682 bytes_left -= curr_num_bytes;
691 ssize_t bytes_written = -1;
692 if (DescriptorIsValid())
696 bytes_written = ::write (m_descriptor, buf, num_bytes);
697 } while (bytes_written < 0 && errno == EINTR);
699 if (bytes_written == -1)
701 error.SetErrorToErrno();
705 num_bytes = bytes_written;
707 else if (StreamIsValid())
709 bytes_written = ::fwrite (buf, 1, num_bytes, m_stream);
711 if (bytes_written == 0)
713 if (::feof(m_stream))
714 error.SetErrorString ("feof");
715 else if (::ferror (m_stream))
716 error.SetErrorString ("ferror");
720 num_bytes = bytes_written;
726 error.SetErrorString("invalid file handle");
734 File::Read (void *buf, size_t &num_bytes, off_t &offset)
738 #if defined (MAX_READ_SIZE)
739 if (num_bytes > MAX_READ_SIZE)
741 uint8_t *p = (uint8_t *)buf;
742 size_t bytes_left = num_bytes;
743 // Init the num_bytes read to zero
746 while (bytes_left > 0)
748 size_t curr_num_bytes;
749 if (bytes_left > MAX_READ_SIZE)
750 curr_num_bytes = MAX_READ_SIZE;
752 curr_num_bytes = bytes_left;
754 error = Read (p + num_bytes, curr_num_bytes, offset);
756 // Update how many bytes were read
757 num_bytes += curr_num_bytes;
758 if (bytes_left < curr_num_bytes)
761 bytes_left -= curr_num_bytes;
771 int fd = GetDescriptor();
772 if (fd != kInvalidDescriptor)
774 ssize_t bytes_read = -1;
777 bytes_read = ::pread (fd, buf, num_bytes, offset);
778 } while (bytes_read < 0 && errno == EINTR);
783 error.SetErrorToErrno();
787 offset += bytes_read;
788 num_bytes = bytes_read;
794 error.SetErrorString("invalid file handle");
797 long cur = ::lseek(m_descriptor, 0, SEEK_CUR);
798 SeekFromStart(offset);
799 error = Read(buf, num_bytes);
807 File::Read (size_t &num_bytes, off_t &offset, bool null_terminate, DataBufferSP &data_buffer_sp)
813 int fd = GetDescriptor();
814 if (fd != kInvalidDescriptor)
816 struct stat file_stats;
817 if (::fstat (fd, &file_stats) == 0)
819 if (file_stats.st_size > offset)
821 const size_t bytes_left = file_stats.st_size - offset;
822 if (num_bytes > bytes_left)
823 num_bytes = bytes_left;
825 size_t num_bytes_plus_nul_char = num_bytes + (null_terminate ? 1 : 0);
826 std::unique_ptr<DataBufferHeap> data_heap_ap;
827 data_heap_ap.reset(new DataBufferHeap());
828 data_heap_ap->SetByteSize(num_bytes_plus_nul_char);
830 if (data_heap_ap.get())
832 error = Read (data_heap_ap->GetBytes(), num_bytes, offset);
835 // Make sure we read exactly what we asked for and if we got
836 // less, adjust the array
837 if (num_bytes_plus_nul_char < data_heap_ap->GetByteSize())
838 data_heap_ap->SetByteSize(num_bytes_plus_nul_char);
839 data_buffer_sp.reset(data_heap_ap.release());
845 error.SetErrorString("file is empty");
848 error.SetErrorToErrno();
851 error.SetErrorString("invalid file handle");
854 error.SetErrorString("invalid file handle");
857 data_buffer_sp.reset();
862 File::Write (const void *buf, size_t &num_bytes, off_t &offset)
866 #if defined (MAX_WRITE_SIZE)
867 if (num_bytes > MAX_WRITE_SIZE)
869 const uint8_t *p = (const uint8_t *)buf;
870 size_t bytes_left = num_bytes;
871 // Init the num_bytes written to zero
874 while (bytes_left > 0)
876 size_t curr_num_bytes;
877 if (bytes_left > MAX_WRITE_SIZE)
878 curr_num_bytes = MAX_WRITE_SIZE;
880 curr_num_bytes = bytes_left;
882 error = Write (p + num_bytes, curr_num_bytes, offset);
884 // Update how many bytes were read
885 num_bytes += curr_num_bytes;
886 if (bytes_left < curr_num_bytes)
889 bytes_left -= curr_num_bytes;
898 int fd = GetDescriptor();
899 if (fd != kInvalidDescriptor)
902 ssize_t bytes_written = -1;
905 bytes_written = ::pwrite (m_descriptor, buf, num_bytes, offset);
906 } while (bytes_written < 0 && errno == EINTR);
908 if (bytes_written < 0)
911 error.SetErrorToErrno();
915 offset += bytes_written;
916 num_bytes = bytes_written;
919 long cur = ::lseek(m_descriptor, 0, SEEK_CUR);
920 error = Write(buf, num_bytes);
921 long after = ::lseek(m_descriptor, 0, SEEK_CUR);
932 error.SetErrorString("invalid file handle");
937 //------------------------------------------------------------------
938 // Print some formatted output to the stream.
939 //------------------------------------------------------------------
941 File::Printf (const char *format, ...)
944 va_start (args, format);
945 size_t result = PrintfVarArg (format, args);
950 //------------------------------------------------------------------
951 // Print some formatted output to the stream.
952 //------------------------------------------------------------------
954 File::PrintfVarArg (const char *format, va_list args)
957 if (DescriptorIsValid())
960 result = vasprintf(&s, format, args);
965 size_t s_len = result;
972 else if (StreamIsValid())
974 result = ::vfprintf (m_stream, format, args);
980 File::ConvertOpenOptionsForPOSIXOpen (uint32_t open_options)
983 if (open_options & eOpenOptionRead && open_options & eOpenOptionWrite)
985 else if (open_options & eOpenOptionWrite)
988 if (open_options & eOpenOptionAppend)
991 if (open_options & eOpenOptionTruncate)
994 if (open_options & eOpenOptionNonBlocking)
997 if (open_options & eOpenOptionCanCreateNewOnly)
998 mode |= O_CREAT | O_EXCL;
999 else if (open_options & eOpenOptionCanCreate)
1006 File::CalculateInteractiveAndTerminal ()
1008 const int fd = GetDescriptor();
1011 m_is_interactive = eLazyBoolNo;
1012 m_is_real_terminal = eLazyBoolNo;
1016 m_is_interactive = eLazyBoolYes;
1017 m_is_real_terminal = eLazyBoolYes;
1022 m_is_interactive = eLazyBoolYes;
1023 struct winsize window_size;
1024 if (::ioctl (fd, TIOCGWINSZ, &window_size) == 0)
1026 if (window_size.ws_col > 0)
1028 m_is_real_terminal = eLazyBoolYes;
1029 if (llvm::sys::Process::FileDescriptorHasColors(fd))
1030 m_supports_colors = eLazyBoolYes;
1039 File::GetIsInteractive ()
1041 if (m_is_interactive == eLazyBoolCalculate)
1042 CalculateInteractiveAndTerminal ();
1043 return m_is_interactive == eLazyBoolYes;
1047 File::GetIsRealTerminal ()
1049 if (m_is_real_terminal == eLazyBoolCalculate)
1050 CalculateInteractiveAndTerminal();
1051 return m_is_real_terminal == eLazyBoolYes;
1055 File::GetIsTerminalWithColors ()
1057 if (m_supports_colors == eLazyBoolCalculate)
1058 CalculateInteractiveAndTerminal();
1059 return m_supports_colors == eLazyBoolYes;