[llvm] r219170 - Support: Add a utility to remap std{in, out, err} to /dev/null if closed
David Majnemer
david.majnemer at gmail.com
Mon Oct 6 16:48:32 PDT 2014
fileno(stdout) will be 1 even if file descriptor 1 is closed.
On Mon, Oct 6, 2014 at 4:43 PM, Reid Kleckner <rnk at google.com> wrote:
> I thought we agreed to reduce our reliance on STDOUT_FILENO and instead
> check fileno(stdout)?
>
> On Mon, Oct 6, 2014 at 4:16 PM, David Majnemer <david.majnemer at gmail.com>
> wrote:
>
>> Author: majnemer
>> Date: Mon Oct 6 18:16:18 2014
>> New Revision: 219170
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=219170&view=rev
>> Log:
>> Support: Add a utility to remap std{in,out,err} to /dev/null if closed
>>
>> It's possible to start a program with one (or all) of the standard file
>> descriptors closed. Subsequent open system calls will give the program
>> a low-numbered file descriptor.
>>
>> This is problematic because we may believe we are writing to standard
>> out instead of a file.
>>
>> Introduce Process::FixupStandardFileDescriptors, a helper function to
>> remap standard file descriptors to /dev/null if they were closed before
>> the program started.
>>
>> Modified:
>> llvm/trunk/include/llvm/Support/Process.h
>> llvm/trunk/lib/Support/Unix/Process.inc
>> llvm/trunk/lib/Support/Windows/Process.inc
>>
>> Modified: llvm/trunk/include/llvm/Support/Process.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Process.h?rev=219170&r1=219169&r2=219170&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Support/Process.h (original)
>> +++ llvm/trunk/include/llvm/Support/Process.h Mon Oct 6 18:16:18 2014
>> @@ -186,6 +186,12 @@ public:
>> ArrayRef<const char *> ArgsFromMain,
>> SpecificBumpPtrAllocator<char> &ArgAllocator);
>>
>> + // This functions ensures that the standard file descriptors (input,
>> output,
>> + // and error) are properly mapped to a file descriptor before we use
>> any of
>> + // them. This should only be called by standalone programs, library
>> + // components should not call this.
>> + static std::error_code FixupStandardFileDescriptors();
>> +
>> /// This function determines if the standard input is connected
>> directly
>> /// to a user's input (keyboard probably), rather than coming from a
>> file
>> /// or pipe.
>>
>> Modified: llvm/trunk/lib/Support/Unix/Process.inc
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Process.inc?rev=219170&r1=219169&r2=219170&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Support/Unix/Process.inc (original)
>> +++ llvm/trunk/lib/Support/Unix/Process.inc Mon Oct 6 18:16:18 2014
>> @@ -18,6 +18,9 @@
>> #include "llvm/Support/Mutex.h"
>> #include "llvm/Support/MutexGuard.h"
>> #include "llvm/Support/TimeValue.h"
>> +#if HAVE_FCNTL_H
>> +#include <fcntl.h>
>> +#endif
>> #ifdef HAVE_SYS_TIME_H
>> #include <sys/time.h>
>> #endif
>> @@ -199,6 +202,62 @@ Process::GetArgumentVector(SmallVectorIm
>> return std::error_code();
>> }
>>
>> +namespace {
>> +class FDCloser {
>> +public:
>> + FDCloser(int &FD) : FD(FD), KeepOpen(false) {}
>> + void keepOpen() { KeepOpen = true; }
>> + ~FDCloser() {
>> + if (!KeepOpen && FD >= 0)
>> + ::close(FD);
>> + }
>> +
>> +private:
>> + FDCloser(const FDCloser &) LLVM_DELETED_FUNCTION;
>> + void operator=(const FDCloser &) LLVM_DELETED_FUNCTION;
>> +
>> + int &FD;
>> + bool KeepOpen;
>> +};
>> +}
>> +
>> +std::error_code Process::FixupStandardFileDescriptors() {
>> + int NullFD = -1;
>> + FDCloser FDC(NullFD);
>> + const int StandardFDs[] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO};
>> + for (int StandardFD : StandardFDs) {
>> + struct stat st;
>> + errno = 0;
>> + while (fstat(StandardFD, &st) < 0) {
>> + assert(errno && "expected errno to be set if fstat failed!");
>> + // fstat should return EBADF if the file descriptor is closed.
>> + if (errno == EBADF)
>> + break;
>> + // retry fstat if we got EINTR, otherwise bubble up the failure.
>> + if (errno != EINTR)
>> + return std::error_code(errno, std::generic_category());
>> + }
>> + // if fstat succeeds, move on to the next FD.
>> + if (!errno)
>> + continue;
>> + assert(errno == EBADF && "expected errno to have EBADF at this
>> point!");
>> +
>> + if (NullFD < 0) {
>> + while ((NullFD = open("/dev/null", O_RDWR)) < 0) {
>> + if (errno == EINTR)
>> + continue;
>> + return std::error_code(errno, std::generic_category());
>> + }
>> + }
>> +
>> + if (NullFD == StandardFD)
>> + FDC.keepOpen();
>> + else if (dup2(NullFD, StandardFD) < 0)
>> + return std::error_code(errno, std::generic_category());
>> + }
>> + return std::error_code();
>> +}
>> +
>> bool Process::StandardInIsUserInput() {
>> return FileDescriptorIsDisplayed(STDIN_FILENO);
>> }
>>
>> Modified: llvm/trunk/lib/Support/Windows/Process.inc
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Process.inc?rev=219170&r1=219169&r2=219170&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Support/Windows/Process.inc (original)
>> +++ llvm/trunk/lib/Support/Windows/Process.inc Mon Oct 6 18:16:18 2014
>> @@ -273,6 +273,10 @@ Process::GetArgumentVector(SmallVectorIm
>> return ec;
>> }
>>
>> +std::error_code Process::FixupStandardFileDescriptors() {
>> + return std::error_code();
>> +}
>> +
>> bool Process::StandardInIsUserInput() {
>> return FileDescriptorIsDisplayed(0);
>> }
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141006/a182fbc0/attachment.html>
More information about the llvm-commits
mailing list