<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Oct 6, 2014 at 4:54 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Mon, Oct 6, 2014 at 4:51 PM, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Mon, Oct 6, 2014 at 4:40 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span>On Mon, Oct 6, 2014 at 4:16 PM, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: majnemer<br>
Date: Mon Oct  6 18:16:18 2014<br>
New Revision: 219170<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=219170&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=219170&view=rev</a><br>
Log:<br>
Support: Add a utility to remap std{in,out,err} to /dev/null if closed<br>
<br>
It's possible to start a program with one (or all) of the standard file<br>
descriptors closed.  Subsequent open system calls will give the program<br>
a low-numbered file descriptor.<br>
<br>
This is problematic because we may believe we are writing to standard<br>
out instead of a file.<br></blockquote><div><br></div></span><div>Shouldn't we just fix these places so they don't make that mistake? (perhaps they should be checking if the FD isatty, etc - or whatever feature it is they care about)</div></div></div></div></blockquote><div><br></div></span><div>Your stdout might be a file by the users choice.  It's not possible to determine if stdout is sane by the time we get as far as constructing outs() or errs().</div></div></div></div></blockquote></span><div><br>For what definition of sanity?<br></div></div></div></div></blockquote><div><br></div><div>Normal file redirection at the command line can result in standard out being a normal file:</div><div>./foo > bar</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br>Anyway, just curious at what problems this addresses & vaguely wondering whether there's a differently general solution as this seems a bit weirdly special case to my vague understanding.</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Introduce Process::FixupStandardFileDescriptors, a helper function to<br>
remap standard file descriptors to /dev/null if they were closed before<br>
the program started.<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/Support/Process.h<br>
    llvm/trunk/lib/Support/Unix/Process.inc<br>
    llvm/trunk/lib/Support/Windows/Process.inc<br>
<br>
Modified: llvm/trunk/include/llvm/Support/Process.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Process.h?rev=219170&r1=219169&r2=219170&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Process.h?rev=219170&r1=219169&r2=219170&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Support/Process.h (original)<br>
+++ llvm/trunk/include/llvm/Support/Process.h Mon Oct  6 18:16:18 2014<br>
@@ -186,6 +186,12 @@ public:<br>
                     ArrayRef<const char *> ArgsFromMain,<br>
                     SpecificBumpPtrAllocator<char> &ArgAllocator);<br>
<br>
+  // This functions ensures that the standard file descriptors (input, output,<br>
+  // and error) are properly mapped to a file descriptor before we use any of<br>
+  // them.  This should only be called by standalone programs, library<br>
+  // components should not call this.<br>
+  static std::error_code FixupStandardFileDescriptors();<br>
+<br>
   /// This function determines if the standard input is connected directly<br>
   /// to a user's input (keyboard probably), rather than coming from a file<br>
   /// or pipe.<br>
<br>
Modified: llvm/trunk/lib/Support/Unix/Process.inc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Process.inc?rev=219170&r1=219169&r2=219170&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Process.inc?rev=219170&r1=219169&r2=219170&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Support/Unix/Process.inc (original)<br>
+++ llvm/trunk/lib/Support/Unix/Process.inc Mon Oct  6 18:16:18 2014<br>
@@ -18,6 +18,9 @@<br>
 #include "llvm/Support/Mutex.h"<br>
 #include "llvm/Support/MutexGuard.h"<br>
 #include "llvm/Support/TimeValue.h"<br>
+#if HAVE_FCNTL_H<br>
+#include <fcntl.h><br>
+#endif<br>
 #ifdef HAVE_SYS_TIME_H<br>
 #include <sys/time.h><br>
 #endif<br>
@@ -199,6 +202,62 @@ Process::GetArgumentVector(SmallVectorIm<br>
   return std::error_code();<br>
 }<br>
<br>
+namespace {<br>
+class FDCloser {<br>
+public:<br>
+  FDCloser(int &FD) : FD(FD), KeepOpen(false) {}<br>
+  void keepOpen() { KeepOpen = true; }<br>
+  ~FDCloser() {<br>
+    if (!KeepOpen && FD >= 0)<br>
+      ::close(FD);<br>
+  }<br>
+<br>
+private:<br>
+  FDCloser(const FDCloser &) LLVM_DELETED_FUNCTION;<br>
+  void operator=(const FDCloser &) LLVM_DELETED_FUNCTION;<br>
+<br>
+  int &FD;<br>
+  bool KeepOpen;<br>
+};<br>
+}<br>
+<br>
+std::error_code Process::FixupStandardFileDescriptors() {<br>
+  int NullFD = -1;<br>
+  FDCloser FDC(NullFD);<br>
+  const int StandardFDs[] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO};<br>
+  for (int StandardFD : StandardFDs) {<br>
+    struct stat st;<br>
+    errno = 0;<br>
+    while (fstat(StandardFD, &st) < 0) {<br>
+      assert(errno && "expected errno to be set if fstat failed!");<br>
+      // fstat should return EBADF if the file descriptor is closed.<br>
+      if (errno == EBADF)<br>
+        break;<br>
+      // retry fstat if we got EINTR, otherwise bubble up the failure.<br>
+      if (errno != EINTR)<br>
+        return std::error_code(errno, std::generic_category());<br>
+    }<br>
+    // if fstat succeeds, move on to the next FD.<br>
+    if (!errno)<br>
+      continue;<br>
+    assert(errno == EBADF && "expected errno to have EBADF at this point!");<br>
+<br>
+    if (NullFD < 0) {<br>
+      while ((NullFD = open("/dev/null", O_RDWR)) < 0) {<br>
+        if (errno == EINTR)<br>
+          continue;<br>
+        return std::error_code(errno, std::generic_category());<br>
+      }<br>
+    }<br>
+<br>
+    if (NullFD == StandardFD)<br>
+      FDC.keepOpen();<br>
+    else if (dup2(NullFD, StandardFD) < 0)<br>
+      return std::error_code(errno, std::generic_category());<br>
+  }<br>
+  return std::error_code();<br>
+}<br>
+<br>
 bool Process::StandardInIsUserInput() {<br>
   return FileDescriptorIsDisplayed(STDIN_FILENO);<br>
 }<br>
<br>
Modified: llvm/trunk/lib/Support/Windows/Process.inc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Process.inc?rev=219170&r1=219169&r2=219170&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Process.inc?rev=219170&r1=219169&r2=219170&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Support/Windows/Process.inc (original)<br>
+++ llvm/trunk/lib/Support/Windows/Process.inc Mon Oct  6 18:16:18 2014<br>
@@ -273,6 +273,10 @@ Process::GetArgumentVector(SmallVectorIm<br>
   return ec;<br>
 }<br>
<br>
+std::error_code Process::FixupStandardFileDescriptors() {<br>
+  return std::error_code();<br>
+}<br>
+<br>
 bool Process::StandardInIsUserInput() {<br>
   return FileDescriptorIsDisplayed(0);<br>
 }<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>