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