Skip to content

Bug in UnixConsoleStream when working with seekable files #126843

@adamsitnik

Description

@adamsitnik

In #125512 we have relaxed RandomAccess requirements and made it support non-seekable files and started using it in UnixConsoleStream:

RandomAccess.Read(_handle, buffer, fileOffset: 0);

RandomAccess.Write(fd, buffer, fileOffset: 0);

But we have assumed that the input and output stream will always be a non-seekable file (pipe or character device). With #125848 it's now very easy to redirect standard handles to files.

The problem is that in all RandomAccess usages in Console, we pass fileOffset: 0 and for regular files it means we keep on reading the first bytes and keep on writing to the beginning of the file.

I've hit this while working on #126807.

Small repro:

        [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
        public void Repro()
        {
            string testFilePath = GetTestFilePath();
            string largeText = new string('A', 1_000);
            File.WriteAllText(testFilePath, largeText);

            Process process = CreateProcess(() =>
            {
                Console.OpenStandardInput().CopyTo(Console.OpenStandardOutput());
                return RemoteExecutor.SuccessExitCode;
            });

            using SafeFileHandle input = File.OpenHandle(testFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            process.StartInfo.StandardInputHandle = input;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.Start();

            Assert.True(process.WaitForExit(WaitInMS));
        }

One fix would be to simply use FileStream (with bufferSize: 0) instead of RandomAccess.

Metadata

Metadata

Type

No fields configured for Bug.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions