LLDB  mainline
File.cpp
Go to the documentation of this file.
1 //===-- File.cpp ----------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Host/File.h"
10 
11 #include <cerrno>
12 #include <climits>
13 #include <cstdarg>
14 #include <cstdio>
15 #include <fcntl.h>
16 
17 #ifdef _WIN32
19 #else
20 #include <sys/ioctl.h>
21 #include <sys/stat.h>
22 #include <termios.h>
23 #include <unistd.h>
24 #endif
25 
26 #include "llvm/Support/ConvertUTF.h"
27 #include "llvm/Support/Errno.h"
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/Process.h"
30 
31 #include "lldb/Host/Config.h"
32 #include "lldb/Host/FileSystem.h"
33 #include "lldb/Host/Host.h"
35 #include "lldb/Utility/FileSpec.h"
36 #include "lldb/Utility/Log.h"
37 
38 using namespace lldb;
39 using namespace lldb_private;
40 using llvm::Expected;
41 
42 Expected<const char *>
43 File::GetStreamOpenModeFromOptions(File::OpenOptions options) {
45  options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
46  File::eOpenOptionReadWrite);
47 
48  if (options & File::eOpenOptionAppend) {
49  if (rw == File::eOpenOptionReadWrite) {
50  if (options & File::eOpenOptionCanCreateNewOnly)
51  return "a+x";
52  else
53  return "a+";
54  } else if (rw == File::eOpenOptionWriteOnly) {
55  if (options & File::eOpenOptionCanCreateNewOnly)
56  return "ax";
57  else
58  return "a";
59  }
60  } else if (rw == File::eOpenOptionReadWrite) {
61  if (options & File::eOpenOptionCanCreate) {
62  if (options & File::eOpenOptionCanCreateNewOnly)
63  return "w+x";
64  else
65  return "w+";
66  } else
67  return "r+";
68  } else if (rw == File::eOpenOptionWriteOnly) {
69  return "w";
70  } else if (rw == File::eOpenOptionReadOnly) {
71  return "r";
72  }
73  return llvm::createStringError(
74  llvm::inconvertibleErrorCode(),
75  "invalid options, cannot convert to mode string");
76 }
77 
78 Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) {
79  OpenOptions opts =
80  llvm::StringSwitch<OpenOptions>(mode)
81  .Cases("r", "rb", eOpenOptionReadOnly)
82  .Cases("w", "wb", eOpenOptionWriteOnly)
83  .Cases("a", "ab",
84  eOpenOptionWriteOnly | eOpenOptionAppend |
85  eOpenOptionCanCreate)
86  .Cases("r+", "rb+", "r+b", eOpenOptionReadWrite)
87  .Cases("w+", "wb+", "w+b",
88  eOpenOptionReadWrite | eOpenOptionCanCreate |
89  eOpenOptionTruncate)
90  .Cases("a+", "ab+", "a+b",
91  eOpenOptionReadWrite | eOpenOptionAppend |
92  eOpenOptionCanCreate)
93  .Default(eOpenOptionInvalid);
94  if (opts != eOpenOptionInvalid)
95  return opts;
96  return llvm::createStringError(
97  llvm::inconvertibleErrorCode(),
98  "invalid mode, cannot convert to File::OpenOptions");
99 }
100 
101 int File::kInvalidDescriptor = -1;
102 FILE *File::kInvalidStream = nullptr;
103 
104 Status File::Read(void *buf, size_t &num_bytes) {
105  return std::error_code(ENOTSUP, std::system_category());
106 }
107 Status File::Write(const void *buf, size_t &num_bytes) {
108  return std::error_code(ENOTSUP, std::system_category());
109 }
110 
111 bool File::IsValid() const { return false; }
112 
113 Status File::Close() { return Flush(); }
114 
115 IOObject::WaitableHandle File::GetWaitableHandle() {
116  return IOObject::kInvalidHandleValue;
117 }
118 
119 Status File::GetFileSpec(FileSpec &file_spec) const {
120  file_spec.Clear();
121  return std::error_code(ENOTSUP, std::system_category());
122 }
123 
124 int File::GetDescriptor() const { return kInvalidDescriptor; }
125 
126 FILE *File::GetStream() { return nullptr; }
127 
128 off_t File::SeekFromStart(off_t offset, Status *error_ptr) {
129  if (error_ptr)
130  *error_ptr = std::error_code(ENOTSUP, std::system_category());
131  return -1;
132 }
133 
134 off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) {
135  if (error_ptr)
136  *error_ptr = std::error_code(ENOTSUP, std::system_category());
137  return -1;
138 }
139 
140 off_t File::SeekFromEnd(off_t offset, Status *error_ptr) {
141  if (error_ptr)
142  *error_ptr = std::error_code(ENOTSUP, std::system_category());
143  return -1;
144 }
145 
146 Status File::Read(void *dst, size_t &num_bytes, off_t &offset) {
147  return std::error_code(ENOTSUP, std::system_category());
148 }
149 
150 Status File::Write(const void *src, size_t &num_bytes, off_t &offset) {
151  return std::error_code(ENOTSUP, std::system_category());
152 }
153 
154 Status File::Flush() { return Status(); }
155 
156 Status File::Sync() { return Flush(); }
157 
158 void File::CalculateInteractiveAndTerminal() {
159  const int fd = GetDescriptor();
160  if (!DescriptorIsValid(fd)) {
161  m_is_interactive = eLazyBoolNo;
162  m_is_real_terminal = eLazyBoolNo;
163  m_supports_colors = eLazyBoolNo;
164  return;
165  }
166  m_is_interactive = eLazyBoolNo;
167  m_is_real_terminal = eLazyBoolNo;
168 #if defined(_WIN32)
169  if (_isatty(fd)) {
170  m_is_interactive = eLazyBoolYes;
171  m_is_real_terminal = eLazyBoolYes;
172 #if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
173  m_supports_colors = eLazyBoolYes;
174 #endif
175  }
176 #else
177  if (isatty(fd)) {
178  m_is_interactive = eLazyBoolYes;
179  struct winsize window_size;
180  if (::ioctl(fd, TIOCGWINSZ, &window_size) == 0) {
181  if (window_size.ws_col > 0) {
182  m_is_real_terminal = eLazyBoolYes;
183  if (llvm::sys::Process::FileDescriptorHasColors(fd))
184  m_supports_colors = eLazyBoolYes;
185  }
186  }
187  }
188 #endif
189 }
190 
191 bool File::GetIsInteractive() {
192  if (m_is_interactive == eLazyBoolCalculate)
193  CalculateInteractiveAndTerminal();
194  return m_is_interactive == eLazyBoolYes;
195 }
196 
197 bool File::GetIsRealTerminal() {
198  if (m_is_real_terminal == eLazyBoolCalculate)
199  CalculateInteractiveAndTerminal();
200  return m_is_real_terminal == eLazyBoolYes;
201 }
202 
203 bool File::GetIsTerminalWithColors() {
204  if (m_supports_colors == eLazyBoolCalculate)
205  CalculateInteractiveAndTerminal();
206  return m_supports_colors == eLazyBoolYes;
207 }
208 
209 size_t File::Printf(const char *format, ...) {
210  va_list args;
211  va_start(args, format);
212  size_t result = PrintfVarArg(format, args);
213  va_end(args);
214  return result;
215 }
216 
217 size_t File::PrintfVarArg(const char *format, va_list args) {
218  size_t result = 0;
219  char *s = nullptr;
220  result = vasprintf(&s, format, args);
221  if (s != nullptr) {
222  if (result > 0) {
223  size_t s_len = result;
224  Write(s, s_len);
225  result = s_len;
226  }
227  free(s);
228  }
229  return result;
230 }
231 
232 Expected<File::OpenOptions> File::GetOptions() const {
233  return llvm::createStringError(
234  llvm::inconvertibleErrorCode(),
235  "GetOptions() not implemented for this File class");
236 }
237 
239  int fd = GetDescriptor();
240  if (!DescriptorIsValid(fd)) {
241  error = std::error_code(ENOTSUP, std::system_category());
242  return 0;
243  }
244  struct stat file_stats;
245  if (::fstat(fd, &file_stats) == -1) {
246  error.SetErrorToErrno();
247  return 0;
248  }
249  error.Clear();
250  return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
251 }
252 
253 Expected<File::OpenOptions> NativeFile::GetOptions() const { return m_options; }
254 
255 int NativeFile::GetDescriptor() const {
256  if (DescriptorIsValid())
257  return m_descriptor;
258 
259  // Don't open the file descriptor if we don't need to, just get it from the
260  // stream if we have one.
261  if (StreamIsValid()) {
262 #if defined(_WIN32)
263  return _fileno(m_stream);
264 #else
265  return fileno(m_stream);
266 #endif
267  }
268 
269  // Invalid descriptor and invalid stream, return invalid descriptor.
270  return kInvalidDescriptor;
271 }
272 
273 IOObject::WaitableHandle NativeFile::GetWaitableHandle() {
274  return GetDescriptor();
275 }
276 
277 FILE *NativeFile::GetStream() {
278  if (!StreamIsValid()) {
279  if (DescriptorIsValid()) {
280  auto mode = GetStreamOpenModeFromOptions(m_options);
281  if (!mode)
282  llvm::consumeError(mode.takeError());
283  else {
284  if (!m_own_descriptor) {
285 // We must duplicate the file descriptor if we don't own it because when you
286 // call fdopen, the stream will own the fd
287 #ifdef _WIN32
288  m_descriptor = ::_dup(GetDescriptor());
289 #else
290  m_descriptor = dup(GetDescriptor());
291 #endif
292  m_own_descriptor = true;
293  }
294 
295  m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor,
296  mode.get());
297 
298  // If we got a stream, then we own the stream and should no longer own
299  // the descriptor because fclose() will close it for us
300 
301  if (m_stream) {
302  m_own_stream = true;
303  m_own_descriptor = false;
304  }
305  }
306  }
307  }
308  return m_stream;
309 }
310 
311 Status NativeFile::Close() {
312  Status error;
313  if (StreamIsValid()) {
314  if (m_own_stream) {
315  if (::fclose(m_stream) == EOF)
316  error.SetErrorToErrno();
317  } else {
318  File::OpenOptions rw =
319  m_options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
320  File::eOpenOptionReadWrite);
321 
322  if (rw == eOpenOptionWriteOnly || rw == eOpenOptionReadWrite) {
323  if (::fflush(m_stream) == EOF)
324  error.SetErrorToErrno();
325  }
326  }
327  }
328  if (DescriptorIsValid() && m_own_descriptor) {
329  if (::close(m_descriptor) != 0)
330  error.SetErrorToErrno();
331  }
332  m_descriptor = kInvalidDescriptor;
333  m_stream = kInvalidStream;
334  m_options = OpenOptions(0);
335  m_own_stream = false;
336  m_own_descriptor = false;
337  m_is_interactive = eLazyBoolCalculate;
338  m_is_real_terminal = eLazyBoolCalculate;
339  return error;
340 }
341 
342 Status NativeFile::GetFileSpec(FileSpec &file_spec) const {
343  Status error;
344 #ifdef F_GETPATH
345  if (IsValid()) {
346  char path[PATH_MAX];
347  if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1)
348  error.SetErrorToErrno();
349  else
350  file_spec.SetFile(path, FileSpec::Style::native);
351  } else {
352  error.SetErrorString("invalid file handle");
353  }
354 #elif defined(__linux__)
355  char proc[64];
356  char path[PATH_MAX];
357  if (::snprintf(proc, sizeof(proc), "/proc/self/fd/%d", GetDescriptor()) < 0)
358  error.SetErrorString("cannot resolve file descriptor");
359  else {
360  ssize_t len;
361  if ((len = ::readlink(proc, path, sizeof(path) - 1)) == -1)
362  error.SetErrorToErrno();
363  else {
364  path[len] = '\0';
365  file_spec.SetFile(path, FileSpec::Style::native);
366  }
367  }
368 #else
369  error.SetErrorString(
370  "NativeFile::GetFileSpec is not supported on this platform");
371 #endif
372 
373  if (error.Fail())
374  file_spec.Clear();
375  return error;
376 }
377 
378 off_t NativeFile::SeekFromStart(off_t offset, Status *error_ptr) {
379  off_t result = 0;
380  if (DescriptorIsValid()) {
381  result = ::lseek(m_descriptor, offset, SEEK_SET);
382 
383  if (error_ptr) {
384  if (result == -1)
385  error_ptr->SetErrorToErrno();
386  else
387  error_ptr->Clear();
388  }
389  } else if (StreamIsValid()) {
390  result = ::fseek(m_stream, offset, SEEK_SET);
391 
392  if (error_ptr) {
393  if (result == -1)
394  error_ptr->SetErrorToErrno();
395  else
396  error_ptr->Clear();
397  }
398  } else if (error_ptr) {
399  error_ptr->SetErrorString("invalid file handle");
400  }
401  return result;
402 }
403 
404 off_t NativeFile::SeekFromCurrent(off_t offset, Status *error_ptr) {
405  off_t result = -1;
406  if (DescriptorIsValid()) {
407  result = ::lseek(m_descriptor, offset, SEEK_CUR);
408 
409  if (error_ptr) {
410  if (result == -1)
411  error_ptr->SetErrorToErrno();
412  else
413  error_ptr->Clear();
414  }
415  } else if (StreamIsValid()) {
416  result = ::fseek(m_stream, offset, SEEK_CUR);
417 
418  if (error_ptr) {
419  if (result == -1)
420  error_ptr->SetErrorToErrno();
421  else
422  error_ptr->Clear();
423  }
424  } else if (error_ptr) {
425  error_ptr->SetErrorString("invalid file handle");
426  }
427  return result;
428 }
429 
430 off_t NativeFile::SeekFromEnd(off_t offset, Status *error_ptr) {
431  off_t result = -1;
432  if (DescriptorIsValid()) {
433  result = ::lseek(m_descriptor, offset, SEEK_END);
434 
435  if (error_ptr) {
436  if (result == -1)
437  error_ptr->SetErrorToErrno();
438  else
439  error_ptr->Clear();
440  }
441  } else if (StreamIsValid()) {
442  result = ::fseek(m_stream, offset, SEEK_END);
443 
444  if (error_ptr) {
445  if (result == -1)
446  error_ptr->SetErrorToErrno();
447  else
448  error_ptr->Clear();
449  }
450  } else if (error_ptr) {
451  error_ptr->SetErrorString("invalid file handle");
452  }
453  return result;
454 }
455 
456 Status NativeFile::Flush() {
457  Status error;
458  if (StreamIsValid()) {
459  if (llvm::sys::RetryAfterSignal(EOF, ::fflush, m_stream) == EOF)
460  error.SetErrorToErrno();
461  } else if (!DescriptorIsValid()) {
462  error.SetErrorString("invalid file handle");
463  }
464  return error;
465 }
466 
467 Status NativeFile::Sync() {
468  Status error;
469  if (DescriptorIsValid()) {
470 #ifdef _WIN32
471  int err = FlushFileBuffers((HANDLE)_get_osfhandle(m_descriptor));
472  if (err == 0)
473  error.SetErrorToGenericError();
474 #else
475  if (llvm::sys::RetryAfterSignal(-1, ::fsync, m_descriptor) == -1)
476  error.SetErrorToErrno();
477 #endif
478  } else {
479  error.SetErrorString("invalid file handle");
480  }
481  return error;
482 }
483 
484 #if defined(__APPLE__)
485 // Darwin kernels only can read/write <= INT_MAX bytes
486 #define MAX_READ_SIZE INT_MAX
487 #define MAX_WRITE_SIZE INT_MAX
488 #endif
489 
490 Status NativeFile::Read(void *buf, size_t &num_bytes) {
491  Status error;
492 
493 #if defined(MAX_READ_SIZE)
494  if (num_bytes > MAX_READ_SIZE) {
495  uint8_t *p = (uint8_t *)buf;
496  size_t bytes_left = num_bytes;
497  // Init the num_bytes read to zero
498  num_bytes = 0;
499 
500  while (bytes_left > 0) {
501  size_t curr_num_bytes;
502  if (bytes_left > MAX_READ_SIZE)
503  curr_num_bytes = MAX_READ_SIZE;
504  else
505  curr_num_bytes = bytes_left;
506 
507  error = Read(p + num_bytes, curr_num_bytes);
508 
509  // Update how many bytes were read
510  num_bytes += curr_num_bytes;
511  if (bytes_left < curr_num_bytes)
512  bytes_left = 0;
513  else
514  bytes_left -= curr_num_bytes;
515 
516  if (error.Fail())
517  break;
518  }
519  return error;
520  }
521 #endif
522 
523  ssize_t bytes_read = -1;
524  if (DescriptorIsValid()) {
525  bytes_read = llvm::sys::RetryAfterSignal(-1, ::read, m_descriptor, buf, num_bytes);
526  if (bytes_read == -1) {
527  error.SetErrorToErrno();
528  num_bytes = 0;
529  } else
530  num_bytes = bytes_read;
531  } else if (StreamIsValid()) {
532  bytes_read = ::fread(buf, 1, num_bytes, m_stream);
533 
534  if (bytes_read == 0) {
535  if (::feof(m_stream))
536  error.SetErrorString("feof");
537  else if (::ferror(m_stream))
538  error.SetErrorString("ferror");
539  num_bytes = 0;
540  } else
541  num_bytes = bytes_read;
542  } else {
543  num_bytes = 0;
544  error.SetErrorString("invalid file handle");
545  }
546  return error;
547 }
548 
549 Status NativeFile::Write(const void *buf, size_t &num_bytes) {
550  Status error;
551 
552 #if defined(MAX_WRITE_SIZE)
553  if (num_bytes > MAX_WRITE_SIZE) {
554  const uint8_t *p = (const uint8_t *)buf;
555  size_t bytes_left = num_bytes;
556  // Init the num_bytes written to zero
557  num_bytes = 0;
558 
559  while (bytes_left > 0) {
560  size_t curr_num_bytes;
561  if (bytes_left > MAX_WRITE_SIZE)
562  curr_num_bytes = MAX_WRITE_SIZE;
563  else
564  curr_num_bytes = bytes_left;
565 
566  error = Write(p + num_bytes, curr_num_bytes);
567 
568  // Update how many bytes were read
569  num_bytes += curr_num_bytes;
570  if (bytes_left < curr_num_bytes)
571  bytes_left = 0;
572  else
573  bytes_left -= curr_num_bytes;
574 
575  if (error.Fail())
576  break;
577  }
578  return error;
579  }
580 #endif
581 
582  ssize_t bytes_written = -1;
583  if (DescriptorIsValid()) {
584  bytes_written =
585  llvm::sys::RetryAfterSignal(-1, ::write, m_descriptor, buf, num_bytes);
586  if (bytes_written == -1) {
587  error.SetErrorToErrno();
588  num_bytes = 0;
589  } else
590  num_bytes = bytes_written;
591  } else if (StreamIsValid()) {
592  bytes_written = ::fwrite(buf, 1, num_bytes, m_stream);
593 
594  if (bytes_written == 0) {
595  if (::feof(m_stream))
596  error.SetErrorString("feof");
597  else if (::ferror(m_stream))
598  error.SetErrorString("ferror");
599  num_bytes = 0;
600  } else
601  num_bytes = bytes_written;
602 
603  } else {
604  num_bytes = 0;
605  error.SetErrorString("invalid file handle");
606  }
607 
608  return error;
609 }
610 
611 Status NativeFile::Read(void *buf, size_t &num_bytes, off_t &offset) {
612  Status error;
613 
614 #if defined(MAX_READ_SIZE)
615  if (num_bytes > MAX_READ_SIZE) {
616  uint8_t *p = (uint8_t *)buf;
617  size_t bytes_left = num_bytes;
618  // Init the num_bytes read to zero
619  num_bytes = 0;
620 
621  while (bytes_left > 0) {
622  size_t curr_num_bytes;
623  if (bytes_left > MAX_READ_SIZE)
624  curr_num_bytes = MAX_READ_SIZE;
625  else
626  curr_num_bytes = bytes_left;
627 
628  error = Read(p + num_bytes, curr_num_bytes, offset);
629 
630  // Update how many bytes were read
631  num_bytes += curr_num_bytes;
632  if (bytes_left < curr_num_bytes)
633  bytes_left = 0;
634  else
635  bytes_left -= curr_num_bytes;
636 
637  if (error.Fail())
638  break;
639  }
640  return error;
641  }
642 #endif
643 
644 #ifndef _WIN32
645  int fd = GetDescriptor();
646  if (fd != kInvalidDescriptor) {
647  ssize_t bytes_read =
648  llvm::sys::RetryAfterSignal(-1, ::pread, fd, buf, num_bytes, offset);
649  if (bytes_read < 0) {
650  num_bytes = 0;
651  error.SetErrorToErrno();
652  } else {
653  offset += bytes_read;
654  num_bytes = bytes_read;
655  }
656  } else {
657  num_bytes = 0;
658  error.SetErrorString("invalid file handle");
659  }
660 #else
661  std::lock_guard<std::mutex> guard(offset_access_mutex);
662  long cur = ::lseek(m_descriptor, 0, SEEK_CUR);
663  SeekFromStart(offset);
664  error = Read(buf, num_bytes);
665  if (!error.Fail())
666  SeekFromStart(cur);
667 #endif
668  return error;
669 }
670 
671 Status NativeFile::Write(const void *buf, size_t &num_bytes, off_t &offset) {
672  Status error;
673 
674 #if defined(MAX_WRITE_SIZE)
675  if (num_bytes > MAX_WRITE_SIZE) {
676  const uint8_t *p = (const uint8_t *)buf;
677  size_t bytes_left = num_bytes;
678  // Init the num_bytes written to zero
679  num_bytes = 0;
680 
681  while (bytes_left > 0) {
682  size_t curr_num_bytes;
683  if (bytes_left > MAX_WRITE_SIZE)
684  curr_num_bytes = MAX_WRITE_SIZE;
685  else
686  curr_num_bytes = bytes_left;
687 
688  error = Write(p + num_bytes, curr_num_bytes, offset);
689 
690  // Update how many bytes were read
691  num_bytes += curr_num_bytes;
692  if (bytes_left < curr_num_bytes)
693  bytes_left = 0;
694  else
695  bytes_left -= curr_num_bytes;
696 
697  if (error.Fail())
698  break;
699  }
700  return error;
701  }
702 #endif
703 
704  int fd = GetDescriptor();
705  if (fd != kInvalidDescriptor) {
706 #ifndef _WIN32
707  ssize_t bytes_written =
708  llvm::sys::RetryAfterSignal(-1, ::pwrite, m_descriptor, buf, num_bytes, offset);
709  if (bytes_written < 0) {
710  num_bytes = 0;
711  error.SetErrorToErrno();
712  } else {
713  offset += bytes_written;
714  num_bytes = bytes_written;
715  }
716 #else
717  std::lock_guard<std::mutex> guard(offset_access_mutex);
718  long cur = ::lseek(m_descriptor, 0, SEEK_CUR);
719  SeekFromStart(offset);
720  error = Write(buf, num_bytes);
721  long after = ::lseek(m_descriptor, 0, SEEK_CUR);
722 
723  if (!error.Fail())
724  SeekFromStart(cur);
725 
726  offset = after;
727 #endif
728  } else {
729  num_bytes = 0;
730  error.SetErrorString("invalid file handle");
731  }
732  return error;
733 }
734 
735 size_t NativeFile::PrintfVarArg(const char *format, va_list args) {
736  if (StreamIsValid()) {
737  return ::vfprintf(m_stream, format, args);
738  } else {
739  return File::PrintfVarArg(format, args);
740  }
741 }
742 
743 mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) {
744  mode_t mode = 0;
745  File::OpenOptions rw =
746  open_options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
747  File::eOpenOptionReadWrite);
748  if (rw == eOpenOptionReadWrite)
749  mode |= O_RDWR;
750  else if (rw == eOpenOptionWriteOnly)
751  mode |= O_WRONLY;
752  else if (rw == eOpenOptionReadOnly)
753  mode |= O_RDONLY;
754 
755  if (open_options & eOpenOptionAppend)
756  mode |= O_APPEND;
757 
758  if (open_options & eOpenOptionTruncate)
759  mode |= O_TRUNC;
760 
761  if (open_options & eOpenOptionNonBlocking)
762  mode |= O_NONBLOCK;
763 
764  if (open_options & eOpenOptionCanCreateNewOnly)
765  mode |= O_CREAT | O_EXCL;
766  else if (open_options & eOpenOptionCanCreate)
767  mode |= O_CREAT;
768 
769  return mode;
770 }
771 
772 char File::ID = 0;
773 char NativeFile::ID = 0;
FileSystem.h
O_NONBLOCK
#define O_NONBLOCK
Definition: windows/PosixApi.h:29
Host.h
lldb_private::File::OpenOptions
OpenOptions
Definition: File.h:48
S_IRWXU
#define S_IRWXU
Definition: windows/PosixApi.h:50
S_IRWXG
#define S_IRWXG
Definition: windows/PosixApi.h:53
lldb_private::eLazyBoolYes
@ eLazyBoolYes
Definition: lldb-private-enumerations.h:115
GetPermissions
static Permissions GetPermissions(const ELFSectionHeader &H)
Definition: ObjectFileELF.cpp:1649
lldb_private::FileSpec
Definition: FileSpec.h:56
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
ID
static char ID
Definition: IRDynamicChecks.cpp:32
Log.h
vasprintf
int vasprintf(char **ret, const char *fmt, va_list ap)
Definition: Windows.cpp:25
S_IRWXO
#define S_IRWXO
Definition: windows/PosixApi.h:56
lldb_private::IOObject::WaitableHandle
int WaitableHandle
Definition: IOObject.h:29
lldb_private::FileSpec::Clear
void Clear()
Clears the object state.
Definition: FileSpec.cpp:261
lldb_private::Status
Definition: Status.h:44
uint32_t
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
lldb_private::Status::SetErrorString
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:242
windows.h
lldb_private::Status::SetErrorToErrno
void SetErrorToErrno()
Set the current error to errno.
Definition: Status.cpp:224
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::eLazyBoolCalculate
@ eLazyBoolCalculate
Definition: lldb-private-enumerations.h:115
FileSpec.h
lldb_private::Status::Clear
void Clear()
Clear the object state.
Definition: Status.cpp:168
lldb_private::FileSpec::SetFile
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition: FileSpec.cpp:174
PATH_MAX
#define PATH_MAX
Definition: windows/PosixApi.h:25
lldb
Definition: SBAddress.h:15
File.h
DataBufferHeap.h