libwinpr-io: improve overlapped io with server-side named pipes

This commit is contained in:
Marc-André Moreau 2013-09-25 23:16:33 -04:00
parent f4e98f29ec
commit 480071cdeb
3 changed files with 94 additions and 28 deletions

View File

@ -218,13 +218,6 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
pNamedPipe->serverfd = -1;
pNamedPipe->ServerMode = FALSE;
if (0)
{
flags = fcntl(pNamedPipe->clientfd, F_GETFL);
flags = flags | O_NONBLOCK;
fcntl(pNamedPipe->clientfd, F_SETFL, flags);
}
ZeroMemory(&s, sizeof(struct sockaddr_un));
s.sun_family = AF_UNIX;
strcpy(s.sun_path, pNamedPipe->lpFilePath);
@ -249,7 +242,11 @@ HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
BOOL DeleteFileA(LPCSTR lpFileName)
{
return TRUE;
int status;
status = unlink(lpFileName);
return (status != -1) ? TRUE : FALSE;
}
BOOL DeleteFileW(LPCWSTR lpFileName)

View File

@ -36,6 +36,13 @@
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <winpr/crt.h>
#include "../handle/handle.h"
#include "../pipe/pipe.h"
@ -61,21 +68,45 @@ BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumb
if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
return FALSE;
if (pipe->clientfd == -1)
return FALSE;
lpBuffer = lpOverlapped->Pointer;
request = (DWORD) lpOverlapped->Internal;
nNumberOfBytes = (DWORD) lpOverlapped->InternalHigh;
if (request == 0)
{
if (pipe->clientfd == -1)
return FALSE;
status = read(pipe->clientfd, lpBuffer, nNumberOfBytes);
}
else
else if (request == 1)
{
if (pipe->clientfd == -1)
return FALSE;
status = write(pipe->clientfd, lpBuffer, nNumberOfBytes);
}
else if (request == 2)
{
socklen_t length;
struct sockaddr_un s;
if (pipe->serverfd == -1)
return FALSE;
length = sizeof(struct sockaddr_un);
ZeroMemory(&s, sizeof(struct sockaddr_un));
status = accept(pipe->serverfd, (struct sockaddr*) &s, &length);
if (status < 0)
return FALSE;
pipe->clientfd = status;
pipe->ServerMode = FALSE;
status = 0;
}
if (status < 0)
{

View File

@ -69,8 +69,10 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP
{
if (pReadPipe)
free(pReadPipe);
if (pWritePipe)
free(pWritePipe);
return FALSE;
}
@ -96,7 +98,6 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
int status;
HANDLE hNamedPipe;
char* lpPipePath;
unsigned long flags;
struct sockaddr_un s;
WINPR_NAMED_PIPE* pNamedPipe;
@ -134,17 +135,12 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
pNamedPipe->serverfd = socket(PF_LOCAL, SOCK_STREAM, 0);
pNamedPipe->ServerMode = TRUE;
if (0)
{
flags = fcntl(pNamedPipe->serverfd, F_GETFL);
flags = flags | O_NONBLOCK;
fcntl(pNamedPipe->serverfd, F_SETFL, flags);
}
if (PathFileExistsA(pNamedPipe->lpFilePath))
DeleteFileA(pNamedPipe->lpFilePath);
ZeroMemory(&s, sizeof(struct sockaddr_un));
s.sun_family = AF_UNIX;
strcpy(s.sun_path, pNamedPipe->lpFilePath);
unlink(s.sun_path);
status = bind(pNamedPipe->serverfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un));
@ -179,21 +175,35 @@ BOOL ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped)
pNamedPipe = (WINPR_NAMED_PIPE*) hNamedPipe;
length = sizeof(struct sockaddr_un);
ZeroMemory(&s, sizeof(struct sockaddr_un));
if (!(pNamedPipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
{
length = sizeof(struct sockaddr_un);
ZeroMemory(&s, sizeof(struct sockaddr_un));
status = accept(pNamedPipe->serverfd, (struct sockaddr*) &s, &length);
status = accept(pNamedPipe->serverfd, (struct sockaddr*) &s, &length);
if (status < 0)
return FALSE;
if (status < 0)
return FALSE;
pNamedPipe->clientfd = status;
if (pNamedPipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
pNamedPipe->clientfd = status;
pNamedPipe->ServerMode = FALSE;
}
else
{
if (!lpOverlapped)
return FALSE;
if (pNamedPipe->serverfd == -1)
return FALSE;
pNamedPipe->lpOverlapped = lpOverlapped;
/* synchronous behavior */
lpOverlapped->Internal = 2;
lpOverlapped->InternalHigh = (ULONG_PTR) 0;
lpOverlapped->Pointer = (PVOID) NULL;
SetEvent(lpOverlapped->hEvent);
}
@ -268,13 +278,41 @@ BOOL WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout)
{
int fd;
unsigned long flags;
WINPR_NAMED_PIPE* pNamedPipe;
pNamedPipe = (WINPR_NAMED_PIPE*) hNamedPipe;
if (lpMode)
{
pNamedPipe->dwPipeMode = *lpMode;
fd = (pNamedPipe->ServerMode) ? pNamedPipe->serverfd : pNamedPipe->clientfd;
if (fd == -1)
return FALSE;
flags = fcntl(fd, F_GETFL);
if (pNamedPipe->dwPipeMode & PIPE_NOWAIT)
flags = (flags | O_NONBLOCK);
else
flags = (flags & ~(O_NONBLOCK));
fcntl(fd, F_SETFL, flags);
}
if (lpMaxCollectionCount)
{
}
if (lpCollectDataTimeout)
{
}
return TRUE;
}