Josh Soref abce91d14b
Spelling (#12954)
* 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>
2025-07-23 15:19:00 -07:00

624 lines
14 KiB
C

/*++
Copyright (c) Microsoft. All rights reserved.
Module Name:
common.c
Abstract:
Common socket definitions and helper routines.
--*/
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <stdbool.h>
#include "common.h"
#include "lxtcommon.h"
int LxtSocketEpoll(int Descriptor, int Event, int Timeout)
/*++
Routine Description:
This routine checks whether the given epoll is set in the file descriptor.
Arguments:
Descriptor - Supplies the descriptor.
Event - Supplies an event to check for.
Timeout - Supplies the timeout value in milliseconds.
Return Value:
0 on success, -1 on failure.
--*/
{
struct epoll_event EpollEvent;
int EpollFd;
int Iterator;
int NumberDescriptors;
int Result;
EpollFd = -1;
LxtCheckErrno(EpollFd = epoll_create(1));
EpollEvent.events = Event;
EpollEvent.data.fd = Descriptor;
LxtCheckErrno(epoll_ctl(EpollFd, EPOLL_CTL_ADD, Descriptor, &EpollEvent));
LxtCheckErrno(NumberDescriptors = epoll_wait(EpollFd, &EpollEvent, 1, Timeout));
//
// If no descriptors were ready within the timeout, that is an error condition
//
if (NumberDescriptors != 1)
{
LxtLogInfo("expecting epoll_wait to return 1, but it returned %d", NumberDescriptors);
Result = -1;
errno = EAGAIN;
goto ErrorExit;
}
if ((EpollEvent.events & Event) == 0)
{
LxtLogError("epoll event(%d) is not set. Epoll event(s) set: %d", Event, EpollEvent.events);
Result = -1;
errno = EINVAL;
goto ErrorExit;
}
Result = 0;
ErrorExit:
if (EpollFd != -1)
{
close(EpollFd);
}
return Result;
}
void* SocketBlockedReaderThread(void* Arg)
/*++
Routine Description:
This routine will call read on the given fd and block.
Arguments:
Arg - Supplies the argument for the datagram server to operate.
Return Value:
Returns 0 on success, -1 on failure.
--*/
{
char Buffer[10] = "123456789";
ssize_t BytesRead;
int Fd;
int Result = LXT_RESULT_FAILURE;
Fd = *(int*)Arg;
LxtCheckErrno(BytesRead = recv(Fd, Buffer, sizeof(Buffer), 0));
if (BytesRead != 0)
{
LxtLogError("recv should return 0 bytes read, but it returned %d bytes", BytesRead);
goto ErrorExit;
}
LxtLogInfo("recv unblocked");
Result = LXT_RESULT_SUCCESS;
ErrorExit:
pthread_exit((void*)(ssize_t)Result);
}
void* SocketBlockedReaderZeroBufferThread(void* Arg)
/*++
Routine Description:
This routine will call read on the given fd with a zero-byte receive buffer
and block.
Arguments:
Arg - Supplies the argument for the datagram server to operate.
Return Value:
Returns 0 on success, -1 on failure.
--*/
{
char Buffer[10] = "123456789";
ssize_t BytesRead;
int Fd;
int Result = LXT_RESULT_FAILURE;
Fd = *(int*)Arg;
LxtCheckErrno(BytesRead = recv(Fd, Buffer, 0, 0));
if (BytesRead != 0)
{
LxtLogError("recv should return 0 bytes read, but it returned %d bytes", BytesRead);
goto ErrorExit;
}
LxtLogInfo("recv unblocked");
Result = LXT_RESULT_SUCCESS;
ErrorExit:
pthread_exit((void*)(ssize_t)Result);
}
struct cmsghdr* SocketGetControlMessage(struct msghdr* MessageHeader, struct cmsghdr* StartControlMessage, int Level, int Type)
/*++
Routine Description:
This routine will return the control information at the given level and
type.
Arguments:
MessageHeader - Supplies the message header from which the control
information has to be extracted.
StartControlMessage - Supplies the control message from where to start.
NULL if the search has to start from the beginning.
Level - Supplies the level of the control information.
Type - Supplies the type of the control information.
Return Value:
Control message or NULL if it does not exist.
--*/
{
struct cmsghdr* ControlMessage;
//
// Use the system macros to extract receive the ip packet control info.
//
ControlMessage = NULL;
//
// If the start control message is provided use that, else get the first
// control message. This is automatically handled by MY_CMSG_NXTHDR.
//
for (ControlMessage = MY_CMSG_NXTHDR(MessageHeader, StartControlMessage); ControlMessage != NULL;
ControlMessage = MY_CMSG_NXTHDR(MessageHeader, ControlMessage))
{
if (ControlMessage->cmsg_len < sizeof(struct cmsghdr))
{
break;
}
//
// Look for a match.
//
if ((ControlMessage->cmsg_level == Level) && (ControlMessage->cmsg_type == Type))
{
return ControlMessage;
}
}
return NULL;
}
void* SocketBlockedWriterThread(void* Arg)
/*++
Routine Description:
This routine will call write on the given fd and block.
Arguments:
Arg - Supplies the argument for the datagram server to operate.
Return Value:
Returns 0 on success, -1 on failure.
--*/
{
char Buffer[10] = "123456789";
ssize_t BytesWritten;
int Fd;
int Result = LXT_RESULT_FAILURE;
Fd = *(int*)Arg;
LxtCheckErrnoFailure(send(Fd, Buffer, sizeof(Buffer), 0), EPIPE);
LxtLogInfo("send unblocked");
Result = LXT_RESULT_SUCCESS;
ErrorExit:
pthread_exit((void*)(ssize_t)Result);
}
int SocketGetSetBooleanSocketOption(int Socket, int OptionLevel, int OptionName, bool SmallerSizeAllowed)
/*++
Routine Description:
This routine tests the getsockopt() and setsockopt() API for the
any of the boolean socket option.
Arguments:
Socket - Supplies the socket.
OptionLevel - Supplies the level at which the option has to be applied.
Option - Supplies the option to test.
SmallerSizeAllowed - Supplies a boolean indicating whether sizes smaller
than the size of the option are allowed.
Return Value:
Returns 0 on success, -1 on failure.
--*/
{
int Result;
int Option;
socklen_t OptionLength;
long long int OptionLong;
Result = LXT_RESULT_FAILURE;
//
// Validate proper handling of boolean socket options.
//
Option = 1;
OptionLength = sizeof(Option);
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
Option = 0;
OptionLength = sizeof(Option);
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 1, "%d");
//
// Reset the option value to 0.
//
Option = 0;
OptionLength = sizeof(Option);
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
Option = 0;
OptionLength = sizeof(Option);
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 0, "%d");
//
// Since it is a boolean option, any value other than 0 is accepted for
// enabling the option. Try -ve.
//
Option = -1;
OptionLength = sizeof(Option);
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
Option = 0;
OptionLength = sizeof(Option);
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 1, "%d");
//
// Reset the option value to 0.
//
Option = 0;
OptionLength = sizeof(Option);
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
Option = 0;
OptionLength = sizeof(Option);
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 0, "%d");
//
// Since it is a boolean option, any value other than 0 is accepted for
// enabling the option. Try > 0.
//
Option = 15;
OptionLength = sizeof(Option);
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 1, "%d");
if (SmallerSizeAllowed == false)
{
//
// Validate that also 1,2 and 3 byte size is not a valid option size for
// boolean socket option.
//
OptionLength = 1;
LxtCheckErrnoFailure(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength), EINVAL);
OptionLength = 2;
LxtCheckErrnoFailure(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength), EINVAL);
OptionLength = 3;
LxtCheckErrnoFailure(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength), EINVAL);
OptionLength = sizeof(Option);
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 1, "%d");
}
else
{
//
// Supplying an option size of 1, 2 and 3 are also accepted.
//
Option = 1;
OptionLength = 1;
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 1, "%d");
//
// Reset the option value to 0.
//
Option = 0;
OptionLength = sizeof(Option);
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
//
// Option size of 2.
//
Option = 1;
OptionLength = 2;
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 1, "%d");
//
// Reset the option value to 0.
//
Option = 0;
OptionLength = sizeof(Option);
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
//
// Use option size of 3.
//
Option = 1;
OptionLength = 3;
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &Option, OptionLength));
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 1, "%d");
}
//
// Verify that anything above 4 bytes is ignored truncated.
//
OptionLong = 0x200000000;
OptionLength = sizeof(OptionLong);
LxtCheckErrno(setsockopt(Socket, OptionLevel, OptionName, &OptionLong, OptionLength));
OptionLength = sizeof(Option);
LxtCheckErrno(getsockopt(Socket, OptionLevel, OptionName, &Option, &OptionLength));
LxtCheckEqual(Option, 0, "%d");
ErrorExit:
return Result;
}
char* SocketGetTypeAsString(int Type)
/*++
Routine Description:
This routine returns the string equivalent for the give socket type.
Arguments:
Type - Supplies the socket type.
Return Value:
Returns the string equivalent for the type; NULL otherwise.
--*/
{
switch (Type)
{
case SOCK_STREAM:
return LXT_SOCKET_STREAM_STRING;
case SOCK_DGRAM:
return LXT_SOCKET_DGRAM_STRING;
case SOCK_RAW:
return LXT_SOCKET_RAW_STRING;
case SOCK_SEQPACKET:
return LXT_SOCKET_SEQPACKET_STRING;
case SOCK_PACKET:
return LXT_SOCKET_PACKET_STRING;
default:
return NULL;
}
}
int SocketStreamClientMsgWaitAll(int ConnectedSocket)
/*++
Routine Description:
This is a client helper routine testing MSG_WAITALL flag recv syscall.
Arguments:
ConnectedSocket - Supplies a socket fd.
Return Value:
0 on success, -1 on failure.
--*/
{
int FullMessageSize;
char* ReceiveBuffer;
int Result = LXT_RESULT_FAILURE;
char* SendBuffer;
int Size;
SendBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
FullMessageSize = 2 * strlen(SendBuffer);
ReceiveBuffer = malloc(FullMessageSize);
if (ReceiveBuffer == NULL)
{
goto ErrorExit;
}
LxtLogInfo("Client: 1. send");
LxtCheckErrno(Size = send(ConnectedSocket, SendBuffer, strlen(SendBuffer), 0));
//
// Sleep long enough that the second send won't be concatenated by WSK to
// test MSW_WAITALL code path, if the socket is inet socket.
//
sleep(1);
LxtLogInfo("Client: 2. delayed send");
LxtCheckErrno(Size = send(ConnectedSocket, SendBuffer, strlen(SendBuffer), 0));
memset(ReceiveBuffer, 0, FullMessageSize);
LxtLogInfo("Client: recv(MSG_WAITALL)");
LxtCheckErrno(Size = recv(ConnectedSocket, ReceiveBuffer, FullMessageSize, MSG_WAITALL));
LxtCheckMemoryEqual(SendBuffer, ReceiveBuffer, FullMessageSize / 2);
LxtCheckMemoryEqual(SendBuffer, ReceiveBuffer + FullMessageSize / 2, sizeof(SendBuffer));
Result = LXT_RESULT_SUCCESS;
ErrorExit:
if (ReceiveBuffer != NULL)
{
free(ReceiveBuffer);
}
return Result;
}
int SocketStreamServerMsgWaitAll(int AcceptedSocket)
/*++
Routine Description:
This is a server helper routine testing MSG_WAITALL flag recv syscall.
Arguments:
AcceptedSocket - Supplies a socket fd.
Return Value:
0 on success, -1 on failure.
--*/
{
int Index;
char* ReceiveBuffer;
int Result = LXT_RESULT_FAILURE;
int Size;
int FullMessageSize;
int Socket = 0;
ReceiveBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
FullMessageSize = 2 * strlen(ReceiveBuffer);
ReceiveBuffer = malloc(FullMessageSize);
if (ReceiveBuffer == NULL)
{
goto ErrorExit;
}
LxtLogInfo("Server: recv(MSG_WAITALL)");
memset(ReceiveBuffer, 0, sizeof(ReceiveBuffer));
LxtCheckErrno(Size = recv(AcceptedSocket, ReceiveBuffer, FullMessageSize, MSG_WAITALL));
LxtLogInfo("Server: write all back");
LxtCheckErrno(write(AcceptedSocket, ReceiveBuffer, Size));
Result = LXT_RESULT_SUCCESS;
ErrorExit:
if (ReceiveBuffer != NULL)
{
free(ReceiveBuffer);
}
return Result;
}