Rasty Rasty - 1 month ago 22
C Question

Winapi: use select on pipe returns 10038

I'm new with winapi and have problem with pipes. I'm creating pipes with

::_pipe
function and want to use
select
on it but
WSAGetLastError
returns
10038
and kua is -1. Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <Winsock2.h>
#include <Windows.h>
#include <Winbase.h>
#include <FileAPI.h>
#include <io.h>
#include <wchar.h>

int main()
{
WORD wVersionRequested;
wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;

WSAStartup(wVersionRequested, &wsaData);
int fd[2];
_pipe(&fd[2], 65536, 0);
FD_SET set;

FD_SET((unsigned int) (fd[0]), (&set));

timeval time;
time.tv_sec = 1;
time.tv_usec = 0;
int kua = select(0, &set, NULL, NULL, &time);
printf("last ->%d\n", WSAGetLastError());
fflush(stdout);
}


Please dont pay attention on headers, I've read some topics which had same error but none of them where like this(pipe created this way). Hope you can help. Thanks.

EDIT
I changed code a little bit now its
_pipe(fd, 65536, 0);
but in this case it gives me seg fault.

Answer

On most platforms, pipes and sockets are both represented using file descriptors, and as such both can be used with file I/O functions that operate on file descriptors, including select().

However, on Windows, sockets and pipes are distinct object types, and are not represented using file descriptors at all. select() only supports sockets, not files or pipes. That is why you are getting error 10038, aka WSAENOTSOCK:

Socket operation on nonsocket.
An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.

There is no equivalent of select() for pipe objects created by _pipe(). All you can do is read and write.

If you need to detect when data arrives on a pipe before reading it, use CreatePipe() and PeekNamedPipe() instead of _pipe(). Otherwise, consider using Overlapped I/O or an I/O Completion Port instead. That will allow you to start an asynchronous read operation in the background and let it notify you when it has received data.