TermiosLib 1.0.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package TermiosLib --version 1.0.3
                    
NuGet\Install-Package TermiosLib -Version 1.0.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TermiosLib" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TermiosLib" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="TermiosLib" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TermiosLib --version 1.0.3
                    
#r "nuget: TermiosLib, 1.0.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TermiosLib@1.0.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TermiosLib&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=TermiosLib&version=1.0.3
                    
Install as a Cake Tool

TermiosLib

A C# wrapper of the renowned C Termios Library for the manipulation of terminal interfaces in a manner defined by POSIX. This library can be used for all serial devices that implement TTY, and or simulate it in one way or another.

See the man page for <termios.h> for more information regarding the library itself.

Example Program:

using System;
using TermiosLib;
using TermiosLib.TermiosEnums;

namespace Termios
{
    internal static class Program
    {
        public static void Main()
        {
            TermiosLib.Termios termios = new(0);
            
            termios.StateSandbox(() =>
            {
                termios.ModifyGlobalAttrs(OptionalActions.TcSaNow, (ref TermiosAttrs newState) =>
                {
                    newState.c_lflag &= ~(LocalFlags.ICanon | LocalFlags.IExten | LocalFlags.Echo | LocalFlags.ISig);
                    newState.c_oflag &= ~OutputFlags.OPost;
                    newState.c_cflag &= ControlFlags.Cs8;
                    newState.c_iflag &= ~(InputFlags.IxOn | InputFlags.IStrip | InputFlags.ICrNl);
                });
                
                System.IO.StreamWriter sw = new(Console.OpenStandardOutput()) {NewLine = "\r\n", AutoFlush = true};
                while (termios.ReadByte(out var b) != -1 && b != 3)
                {
                    sw.WriteLine(b + $" ({(char) b})");
                }
            });
        }
    }
}

Standard Defined Functions:

void GetAttrs(out TermiosAttrs termios)

Description:

Returns the current global termios state in the C# managed struct through out.

Failure cases:

Should not fail in under any circumstances unless the system defines the terminal file descriptor as a number other than 0, or some strange business regarding the group process being orphaned.

Example:

GetAttrs(out TermiosAttrs termios);

// This is for example purposes only. See ModifyGlobalAttrs(...) for why this is
// should not be done like this.
ModifyGlobalAttrs((ref TermiosAttrs newState) => {
    newState = termios;
});
void ModifyGlobalAttrs(OptionalActions optionalActions, ModifyAction modify)

ModifyAction is defined as delegate void ModifyAction(ref TermiosAttrs t)

Due to calling tcsetattr(int, int, struct termios*) before tcgetattr(int, struct termios*) being undefined, this function will always call GetAttrs(...) internally. Hence, it is almost always unnecessary to call GetAttrs(...) before ModifyGlobalAttrs(...) (especially with the extended lib functions). Just call the function by itself.

Description:

Sets the global state of termios through the C# managed TermiosAttrs struct

Failure cases:

Should not fail in under any circumstances unless the system defines the terminal file descriptor as a number other than 0, or some strange business regarding the group process being orphaned

Example:

ModifyGlobalAttrs(OptionalActions.TcSaNow, (ref TermiosAttrs newState) =>
{
    newState.c_lflag &= ~(LocalFlags.ICanon | LocalFlags.IExten | LocalFlags.Echo | LocalFlags.ISig);
    newState.c_oflag &= ~OutputFlags.OPost;
    newState.c_cflag &= ControlFlags.Cs8;
    newState.c_iflag &= ~(InputFlags.IxOn | InputFlags.IStrip | InputFlags.ICrNl);
});
void DrainOutput()

Description:

Waits for all output to be sent to the serial device

Failure cases:

Should not fail in under any circumstances unless the system defines the terminal file descriptor as a number other than 0, or some strange business regarding the group process being orphaned

void FlushOutput(LineCtrlFlags queueSelector)

Description:

Discards data written to the object referred to by the file descriptor but not transmitted, or data received but not read depending on the value of queue selector.

Failure cases:

Should not fail under any circumstances unless the system defines the terminal file descriptor as a number other than 0, or some strange business regarding the group process being orphaned.

long GetProcessGroupId()

Description:

Returns the group process id for the terminal.

Failure cases:

Should not fail in under any circumstances unless the system defines the terminal file descriptor as a number other than 0.

