mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-10 16:30:30 -06:00
* link: Collect WSL logs (recommended method) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Advanced Authoring Tests in C++ Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: CMake Documentation and Community Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Collect WSL logs for networking issues Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Collect WSL logs (recommended method) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: ; otherwise, Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: a Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: access Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: accessible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: across Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: actively Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: adapters Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: address Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: addresses Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: and Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: appropriate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: argument Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: associated Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: attach Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: available Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: beginning Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: between Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: binaries Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: bound Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: buffer Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: buffers Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: cannot Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: canonical Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: capabilities Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: case-insensitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: case-sensitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: certified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: command Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: committer Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: communication Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: complains Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: configuration Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: consumed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: continue Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: converted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: currently Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: customers Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: daemon Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: deferred Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: definitions Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: delimiter Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: delivered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: dellink Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: derived Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: descriptor Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destined Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destruct Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destructible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destructor Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: detach Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: differentiate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: directories Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: disassociate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: disposition Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: distribution Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: distro Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: duping Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: emitted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: empty Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: environment Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: every time Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: exclusive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: expected Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: expire Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: explicitly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: fall back Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: false Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: fastfail Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: filesystem Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: first Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: followed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: for Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: functionality Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: functionally Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: github Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: greater Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: guarantee Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: guaranteed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: handles Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hangup Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hierarchy Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hogwarts Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hydrated Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: icrnl Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: implementation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: implementing Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: initialize Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instance Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instantiate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instantiations Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: intentionally Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: interpret Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: interpreter Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: irreversibly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: iteration Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: iterator Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: its Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: kernel Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: kmsg Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: knowledge Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: maximum Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: mirrored Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: msftconnecttest Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: multi Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: multiple Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: mutable Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: namespace Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: nonexistent Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: notifications Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: occurred Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: occurring Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: otherwise, Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: outstanding Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: overridden Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: partition Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: pass through Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: passthrough Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: performs Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: periodically Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: positional Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: precedence Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: preexisting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: preferring Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: prepopulate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: previous Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: privileges Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: process Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: processes Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: programmatically Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: protection Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: provided Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: reasonable Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: receive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: received Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: red hat Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: reentrant Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: registered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: regularly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: relay Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: release Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: representing Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: requests Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: response Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: resurrect Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: retention Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: returned Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: security Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: semaphore Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: separate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: separator Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: service Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: set up Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: setup Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: severely Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: should Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: signal Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: similarly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: simple Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: simplified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: single Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: specified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: splitting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: standard Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: stress Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: succeed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: success Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: successfully Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: supplementary Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: synced Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: system Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: take Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: than Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: that opening Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: the Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: threadpool Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: to Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: true Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: truncate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: tunneling Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unexpected Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: uninitialize Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unique Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unprivileged Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unregistered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: untrusted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: upgrade Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: utility Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: validating Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variant Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variations Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: verify Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: visible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: whether Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: winget Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: worker Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: written Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: wslservice Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * format source --------- Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Co-authored-by: Ben Hillis <benhillis@gmail.com> Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
1053 lines
27 KiB
C
1053 lines
27 KiB
C
/*++
|
|
|
|
Copyright (c) Microsoft. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
Template.c
|
|
|
|
Abstract:
|
|
|
|
This file is a ttys test.
|
|
|
|
--*/
|
|
|
|
#include "lxtcommon.h"
|
|
#include "unittests.h"
|
|
#include <sys/ioctl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/sysmacros.h>
|
|
#include <fcntl.h>
|
|
#include <termios.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <poll.h>
|
|
|
|
#define LXT_NAME "Ttys"
|
|
|
|
#define LXT_TTYS_LARGE_BUFFER_SIZE (1 * 1024)
|
|
#define LXT_TTYS_DEFAULT "/dev/ttyS1"
|
|
#define LXT_TTYS_DEFAULT_MINOR (LXT_TTYS_DEV_OFFSET + 1)
|
|
#define LXT_TTYS_DEFAULT2 "/dev/ttyS2"
|
|
#define LXT_TTYS_DEFAULT2_MINOR (LXT_TTYS_DEV_OFFSET + 2)
|
|
#define LXT_TTYS_FORMAT "/dev/ttyS%d"
|
|
#define LXT_TTYS_MAX 192
|
|
#define LXT_TTYS_DEV_MODE (S_IFCHR | 0660)
|
|
#define LXT_TTYS_DEV_MAJOR 4
|
|
#define LXT_TTYS_DEV_OFFSET 64
|
|
|
|
LXT_VARIATION_HANDLER TtysBasicOps;
|
|
LXT_VARIATION_HANDLER TtysTermiosBaudParity;
|
|
LXT_VARIATION_HANDLER TtysWrite;
|
|
LXT_VARIATION_HANDLER TtysWindowSize;
|
|
LXT_VARIATION_HANDLER TtysTermiosFlowControl;
|
|
LXT_VARIATION_HANDLER TtysWriteRead;
|
|
LXT_VARIATION_HANDLER TtysModemIoctls;
|
|
|
|
//
|
|
// Global constants
|
|
//
|
|
// TtysWriteRead requires two connected serial ports for testing.
|
|
//
|
|
|
|
static const LXT_VARIATION g_LxtVariations[] = {
|
|
{"Ttys basic operations", TtysBasicOps},
|
|
{"Ttys termios - baud rate and parity", TtysTermiosBaudParity},
|
|
{"Ttys write", TtysWrite},
|
|
{"Ttys window size", TtysWindowSize},
|
|
/* {"Ttys write read", TtysWriteRead}, */
|
|
{"Ttys termios - flow control", TtysTermiosFlowControl},
|
|
{"Ttys modem ioctls", TtysModemIoctls}};
|
|
|
|
int TtysTestEntry(int Argc, char* Argv[])
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
LXT_ARGS Args;
|
|
int Result;
|
|
|
|
LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
|
|
LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
|
|
|
|
ErrorExit:
|
|
LxtUninitialize();
|
|
return !LXT_SUCCESS(Result);
|
|
}
|
|
|
|
int TtysBasicOps(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
char Buffer[64];
|
|
dev_t Device;
|
|
int Fd;
|
|
char Path[32];
|
|
int Index;
|
|
int Result;
|
|
|
|
for (Index = 0; Index < LXT_TTYS_MAX; ++Index)
|
|
{
|
|
snprintf(Path, sizeof(Path), LXT_TTYS_FORMAT, Index);
|
|
unlink(Path);
|
|
Device = makedev(LXT_TTYS_DEV_MAJOR, Index + LXT_TTYS_DEV_OFFSET);
|
|
LxtCheckErrno(mknod(Path, LXT_TTYS_DEV_MODE, Device));
|
|
Fd = open(Path, O_RDWR | O_NONBLOCK, 0);
|
|
if (Fd != -1)
|
|
{
|
|
read(Fd, Buffer, sizeof(Buffer));
|
|
write(Fd, Buffer, sizeof(Buffer));
|
|
fsync(Fd);
|
|
tcflush(Fd, TCIOFLUSH);
|
|
LxtClose(Fd);
|
|
}
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int TtysTermiosBaudParity(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
int BaudRate;
|
|
int BaudRates[] = {B1200, B9600, B9600};
|
|
int Cflag;
|
|
dev_t Device;
|
|
int Iflag;
|
|
int Index;
|
|
int Fd;
|
|
int Result;
|
|
struct termios Termios = {0};
|
|
struct termios TermiosNew = {0};
|
|
|
|
Fd = -1;
|
|
Result = LXT_RESULT_FAILURE;
|
|
|
|
//
|
|
// Check the default termios values.
|
|
//
|
|
// N.B. Ignore termios fields that may differ.
|
|
//
|
|
|
|
Device = makedev(LXT_TTYS_DEV_MAJOR, LXT_TTYS_DEFAULT_MINOR);
|
|
mknod(LXT_TTYS_DEFAULT, LXT_TTYS_DEV_MODE, Device);
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
if (Fd == -1)
|
|
{
|
|
if (errno == EIO)
|
|
{
|
|
LxtLogInfo("Skipping test %d", errno);
|
|
Result = LXT_RESULT_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
LxtLogError("Unexpected error %d", errno);
|
|
}
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtCheckErrno(tcgetattr(Fd, &Termios));
|
|
LxtCheckEqual(Termios.c_oflag, 05, "%d");
|
|
LxtCheckEqual(Termios.c_lflag, 0105063, "%d");
|
|
LxtCheckEqual(Termios.c_line, 0, "%d");
|
|
LxtCheckEqual(Termios.c_cc[0], 3, "%d");
|
|
LxtCheckEqual(Termios.c_cc[1], 28, "%d");
|
|
LxtCheckEqual(Termios.c_cc[2], 127, "%d");
|
|
LxtCheckEqual(Termios.c_cc[3], 21, "%d");
|
|
LxtCheckEqual(Termios.c_cc[5], 0, "%d");
|
|
LxtCheckEqual(Termios.c_cc[6], 1, "%d");
|
|
LxtCheckEqual(Termios.c_cc[7], 0, "%d");
|
|
LxtCheckEqual(Termios.c_cc[10], 26, "%d");
|
|
LxtCheckEqual(Termios.c_cc[11], 0, "%d");
|
|
LxtCheckEqual(Termios.c_cc[12], 18, "%d");
|
|
LxtCheckEqual(Termios.c_cc[13], 15, "%d");
|
|
LxtCheckEqual(Termios.c_cc[14], 23, "%d");
|
|
LxtCheckEqual(Termios.c_cc[15], 22, "%d");
|
|
LxtCheckEqual(Termios.c_cc[16], 0, "%d");
|
|
|
|
//
|
|
// Set and check the baud rate.
|
|
//
|
|
|
|
BaudRate = cfgetispeed(&Termios);
|
|
for (Index = 0; Index < LXT_COUNT_OF(BaudRates); ++Index)
|
|
{
|
|
cfsetspeed(&Termios, BaudRates[Index]);
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
}
|
|
|
|
//
|
|
// Reset to the original.
|
|
//
|
|
|
|
cfsetspeed(&Termios, BaudRate);
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Set and check the parity enable and type bits
|
|
//
|
|
// N.B. NT does not support setting input and output parity independently,
|
|
// but Linux does.
|
|
//
|
|
|
|
Cflag = Termios.c_cflag;
|
|
Iflag = Termios.c_iflag;
|
|
|
|
//
|
|
// No parity, 8 bits
|
|
//
|
|
|
|
Termios.c_iflag &= ~INPCK;
|
|
Termios.c_cflag &= ~PARENB;
|
|
Termios.c_cflag &= ~CSTOPB;
|
|
Termios.c_cflag &= ~CMSPAR;
|
|
Termios.c_cflag &= ~CSIZE;
|
|
Termios.c_cflag |= CS8;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Even parity, 7 bits
|
|
//
|
|
|
|
Termios.c_iflag |= INPCK;
|
|
Termios.c_cflag |= PARENB;
|
|
Termios.c_cflag &= ~PARODD;
|
|
Termios.c_cflag &= ~CMSPAR;
|
|
Termios.c_cflag &= ~CSTOPB;
|
|
Termios.c_cflag &= ~CSIZE;
|
|
Termios.c_cflag |= CS7;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Odd parity, 7 bits
|
|
//
|
|
|
|
Termios.c_iflag |= INPCK;
|
|
Termios.c_cflag |= PARENB;
|
|
Termios.c_cflag |= PARODD;
|
|
Termios.c_cflag &= ~CMSPAR;
|
|
Termios.c_cflag &= ~CSTOPB;
|
|
Termios.c_cflag &= ~CSIZE;
|
|
Termios.c_cflag |= CS7;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Even parity, 5 bits
|
|
//
|
|
|
|
Termios.c_iflag |= INPCK;
|
|
Termios.c_cflag |= PARENB;
|
|
Termios.c_cflag &= ~PARODD;
|
|
Termios.c_cflag &= ~CMSPAR;
|
|
Termios.c_cflag &= ~CSTOPB;
|
|
Termios.c_cflag &= ~CSIZE;
|
|
Termios.c_cflag |= CS5;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Odd parity, 5 bits, with stop bit
|
|
//
|
|
|
|
Termios.c_iflag |= INPCK;
|
|
Termios.c_cflag |= PARENB;
|
|
Termios.c_cflag |= PARODD;
|
|
Termios.c_cflag &= ~CMSPAR;
|
|
Termios.c_cflag |= CSTOPB;
|
|
Termios.c_cflag &= ~CSIZE;
|
|
Termios.c_cflag |= CS5;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Space parity, 7 bits
|
|
//
|
|
|
|
Termios.c_iflag |= INPCK;
|
|
Termios.c_cflag |= PARENB;
|
|
Termios.c_cflag &= ~PARODD;
|
|
Termios.c_cflag |= CMSPAR;
|
|
Termios.c_cflag &= ~CSTOPB;
|
|
Termios.c_cflag &= ~CSIZE;
|
|
Termios.c_cflag |= CS7;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Mark parity, 7 bits
|
|
//
|
|
|
|
Termios.c_iflag |= INPCK;
|
|
Termios.c_cflag |= PARENB;
|
|
Termios.c_cflag |= PARODD;
|
|
Termios.c_cflag |= CMSPAR;
|
|
Termios.c_cflag &= ~CSTOPB;
|
|
Termios.c_cflag &= ~CSIZE;
|
|
Termios.c_cflag |= CS7;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Reset to the original
|
|
//
|
|
|
|
Termios.c_cflag = Cflag;
|
|
Termios.c_iflag = Iflag;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Fd != -1)
|
|
{
|
|
LxtClose(Fd);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int TtysWrite(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
char Buffer[64];
|
|
int BytesWritten;
|
|
dev_t Device;
|
|
int Fd;
|
|
char Path[32];
|
|
struct pollfd PollFd;
|
|
int Index;
|
|
int Result;
|
|
|
|
//
|
|
// Test non-blocking write paths.
|
|
//
|
|
// N.B. Blocking can hang if there is no reader.
|
|
//
|
|
|
|
Fd = -1;
|
|
Device = makedev(LXT_TTYS_DEV_MAJOR, LXT_TTYS_DEFAULT_MINOR);
|
|
mknod(LXT_TTYS_DEFAULT, LXT_TTYS_DEV_MODE, Device);
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
if (Fd == -1)
|
|
{
|
|
if (errno == EIO)
|
|
{
|
|
LxtLogInfo("Skipping test %d", errno);
|
|
Result = LXT_RESULT_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
LxtLogError("Unexpected error %d", errno);
|
|
}
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
memset(&PollFd, 0, sizeof(PollFd));
|
|
PollFd.fd = Fd;
|
|
PollFd.events = POLLIN | POLLOUT | POLLHUP;
|
|
LxtCheckErrno(poll(&PollFd, 1, 0));
|
|
LxtCheckEqual(PollFd.revents & POLLOUT, POLLOUT, "%d");
|
|
|
|
errno = 0;
|
|
BytesWritten = write(Fd, Buffer, sizeof(Buffer));
|
|
if ((BytesWritten != sizeof(Buffer)) && (errno != EAGAIN))
|
|
{
|
|
LxtLogError("Unexpected BytesWritten %d, %d", BytesWritten, errno);
|
|
Result = LXT_RESULT_FAILURE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Fd != -1)
|
|
{
|
|
LxtClose(Fd);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int TtysWindowSize(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
dev_t Device;
|
|
int Fd;
|
|
char Path[32];
|
|
int Result;
|
|
struct winsize WindowSize;
|
|
struct winsize WindowSizeNew;
|
|
|
|
//
|
|
// Test setting and getting the window size of a serial device.
|
|
//
|
|
|
|
Fd = -1;
|
|
Device = makedev(LXT_TTYS_DEV_MAJOR, LXT_TTYS_DEFAULT_MINOR);
|
|
mknod(LXT_TTYS_DEFAULT, LXT_TTYS_DEV_MODE, Device);
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR, 0);
|
|
if (Fd == -1)
|
|
{
|
|
if (errno == EIO)
|
|
{
|
|
LxtLogInfo("Skipping test %d", errno);
|
|
Result = LXT_RESULT_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
LxtLogError("Unexpected error %d", errno);
|
|
}
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtCheckErrno(ioctl(Fd, TIOCGWINSZ, &WindowSize));
|
|
LxtLogInfo("%d, %d", WindowSize.ws_row, WindowSize.ws_col);
|
|
WindowSizeNew = WindowSize;
|
|
WindowSizeNew.ws_row += 1;
|
|
WindowSizeNew.ws_col += 1;
|
|
LxtCheckErrno(ioctl(Fd, TIOCSWINSZ, &WindowSizeNew));
|
|
LxtCheckErrno(ioctl(Fd, TIOCGWINSZ, &WindowSize));
|
|
LxtCheckMemoryEqual(&WindowSize, &WindowSizeNew, sizeof(WindowSize));
|
|
memset(&WindowSizeNew, 0, sizeof(WindowSizeNew));
|
|
LxtCheckErrno(ioctl(Fd, TIOCSWINSZ, &WindowSizeNew));
|
|
LxtCheckErrno(ioctl(Fd, TIOCGWINSZ, &WindowSize));
|
|
LxtCheckMemoryEqual(&WindowSize, &WindowSizeNew, sizeof(WindowSize));
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Fd != -1)
|
|
{
|
|
LxtClose(Fd);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int TtysTermiosFlowControl(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
int Cflag;
|
|
dev_t Device;
|
|
int Iflag;
|
|
int Index;
|
|
int Fd;
|
|
int Result;
|
|
struct termios Termios = {0};
|
|
struct termios TermiosNew = {0};
|
|
char VStart;
|
|
char VStop;
|
|
|
|
Fd = -1;
|
|
Result = LXT_RESULT_FAILURE;
|
|
|
|
//
|
|
// Check the default termios values.
|
|
//
|
|
// N.B. Ignore the termios settings that may differ..
|
|
//
|
|
|
|
Device = makedev(LXT_TTYS_DEV_MAJOR, LXT_TTYS_DEFAULT_MINOR);
|
|
mknod(LXT_TTYS_DEFAULT, LXT_TTYS_DEV_MODE, Device);
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
if (Fd == -1)
|
|
{
|
|
if (errno == EIO)
|
|
{
|
|
LxtLogInfo("Skipping test %d", errno);
|
|
Result = LXT_RESULT_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
LxtLogError("Unexpected error %d", errno);
|
|
}
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Set and check the parity enable and type bits
|
|
//
|
|
// N.B. NT does not support setting input and output parity independently,
|
|
// but Linux does.
|
|
//
|
|
|
|
LxtCheckErrno(tcgetattr(Fd, &Termios));
|
|
Cflag = Termios.c_cflag;
|
|
Iflag = Termios.c_iflag;
|
|
VStart = Termios.c_cc[VSTART];
|
|
VStop = Termios.c_cc[VSTOP];
|
|
|
|
//
|
|
// ixon and ixoff set
|
|
//
|
|
|
|
Termios.c_iflag |= IXON;
|
|
Termios.c_iflag |= IXOFF;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// ixon and ixoff not set
|
|
//
|
|
|
|
Termios.c_iflag &= ~IXON;
|
|
Termios.c_iflag &= ~IXOFF;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// crtscts set
|
|
//
|
|
|
|
Termios.c_cflag |= CRTSCTS;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// crtscts not set
|
|
//
|
|
|
|
Termios.c_cflag &= ~CRTSCTS;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// clocal not set
|
|
//
|
|
|
|
LxtLogInfo("Clearing clocal");
|
|
Termios.c_cflag &= ~CLOCAL;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// clocal set
|
|
//
|
|
|
|
Termios.c_cflag |= CLOCAL;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Flip vstart and vstop
|
|
//
|
|
|
|
LxtLogInfo("Updating vstart and vstop");
|
|
Termios.c_cc[VSTART] = VStop;
|
|
Termios.c_cc[VSTOP] = VStart;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
//
|
|
// Reset to the original
|
|
//
|
|
|
|
LxtLogInfo("Resetting...");
|
|
Termios.c_cflag = Cflag;
|
|
Termios.c_iflag = Iflag;
|
|
Termios.c_cc[VSTART] = VStart;
|
|
Termios.c_cc[VSTOP] = VStop;
|
|
LxtCheckErrno(tcsetattr(Fd, TCSANOW, &Termios));
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosNew));
|
|
LxtCheckMemoryEqual(&Termios, &TermiosNew, sizeof(Termios));
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Fd != -1)
|
|
{
|
|
LxtClose(Fd);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int TtysWriteReadTransfer(PLXT_ARGS Args, int FdRead, int FdWrite)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
int BytesRead;
|
|
int BytesWritten;
|
|
int BytesTotal;
|
|
pid_t ChildPid;
|
|
int Index;
|
|
char* RecvBuffer;
|
|
int Result;
|
|
char* SendBuffer;
|
|
|
|
ChildPid = -1;
|
|
RecvBuffer = NULL;
|
|
SendBuffer = NULL;
|
|
|
|
//
|
|
// Allocate a buffer with known data to transfer and a buffer to receive
|
|
// the data.
|
|
//
|
|
|
|
SendBuffer = LxtAlloc(LXT_TTYS_LARGE_BUFFER_SIZE);
|
|
if (SendBuffer == NULL)
|
|
{
|
|
Result = LXT_RESULT_FAILURE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
for (Index = 0; Index < LXT_TTYS_LARGE_BUFFER_SIZE; ++Index)
|
|
{
|
|
SendBuffer[Index] = (char)Index;
|
|
}
|
|
|
|
RecvBuffer = LxtAlloc(LXT_TTYS_LARGE_BUFFER_SIZE);
|
|
if (RecvBuffer == NULL)
|
|
{
|
|
Result = LXT_RESULT_FAILURE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
memset(RecvBuffer, 0, LXT_TTYS_LARGE_BUFFER_SIZE);
|
|
|
|
//
|
|
// Send and recv the data.
|
|
//
|
|
|
|
LxtCheckErrno(ChildPid = fork());
|
|
if (ChildPid == 0)
|
|
{
|
|
for (BytesTotal = 0; BytesTotal < LXT_TTYS_LARGE_BUFFER_SIZE; BytesTotal += BytesWritten)
|
|
{
|
|
BytesWritten = write(FdWrite, &SendBuffer[BytesTotal], LXT_TTYS_LARGE_BUFFER_SIZE - BytesTotal);
|
|
|
|
if (BytesWritten == -1)
|
|
{
|
|
if ((errno == EAGAIN) || (errno == EINTR))
|
|
{
|
|
BytesWritten = 0;
|
|
continue;
|
|
}
|
|
|
|
Result = LXT_RESULT_FAILURE;
|
|
LxtLogError("Write failed with %d", errno);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
_exit(0);
|
|
}
|
|
|
|
for (BytesTotal = 0; BytesTotal < LXT_TTYS_LARGE_BUFFER_SIZE; BytesTotal += BytesRead)
|
|
{
|
|
BytesRead = read(FdRead, &RecvBuffer[BytesTotal], LXT_TTYS_LARGE_BUFFER_SIZE - BytesTotal);
|
|
|
|
if (BytesRead == -1)
|
|
{
|
|
if ((errno == EAGAIN) || (errno == EINTR))
|
|
{
|
|
BytesRead = 0;
|
|
continue;
|
|
}
|
|
|
|
Result = LXT_RESULT_FAILURE;
|
|
LxtLogError("Read failed with %d", errno);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
LxtWaitPidPoll(ChildPid, 0);
|
|
for (Index = 0; Index < LXT_TTYS_LARGE_BUFFER_SIZE; ++Index)
|
|
{
|
|
if (RecvBuffer[Index] != (char)Index)
|
|
{
|
|
Result = LXT_RESULT_FAILURE;
|
|
LxtLogError("Mismatch at index %d: %d != %d", Index, (int)(RecvBuffer[Index]), (int)((char)Index));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
Result = 0;
|
|
|
|
ErrorExit:
|
|
if (ChildPid == 0)
|
|
{
|
|
_exit(Result);
|
|
}
|
|
|
|
if (RecvBuffer != NULL)
|
|
{
|
|
LxtFree(RecvBuffer);
|
|
}
|
|
|
|
if (SendBuffer != NULL)
|
|
{
|
|
LxtFree(SendBuffer);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int TtysWriteReadTermios(PLXT_ARGS Args, int FdRead, int FdWrite)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
struct termios FdReadTermios;
|
|
int Fds[2];
|
|
struct termios FdWriteTermios;
|
|
int Index;
|
|
struct termios Termios;
|
|
int Result;
|
|
|
|
//
|
|
// Set the termios structure for transferring raw data.
|
|
//
|
|
|
|
Fds[0] = FdRead;
|
|
Fds[1] = FdWrite;
|
|
for (Index = 0; Index < LXT_COUNT_OF(Fds); ++Index)
|
|
{
|
|
LxtCheckErrno(tcgetattr(Fds[Index], &Termios));
|
|
Termios.c_iflag = 0;
|
|
Termios.c_oflag = 0;
|
|
Termios.c_cflag = B115200 | CREAD | CS8;
|
|
Termios.c_lflag = 0;
|
|
LxtCheckErrno(tcsetattr(Fds[Index], TCSANOW, &Termios));
|
|
}
|
|
|
|
memset(&FdReadTermios, 0, sizeof(FdReadTermios));
|
|
LxtCheckErrno(tcgetattr(FdRead, &FdReadTermios));
|
|
memset(&FdWriteTermios, 0, sizeof(FdWriteTermios));
|
|
LxtCheckErrno(tcgetattr(FdWrite, &FdWriteTermios));
|
|
LxtCheckMemoryEqual(&FdReadTermios, &FdWriteTermios, sizeof(FdWriteTermios));
|
|
|
|
Result = 0;
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int TtysWriteRead(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
int BytesWritten;
|
|
dev_t Device;
|
|
int FdRead;
|
|
int FdWrite;
|
|
char Path[32];
|
|
int Result;
|
|
|
|
FdRead = -1;
|
|
FdWrite = -1;
|
|
|
|
Device = makedev(LXT_TTYS_DEV_MAJOR, LXT_TTYS_DEFAULT_MINOR);
|
|
mknod(LXT_TTYS_DEFAULT, LXT_TTYS_DEV_MODE, Device);
|
|
LxtCheckErrno(FdRead = open(LXT_TTYS_DEFAULT, O_RDWR, 0));
|
|
Device = makedev(LXT_TTYS_DEV_MAJOR, LXT_TTYS_DEFAULT2_MINOR);
|
|
mknod(LXT_TTYS_DEFAULT2, LXT_TTYS_DEV_MODE, Device);
|
|
LxtCheckErrno(FdWrite = open(LXT_TTYS_DEFAULT2, O_RDWR, 0));
|
|
LxtCheckResult(TtysWriteReadTermios(Args, FdRead, FdWrite));
|
|
|
|
//
|
|
// Transfer data with blocking IO
|
|
//
|
|
|
|
LxtCheckResult(TtysWriteReadTransfer(Args, FdRead, FdWrite));
|
|
|
|
//
|
|
// Transfer again with non-blocking IO.
|
|
//
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (FdRead != -1)
|
|
{
|
|
LxtClose(FdRead);
|
|
}
|
|
|
|
if (FdWrite != -1)
|
|
{
|
|
LxtClose(FdWrite);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int TtysModemIoctls(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
dev_t Device;
|
|
int Fd;
|
|
int ModemSettings;
|
|
int ModemSettingsOrig;
|
|
int Result;
|
|
struct termios Termios;
|
|
struct termios TermiosOrig;
|
|
|
|
Fd = -1;
|
|
ModemSettingsOrig = -1;
|
|
Result = LXT_RESULT_FAILURE;
|
|
|
|
//
|
|
// Check the default modem settings
|
|
//
|
|
|
|
Device = makedev(LXT_TTYS_DEV_MAJOR, LXT_TTYS_DEFAULT_MINOR);
|
|
mknod(LXT_TTYS_DEFAULT, LXT_TTYS_DEV_MODE, Device);
|
|
Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0);
|
|
if (Fd == -1)
|
|
{
|
|
if (errno == EIO)
|
|
{
|
|
LxtLogInfo("Skipping test %d", errno);
|
|
Result = LXT_RESULT_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
LxtLogError("Unexpected error %d", errno);
|
|
}
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtCheckResult(ioctl(Fd, TIOCMGET, &ModemSettingsOrig));
|
|
LxtLogInfo("ModemSettingsOrig: %d", ModemSettingsOrig);
|
|
ModemSettings = ModemSettingsOrig;
|
|
LxtCheckResult(ioctl(Fd, TIOCMSET, &ModemSettings));
|
|
LxtCheckResult(ioctl(Fd, TIOCMGET, &ModemSettings));
|
|
LxtCheckEqual(ModemSettings, ModemSettingsOrig, "%d");
|
|
|
|
//
|
|
// Check that invalid settings are ignored
|
|
//
|
|
|
|
ModemSettings = -1;
|
|
LxtCheckResult(ioctl(Fd, TIOCMSET, &ModemSettings));
|
|
LxtCheckResult(ioctl(Fd, TIOCMGET, &ModemSettings));
|
|
LxtCheckNotEqual(ModemSettings, ModemSettingsOrig, "%d");
|
|
ModemSettings = -1;
|
|
LxtCheckResult(ioctl(Fd, TIOCMBIC, &ModemSettings));
|
|
LxtCheckResult(ioctl(Fd, TIOCMGET, &ModemSettings));
|
|
LxtCheckEqual(ModemSettings, 0, "%d");
|
|
ModemSettings = -1;
|
|
LxtCheckResult(ioctl(Fd, TIOCMBIS, &ModemSettings));
|
|
LxtCheckResult(ioctl(Fd, TIOCMGET, &ModemSettings));
|
|
LxtCheckNotEqual(ModemSettings, ModemSettingsOrig, "%d");
|
|
|
|
//
|
|
// Recheck the settings after closing and reopening.
|
|
//
|
|
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
LxtCheckErrno(Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0));
|
|
LxtCheckResult(ioctl(Fd, TIOCMGET, &ModemSettings));
|
|
LxtCheckNotEqual(ModemSettings, ModemSettingsOrig, "%d");
|
|
|
|
//
|
|
// Check DTR
|
|
//
|
|
// N.B. Some serial drivers start up with DTR on native Linux.
|
|
//
|
|
|
|
ModemSettings = ModemSettingsOrig & ~TIOCM_DTR;
|
|
LxtCheckResult(ioctl(Fd, TIOCMSET, &ModemSettings));
|
|
LxtCheckResult(ioctl(Fd, TIOCMGET, &ModemSettings));
|
|
LxtCheckEqual(ModemSettings, ModemSettingsOrig & ~TIOCM_DTR, "%d");
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
LxtCheckErrno(Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0));
|
|
|
|
ModemSettings = TIOCM_DTR;
|
|
LxtCheckResult(ioctl(Fd, TIOCMBIS, &ModemSettings));
|
|
LxtCheckResult(ioctl(Fd, TIOCMGET, &ModemSettings));
|
|
LxtCheckEqual(ModemSettings, ModemSettingsOrig | TIOCM_DTR, "%d");
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
LxtCheckErrno(Fd = open(LXT_TTYS_DEFAULT, O_RDWR | O_NONBLOCK, 0));
|
|
LxtCheckResult(ioctl(Fd, TIOCMGET, &ModemSettings));
|
|
LxtCheckEqual(ModemSettings, ModemSettingsOrig | TIOCM_DTR, "%d");
|
|
|
|
//
|
|
// Check that changing RTS doesn't impact termios
|
|
//
|
|
|
|
LxtCheckErrno(tcgetattr(Fd, &TermiosOrig));
|
|
ModemSettings = TIOCM_RTS;
|
|
LxtCheckResult(ioctl(Fd, TIOCMBIS, &ModemSettings));
|
|
LxtCheckErrno(tcgetattr(Fd, &Termios));
|
|
LxtCheckMemoryEqual(&TermiosOrig, &Termios, sizeof(Termios));
|
|
ModemSettings = TIOCM_RTS;
|
|
LxtCheckResult(ioctl(Fd, TIOCMBIC, &ModemSettings));
|
|
LxtCheckErrno(tcgetattr(Fd, &Termios));
|
|
LxtCheckMemoryEqual(&TermiosOrig, &Termios, sizeof(Termios));
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Fd != -1)
|
|
{
|
|
if (ModemSettingsOrig != -1)
|
|
{
|
|
LxtCheckResult(ioctl(Fd, TIOCMSET, &ModemSettingsOrig));
|
|
}
|
|
|
|
LxtClose(Fd);
|
|
}
|
|
|
|
return Result;
|
|
}
|