private static void WriteToStderr(string message)
{
// We don't want to write UTF-16 to a file like standard error. Ideally we would transcode this
// to UTF8, but the downside of that is it pulls in a bunch of stuff into what is ideally
// a path with minimal dependencies (as to prevent re-entrency), so we'll take the strategy
// of just throwing away any non ASCII characters from the message and writing the rest
const int BufferLength = 256;
unsafe
{
byte* buf = stackalloc byte[BufferLength];
int bufCount;
int i = 0;
using (SafeFileHandle fileHandle = SafeFileHandleHelper.Open(() => Interop.Sys.Dup(Interop.Sys.FileDescriptors.STDERR_FILENO)))
{
while (i < message.Length)
{
for (bufCount = 0; bufCount < BufferLength && i < message.Length; i++)
{
if (message[i] <= 0x7F)
{
buf[bufCount] = (byte)message[i];
bufCount++;
}
}
int totalBytesWritten = 0;
while (bufCount > 0)
{
int bytesWritten = Interop.Sys.Write(fileHandle, buf + totalBytesWritten, bufCount);
if (bytesWritten < 0)
{
// On error, simply stop writing the debug output. This could commonly happen if stderr
// was piped to a program that ended before this program did, resulting in EPIPE errors.
return;
}
bufCount -= bytesWritten;
totalBytesWritten += bytesWritten;
}
}
}
}
}
}