mirror of
https://github.com/microsoft/WSL.git
synced 2025-07-03 15:23:22 +00:00
290 lines
6.3 KiB
C
290 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;
|
||
|
}
|