Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

172 lines
3.4 KiB
C

// mqueue.h
// Copyright 2016 Robin.Rowe@Cinepaint.org
// License open source MIT
#ifndef mqueue_h
#define mqueue_h
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include "../portable/SystemLog.h"
#ifndef __cplusplus
#error
#endif
struct mq_attr
{ int mq_flags;
int mq_maxmsg;
int mq_msgsize;
int mq_curmsgs;
};
typedef intptr_t mqd_t;
inline
int MultiByteToWideChar(LPCSTR lpMultiByteStr,LPWSTR lpWideCharStr,int bufsize)
{ UINT codePage=CP_UTF8;
DWORD dwFlags=0;
int cbMultiByte=-1;
return MultiByteToWideChar(codePage,
dwFlags,
lpMultiByteStr,
cbMultiByte,
lpWideCharStr,
bufsize);
}
/* man mq_open:
Each message queue is identified by a name of the form '/somename'.
That is, a null-terminated string of up to NAME_MAX (i.e., 255)
characters consisting of an initial slash, followed by one or
more characters, none of which are slashes.
*/
inline
mqd_t mq_open(const char *name,int oflag,mode_t mode,mq_attr* attr=0)
{ const size_t bufsize=80;
char pipeName[bufsize];
#pragma warning(disable:4996)
// This name must have the following form:
// LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");
strcpy(pipeName,"\\\\.\\pipe\\");
strcat(pipeName,name+1);
if(strchr(pipeName,'/'))
{ TRACE("Invalid mq_open");
return -1;
}
if(oflag & O_CREAT)
{ DWORD openMode = 0;
switch(oflag)
{ default:
return (mqd_t) -1;
case O_CREAT | O_RDONLY:
openMode = PIPE_ACCESS_INBOUND;
break;
case O_CREAT | O_WRONLY:
openMode = PIPE_ACCESS_OUTBOUND;
break;
case O_CREAT | O_RDWR:
openMode = PIPE_ACCESS_DUPLEX;
break;
}
DWORD pipeMode = PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS;
DWORD kernelBufsize = 512;
HANDLE hPipe = CreateNamedPipe(
pipeName,
openMode,
pipeMode,
PIPE_UNLIMITED_INSTANCES,
kernelBufsize,
kernelBufsize,
NULL,
NULL);
if (hPipe == INVALID_HANDLE_VALUE)
{ TRACE(0);
return -1;
}
BOOL ok = ConnectNamedPipe(hPipe,NULL);
if(!ok)
{ TRACE(0);
return -1;
}
return (mqd_t) hPipe;
}
DWORD dwDesiredAccess=0;
DWORD dwShareMode=0;
switch(oflag)
{ case O_RDONLY:
dwDesiredAccess|=GENERIC_READ;
dwShareMode|=FILE_SHARE_READ;
break;
case O_WRONLY:
dwDesiredAccess|=GENERIC_WRITE;
dwShareMode|=FILE_SHARE_WRITE;
break;
case O_RDWR:
dwDesiredAccess=GENERIC_READ | GENERIC_WRITE;
dwShareMode=FILE_SHARE_READ | FILE_SHARE_WRITE;
break;
}
HANDLE hPipe = CreateFileA(pipeName,
dwDesiredAccess,
dwShareMode,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hPipe == INVALID_HANDLE_VALUE)
{ TRACE(0);
return -1;
}
return (mqd_t) hPipe;
}
inline
int mq_send(mqd_t mqdes, const char *buffer,size_t bufsize, unsigned msg_prio)
{ if(msg_prio!=0)
{ return -1;
}
HANDLE h = (HANDLE) mqdes;
DWORD cbWritten;
const BOOL ok = WriteFile(h,buffer,(DWORD)bufsize,&cbWritten,NULL);
if (!ok)
{ TRACE(0);
return -1;
}
return cbWritten;
}
inline
ssize_t mq_receive(mqd_t mqdes,char* buffer,size_t bufsize,unsigned* msg_prio)
{ if(msg_prio!=0)
{ TRACE(0);
return -1;
}
HANDLE h = (HANDLE) mqdes;
DWORD numRead;
const BOOL ok = ReadFile(h,buffer,(DWORD) bufsize,&numRead,NULL);
if(!ok) // || msgSize != numRead)
{ TRACE(0);
return -1;
}
return numRead;
}
inline
int mq_close(mqd_t mqdes)
{ if(mqdes < 0)
{ return -1;
}
const BOOL ok = CloseHandle((HANDLE)mqdes);
return ok ? 0:-1;
}
inline
int mq_unlink(const char* name)
{ (void) name;
return 0;
}
#endif