summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-11-30 16:50:05 -0500
committerGitHub <noreply@github.com>2021-11-30 16:50:05 -0500
commitce12e1d64d6b0b62609f061d3773a7e8b35849c3 (patch)
tree72da79208edff4fdebfc32db759ecca21716c260 /source/core
parentace4e334bc5fb299d2890b5e3f35dfd84ea32606 (diff)
Auto flush for streams for stdin/out in slang-test (#2035)
* #include an absolute path didn't work - because paths were taken to always be relative. * Move StreamType from Process to StdStreamType in slang-stream.h * Disable buffering for stdout/stderr for slang-test. * Improve comment.
Diffstat (limited to 'source/core')
-rw-r--r--source/core/slang-process-util.cpp4
-rw-r--r--source/core/slang-process.h14
-rw-r--r--source/core/slang-stream.cpp46
-rw-r--r--source/core/slang-stream.h17
-rw-r--r--source/core/unix/slang-unix-process.cpp16
-rw-r--r--source/core/windows/slang-win-process.cpp18
6 files changed, 85 insertions, 30 deletions
diff --git a/source/core/slang-process-util.cpp b/source/core/slang-process-util.cpp
index b1466d150..1a160b00b 100644
--- a/source/core/slang-process-util.cpp
+++ b/source/core/slang-process-util.cpp
@@ -49,8 +49,8 @@ static String _getText(const ConstArrayView<Byte>& bytes)
/* static */SlangResult ProcessUtil::readUntilTermination(Process* process, List<Byte>* outStdOut, List<Byte>* outStdError)
{
- Stream* stdOutStream = process->getStream(Process::StreamType::StdOut);
- Stream* stdErrorStream = process->getStream(Process::StreamType::ErrorOut);
+ Stream* stdOutStream = process->getStream(StdStreamType::Out);
+ Stream* stdErrorStream = process->getStream(StdStreamType::ErrorOut);
while (!process->isTerminated())
{
diff --git a/source/core/slang-process.h b/source/core/slang-process.h
index 7cd7596ae..6d86d8b14 100644
--- a/source/core/slang-process.h
+++ b/source/core/slang-process.h
@@ -16,14 +16,6 @@ namespace Slang {
class Process : public RefObject
{
public:
- enum class StreamType
- {
- ErrorOut,
- StdOut,
- StdIn,
- CountOf,
- };
-
typedef uint32_t Flags;
struct Flag
{
@@ -34,7 +26,7 @@ public:
};
/// Get the stream for the type
- Stream* getStream(StreamType type) const { return m_streams[Index(type)]; }
+ Stream* getStream(StdStreamType type) const { return m_streams[Index(type)]; }
/// Get the value returned from the process when it exited/returned.
int32_t getReturnValue() const { return m_returnValue; }
@@ -71,7 +63,7 @@ public:
static void sleepCurrentThread(Int timeInMs);
/// Get a standard stream
- static SlangResult getStdStream(StreamType type, RefPtr<Stream>& out);
+ static SlangResult getStdStream(StdStreamType type, RefPtr<Stream>& out);
/// Get the clock frequency
static uint64_t getClockFrequency();
@@ -81,7 +73,7 @@ public:
protected:
int32_t m_returnValue = 0; ///< Value returned if process terminated
- RefPtr<Stream> m_streams[Index(StreamType::CountOf)]; ///< Streams to communicate with the process
+ RefPtr<Stream> m_streams[Index(StdStreamType::CountOf)]; ///< Streams to communicate with the process
};
}
diff --git a/source/core/slang-stream.cpp b/source/core/slang-stream.cpp
index 7d4fab09e..47cf533eb 100644
--- a/source/core/slang-stream.cpp
+++ b/source/core/slang-stream.cpp
@@ -663,4 +663,50 @@ SlangResult BufferedReadStream::readUntilContains(size_t size)
}
}
+static FILE* _getFileFromStdStreamType(StdStreamType stdStream)
+{
+ switch (stdStream)
+ {
+ case StdStreamType::ErrorOut: return stderr;
+ case StdStreamType::Out: return stdout;
+ case StdStreamType::In: return stdin;
+ default: return nullptr;
+ }
+}
+
+static int _getBufferOptions(StreamBufferStyle style)
+{
+ switch (style)
+ {
+ case StreamBufferStyle::None: return _IONBF;
+ case StreamBufferStyle::Line: return _IOLBF;
+ default:
+ case StreamBufferStyle::Full: return _IOFBF;
+ }
+}
+
+/* static */SlangResult StreamUtil::setStreamBufferStyle(StdStreamType stdStream, StreamBufferStyle style)
+{
+ FILE* file = _getFileFromStdStreamType(stdStream);
+
+ if (file)
+ {
+ auto options = _getBufferOptions(style);
+
+ // https://www.cplusplus.com/reference/cstdio/setvbuf/
+
+ // NOTE! We don't set a buffer here (we pass in nullptr).
+ // Passing nullptr is fine for 'no buffering' and sets a 'dynamic buffer' for others.
+ // But it's not clear the behavior is around the buffer size. It seems the size is a
+ // 'suggestion' so it will set the default but the documentation is unclear.
+ if (setvbuf(file, nullptr, options, 0) == 0)
+ {
+ return SLANG_OK;
+ }
+ return SLANG_FAIL;
+ }
+
+ return SLANG_E_NOT_AVAILABLE;
+}
+
} // namespace Slang
diff --git a/source/core/slang-stream.h b/source/core/slang-stream.h
index a163a0c5d..388b178c9 100644
--- a/source/core/slang-stream.h
+++ b/source/core/slang-stream.h
@@ -6,6 +6,14 @@
namespace Slang
{
+enum class StdStreamType
+{
+ ErrorOut,
+ Out,
+ In,
+ CountOf,
+};
+
enum class SeekOrigin
{
Start, ///< Seek from the start of the stream
@@ -236,6 +244,13 @@ protected:
RefPtr<Stream> m_stream; ///< Stream that is being read from
};
+enum class StreamBufferStyle
+{
+ None,
+ Line,
+ Full,
+};
+
struct StreamUtil
{
/// Appends all bytes that can be read from stream into bytes
@@ -251,6 +266,8 @@ struct StreamUtil
static SlangResult readOrDiscard(Stream* stream, size_t readSize, List<Byte>* ioBytes);
static SlangResult readOrDiscardAll(Stream* stream, size_t readSize, List<Byte>* ioBytes);
+
+ static SlangResult setStreamBufferStyle(StdStreamType stdStream, StreamBufferStyle style);
};
diff --git a/source/core/unix/slang-unix-process.cpp b/source/core/unix/slang-unix-process.cpp
index 4e8344486..2c84ef08f 100644
--- a/source/core/unix/slang-unix-process.cpp
+++ b/source/core/unix/slang-unix-process.cpp
@@ -435,12 +435,12 @@ static const int kCannotExecute = 126;
::close(stderrPipe[1]);
::close(stdinPipe[0]);
- RefPtr<Stream> streams[Index(Process::StreamType::CountOf)];
+ RefPtr<Stream> streams[Index(StdStreamType::CountOf)];
// Previously code didn't need to close, so we'll make stream not own the handles
- streams[Index(Process::StreamType::StdOut)] = new UnixPipeStream(stdoutPipe[0], FileAccess::Read, true);
- streams[Index(Process::StreamType::ErrorOut)] = new UnixPipeStream(stderrPipe[0], FileAccess::Read, true);
- streams[Index(Process::StreamType::StdIn)] = new UnixPipeStream(stdinPipe[1], FileAccess::Write, true);
+ streams[Index(StdStreamType::Out)] = new UnixPipeStream(stdoutPipe[0], FileAccess::Read, true);
+ streams[Index(StdStreamType::ErrorOut)] = new UnixPipeStream(stderrPipe[0], FileAccess::Read, true);
+ streams[Index(StdStreamType::In)] = new UnixPipeStream(stdinPipe[1], FileAccess::Write, true);
outProcess = new UnixProcess(childPid, streams[0].readRef());
return SLANG_OK;
@@ -481,21 +481,21 @@ static const int kCannotExecute = 126;
nanosleep(&timeSpec, nullptr);
}
-/* static */SlangResult Process::getStdStream(StreamType type, RefPtr<Stream>& out)
+/* static */SlangResult Process::getStdStream(StdStreamType type, RefPtr<Stream>& out)
{
switch (type)
{
- case StreamType::StdIn:
+ case StdStreamType::In:
{
out = new UnixPipeStream(STDIN_FILENO, FileAccess::Read, false);
break;
}
- case StreamType::StdOut:
+ case StdStreamType::Out:
{
out = new UnixPipeStream(STDOUT_FILENO, FileAccess::Write, false);
break;
}
- case StreamType::ErrorOut:
+ case StdStreamType::ErrorOut:
{
out = new UnixPipeStream(STDERR_FILENO, FileAccess::Write, false);
break;
diff --git a/source/core/windows/slang-win-process.cpp b/source/core/windows/slang-win-process.cpp
index ed06f5692..e0e38f2d4 100644
--- a/source/core/windows/slang-win-process.cpp
+++ b/source/core/windows/slang-win-process.cpp
@@ -120,7 +120,7 @@ public:
WinProcess(HANDLE handle, Stream* const* streams) :
m_processHandle(handle)
{
- for (Index i = 0; i < Index(Process::StreamType::CountOf); ++i)
+ for (Index i = 0; i < Index(StdStreamType::CountOf); ++i)
{
m_streams[i] = streams[i];
}
@@ -373,21 +373,21 @@ void WinProcess::kill(int32_t returnCode)
return UnownedStringSlice::fromLiteral(".exe");
}
-/* static */SlangResult Process::getStdStream(StreamType type, RefPtr<Stream>& out)
+/* static */SlangResult Process::getStdStream(StdStreamType type, RefPtr<Stream>& out)
{
switch (type)
{
- case StreamType::StdIn:
+ case StdStreamType::In:
{
out = new WinPipeStream(GetStdHandle(STD_INPUT_HANDLE), FileAccess::Read, false);
return SLANG_OK;
}
- case StreamType::StdOut:
+ case StdStreamType::Out:
{
out = new WinPipeStream(GetStdHandle(STD_OUTPUT_HANDLE), FileAccess::Write, false);
return SLANG_OK;
}
- case StreamType::ErrorOut:
+ case StdStreamType::ErrorOut:
{
out = new WinPipeStream(GetStdHandle(STD_ERROR_HANDLE), FileAccess::Write, false);
return SLANG_OK;
@@ -518,10 +518,10 @@ void WinProcess::kill(int32_t returnCode)
processHandle = processInfo.hProcess;
}
- RefPtr<Stream> streams[Index(Process::StreamType::CountOf)];
- streams[Index(Process::StreamType::ErrorOut)] = new WinPipeStream(childStdErrRead.detach(), FileAccess::Read);
- streams[Index(Process::StreamType::StdOut)] = new WinPipeStream(childStdOutRead.detach(), FileAccess::Read);
- streams[Index(Process::StreamType::StdIn)] = new WinPipeStream(childStdInWrite.detach(), FileAccess::Write);
+ RefPtr<Stream> streams[Index(StdStreamType::CountOf)];
+ streams[Index(StdStreamType::ErrorOut)] = new WinPipeStream(childStdErrRead.detach(), FileAccess::Read);
+ streams[Index(StdStreamType::Out)] = new WinPipeStream(childStdOutRead.detach(), FileAccess::Read);
+ streams[Index(StdStreamType::In)] = new WinPipeStream(childStdInWrite.detach(), FileAccess::Write);
outProcess = new WinProcess(processHandle.detach(), streams[0].readRef());
return SLANG_OK;