mirror of
https://github.com/microsoft/WSL.git
synced 2025-07-03 07:23:20 +00:00

Many Microsoft employees have contributed to the Windows Subsystem for Linux, this commit is the result of their work since 2016. The entire history of the Windows Subsystem for Linux can't be shared here, but here's an overview of WSL's history after it moved to it own repository in 2021: Number of commits on the main branch: 2930 Number of contributors: 31 Head over https://github.com/microsoft/WSL/releases for a more detailed history of the features added to WSL since 2021.
289 lines
6.3 KiB
C
289 lines
6.3 KiB
C
/*++
|
|
|
|
Copyright (c) Microsoft. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
Template.c
|
|
|
|
Abstract:
|
|
|
|
This file is the poll.
|
|
|
|
--*/
|
|
|
|
#include "lxtcommon.h"
|
|
#include "unittests.h"
|
|
#include <poll.h>
|
|
#include <signal.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
|
|
#define LXT_NAME "Poll"
|
|
|
|
int PollVariation0(PLXT_ARGS Args);
|
|
|
|
//
|
|
// Global constants
|
|
//
|
|
|
|
static const LXT_VARIATION g_LxtVariations[] = {{"Poll0", PollVariation0}};
|
|
|
|
int PollTestEntry(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 CountFilledDescriptors(struct pollfd* PollDescriptors, int Count)
|
|
{
|
|
int NumberFilled;
|
|
int Index;
|
|
|
|
NumberFilled = 0;
|
|
|
|
for (Index = 0; Index < Count; Index += 1)
|
|
{
|
|
|
|
if (PollDescriptors[Index].revents != 0)
|
|
{
|
|
NumberFilled += 1;
|
|
}
|
|
}
|
|
|
|
return NumberFilled;
|
|
}
|
|
|
|
int PollVariation0(PLXT_ARGS Args)
|
|
{
|
|
int Result;
|
|
int FileDescriptor1;
|
|
int FileDescriptor2;
|
|
struct pollfd PollDescriptors[3];
|
|
int NumberFilled;
|
|
|
|
//
|
|
// Initialize locals.
|
|
//
|
|
|
|
FileDescriptor1 = -1;
|
|
FileDescriptor2 = -1;
|
|
|
|
//
|
|
// Open a file that will be used for select.
|
|
//
|
|
|
|
FileDescriptor1 = open("/data/test/poll_test.bin", O_RDWR | O_CREAT, S_IRWXU);
|
|
|
|
if (FileDescriptor1 == -1)
|
|
{
|
|
Result = errno;
|
|
LxtLogError("Could not create test file! %d", Result);
|
|
goto cleanup;
|
|
}
|
|
|
|
FileDescriptor2 = open("/data/test/poll_test.bin", O_RDWR | O_CREAT, S_IRWXU);
|
|
|
|
if (FileDescriptor2 == -1)
|
|
{
|
|
Result = errno;
|
|
LxtLogError("Could not create test file! %d", Result);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Fill the poll descriptors.
|
|
//
|
|
|
|
PollDescriptors[0].fd = FileDescriptor1;
|
|
PollDescriptors[0].events = POLLIN;
|
|
PollDescriptors[0].revents = -1;
|
|
|
|
PollDescriptors[1].fd = FileDescriptor2;
|
|
PollDescriptors[1].events = POLLRDHUP;
|
|
PollDescriptors[1].revents = -1;
|
|
|
|
PollDescriptors[2].fd = 100;
|
|
PollDescriptors[2].events = POLLOUT;
|
|
PollDescriptors[2].revents = -1;
|
|
|
|
Result = poll(PollDescriptors, 3, 60001);
|
|
|
|
if (Result == -1)
|
|
{
|
|
Result = errno;
|
|
LxtLogError("Waiting on poll failed! %d", Result);
|
|
goto cleanup;
|
|
}
|
|
|
|
if (Result != 2)
|
|
{
|
|
LxtLogError("Waiting on poll returned more than 2 events! %d", Result);
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
NumberFilled = CountFilledDescriptors(PollDescriptors, 3);
|
|
|
|
if (NumberFilled != Result)
|
|
{
|
|
LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
if (PollDescriptors[2].revents != POLLNVAL)
|
|
{
|
|
LxtLogError("Poll descriptor 3 was filled incorrectly!");
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
NumberFilled = CountFilledDescriptors(PollDescriptors, 3);
|
|
|
|
if (NumberFilled != Result)
|
|
{
|
|
LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Poll with zero descriptors and it should time out.
|
|
//
|
|
|
|
LxtLogInfo("Wait for 1s for poll to timeout...");
|
|
|
|
Result = poll(PollDescriptors, 0, 1000);
|
|
|
|
if (Result == -1)
|
|
{
|
|
Result = errno;
|
|
LxtLogError("Waiting on poll failed! %d", Result);
|
|
goto cleanup;
|
|
}
|
|
|
|
if (Result != 0)
|
|
{
|
|
LxtLogError("Waiting on poll returned data but should have timed out! %d", Result);
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Poll for read/write but get notified of error.
|
|
//
|
|
|
|
read(FileDescriptor2, NULL, 111);
|
|
|
|
PollDescriptors[1].fd = FileDescriptor2;
|
|
PollDescriptors[1].events = POLLIN | POLLOUT;
|
|
PollDescriptors[1].revents = -1;
|
|
|
|
PollDescriptors[2].fd = -FileDescriptor2;
|
|
PollDescriptors[2].events = POLLIN | POLLOUT;
|
|
PollDescriptors[2].revents = -1;
|
|
|
|
Result = poll(PollDescriptors, 3, -2);
|
|
|
|
if (Result == -1)
|
|
{
|
|
Result = errno;
|
|
LxtLogError("Waiting on poll failed! %d", Result);
|
|
goto cleanup;
|
|
}
|
|
|
|
if (Result != 2)
|
|
{
|
|
LxtLogError("Waiting on poll returned more than 2 events! %d", Result);
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
NumberFilled = CountFilledDescriptors(PollDescriptors, 3);
|
|
|
|
if (NumberFilled != Result)
|
|
{
|
|
LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Poll for nothing but still got notified of error.
|
|
//
|
|
|
|
PollDescriptors[1].fd = FileDescriptor2;
|
|
PollDescriptors[1].events = 0;
|
|
PollDescriptors[1].revents = -1;
|
|
|
|
PollDescriptors[2].fd = -FileDescriptor2;
|
|
PollDescriptors[2].events = POLLIN | POLLOUT;
|
|
PollDescriptors[2].revents = -1;
|
|
|
|
Result = poll(PollDescriptors, 3, -2);
|
|
|
|
if (Result == -1)
|
|
{
|
|
Result = errno;
|
|
LxtLogError("Waiting on poll failed! %d", Result);
|
|
goto cleanup;
|
|
}
|
|
|
|
if (Result != 1)
|
|
{
|
|
LxtLogError("Waiting on poll returned more than 1 events! %d", Result);
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
NumberFilled = CountFilledDescriptors(PollDescriptors, 3);
|
|
|
|
if (NumberFilled != Result)
|
|
{
|
|
LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
NumberFilled = CountFilledDescriptors(PollDescriptors, 1);
|
|
|
|
if (NumberFilled != Result)
|
|
{
|
|
LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
|
|
Result = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
cleanup:
|
|
|
|
if (FileDescriptor1 != -1)
|
|
{
|
|
close(FileDescriptor1);
|
|
}
|
|
|
|
if (FileDescriptor2 != -1)
|
|
{
|
|
close(FileDescriptor2);
|
|
}
|
|
|
|
return Result;
|
|
}
|