void SendBreak(long duration)

Description:

Will initiate the transmission of zero-valued bits for a specified duration, which for a duration of zero is between 0.25 and 0.5 seconds and for durations greater than zero it is implementation defined

Failure cases:

Should not fail under any circumstances unless the system defines the terminal file descriptor as a number other than 0, or some strange business regarding the group process being orphaned

Non-POSIX Functions:

void EnableRaw()

Related to the function cfmakeraw(3) defined on certain systems that enables flags that enables raw input.

Description: Disables the ICANON, IEXTEN, ECHO, ISIG, OPOST, IXON, ISTRIP, and ICRNL flags and enables the CS8 flag in order to redirect all input to stdin in 8 bit bytes.

Failure cases:

This function fails only if the underlying GetAttrs and SetAttrs calls fail.

void ResetTerm()

Related to the function cfmakesane(3) defined on certain systems that reverts the global termios flags to a state similar to a newly created terminal device.

Description:

Returns the terminal to the state it was in at the time of the original constructor call for any specified file descriptor.

Failure cases:

This function fails only if the underlying SetAttrs call fails.

Extended Mechanics Explanation:

Due to this function being necessary for reverting to the original state of the terminal prior to any form of modification, the global termios struct's state for any given file descriptor is statically stored and applied to all future instances of a Termios struct with the same file descriptor.

This guarantees that the behavior of ResetTerm() is the same irregardless of any action taken upon the struct prior to calling.

IEEE Defined Functions:

long ReadByte(out byte b)

Description:

Reads in a single byte from stdin, returning through out with b. Intended for use when Termios raw mode is enabled as it causes Console.Read() to work in an fashion that may not be expected or desirable.

Failure cases:

Failure is NOT handled in the library, so it is necessary to make sure that the return value of the function is not -1. Errno may be queried through Marshal.GetLastWin32Error() regardless of operating system

Wrapper Specific Functions:

The following functions are not implemented out of necessity in regards to any specific standard or library, but rather out of convenience for those who will use this library.

void StateSandbox(Action function)

Description:

Given a function, StateSandbox will execute it in a way that reverts the global termios state to what it was prior to calling the function, regardless of what occurs within the passed function.

Failure Cases:

Will only fail if its internal GetAttrs or SetAttrs calls fail.

Examples:

using TermiosLib;

TermiosHandle terminalHandle = new(0);

terminalHandle.StateSandbox(() => {
    // Reckless global termios modifications just for the fun of it
    terminalHandle.EnableRaw();
    terminalHandle.ModifyGlobalAttrs((ref TermiosLib.Termios newState) => {
        newState.c_cflag &= ControlFlags.Cs7;
    });
});
// No need to call termios.ResetTerm() because its already been reverted :)
void FallbackOnFailure(Func<bool> predicate, ModifyAction fallbackState)

Description:

Given a function that returns a bool, if the function fails (denoted by a return value of false), then the global state will reflect whatever flags are set in the fallback state.

Failure cases:

Will only fail if its internal GetAttrs or SetAttrs calls fail.

Examples:

using TermiosLib;

TermiosHandle terminalHandle = new(0);

terminalHandle.FallbackOnFailure(() => {
    newState.c_cflag &= ~ControlFlags.Cs8;
    newState.c_cflag |= ControlFlags.Cs6;
    // Something causes a failure
    return false;
}, 
(ref TermiosLib.Termios newState) => {
    newState.c_cflag &= ~ControlFlags.Cs8;
    // This is ultimately the flag that gets set
    newState.c_cflag |= ControlFlags.Cs7;
});
// No need to call termios.ResetTerm() because its already been reverted :)
string GlobalStateString()

Description:

Returns a formatted string of the struct that represents the current global termios struct.

Failure cases:

May fail if the internal GetAttrs call fails.

string OriginalStateString()

Description:

Returns a formatted string of the struct that represents 
the the global termios struct as it was at the beginning
of the program.

If the constructor for the file descriptor succeeds,
then this function is guaranteed to never fail.
Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net5.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.1 813 3/9/2022
2.0.0 580 3/9/2022
1.0.4 456 11/4/2021
1.0.3 484 11/3/2021
1.0.2 475 11/3/2021
1.0.1 475 11/3/2021
1.0.0 488 11/3/2021

Readme was missing in previous versions that were fixing other bugs.  Should be the last patch for a bit.