#if !defined(__linux__) && !defined(ANDROID)
#include <winsock2.h>
typedef SOCKET socket_t; /* https://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c */
#ifndef SHUT_WR
#define SHUT_WR SD_SEND
#endif
#ifndef SHUT_RD
#define SHUT_RD SD_RECEIVE
#endif
#define close(s) closesocket(s)
#ifndef messagebox
#define messagebox(str) MessageBoxA(NULL,str,"win32_pipe",0);
#endif
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
typedef int socket_t;
#define INVALID_SOCKET -1
#endif
#ifndef FILLIPV4ADDR
#define FILLIPV4ADDR(a,family,addr,port) \
memset(&(a),0,sizeof(struct sockaddr_in)),\
s.sin_family=family,\
s.sin_addr.s_addr=addr,\
s.sin_port=htons(port)
#endif
#if 1
#include <stdio.h>
#endif
static int *
win32pipe_initvalue(void)
{
static int init=0;
return(&init);
}
int
win32pipe_init(void)
{
int *init;
init=win32pipe_initvalue();
if(*init!=0)
return(0);
*init=1;
#if !defined(__linux__) && !defined(ANDROID)
{
WSADATA wsaData;
return(WSAStartup(0x202,&wsaData));
}
#else
return(0);
#endif
}
void
win32pipe_fini(void)
{
int *init;
init=win32pipe_initvalue();
if(*init==0)
return;
#if !defined(__linux__) && !defined(ANDROID)
WSACleanup();
#endif
*init=0;
}
int
win32pipe_pipe(int fds[2])
{
socket_t serverfd,workfd,clientfd;
struct sockaddr_in s;
int sizes;
unsigned char *ip;
char *errstr;
win32pipe_init();
FILLIPV4ADDR(s,AF_INET,htonl(INADDR_ANY),0);
ip=(unsigned char *) &(s.sin_addr.s_addr);
ip[0]=127,ip[1]=0,ip[2]=0,ip[3]=1;
serverfd=workfd=clientfd=INVALID_SOCKET;
if((errstr="Couldn't create server socket")==NULL
|| (serverfd=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET
|| (errstr="Couldn't bind server socket")==NULL
|| bind(serverfd,(struct sockaddr *)&s,sizeof(s))!=0
|| (errstr="Couldn't listen on server socket")==NULL
|| listen(serverfd,4)==-1
|| (sizes=sizeof(s))!=sizeof(s)
|| (errstr="Couldn't get server socket name")==NULL
|| getsockname(serverfd,(struct sockaddr *)&s,&sizes)==-1
|| (errstr="Couldn't create client socket")==NULL
|| (clientfd=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET
|| (errstr="Couldn't connect client socket to server socket")==NULL
|| connect(clientfd,(struct sockaddr *)&s,sizeof(s))==-1
|| (errstr="Couldn't accept client socket connection to server socket")==NULL
|| (workfd=accept(serverfd,(struct sockaddr *)&s,&sizes))==-1
) {
{
char errbuf[4096];
unsigned char *ip;
int port;
if(strcmp(errstr,"Couldn't connect client socket to server socket")==0) {
ip=(unsigned char *) &(s.sin_addr.s_addr);
port=ntohs(s.sin_port);
snprintf(errbuf,sizeof(errbuf),"%s\nWinsock error: %ld\nRemote address:%i.%i.%i.%i\nRemote port:%i"
,errstr
,WSAGetLastError()
,(int)(ip[0]),(int)(ip[1]),(int)(ip[2]),(int)(ip[3])
,port
);
} else {
snprintf(errbuf,sizeof(errbuf),"%s\nWinsock error: %ld",errstr,WSAGetLastError());
}
errbuf[sizeof(errbuf)-1]='\0';
messagebox(errbuf);
}
if(serverfd!=-1)
close(serverfd),serverfd=-1;
if(clientfd!=-1)
close(clientfd),clientfd=-1;
if(workfd!=-1)
close(workfd),workfd=-1;
return(-1);
}
close(serverfd),serverfd=-1;
shutdown(workfd,SHUT_WR);
shutdown(clientfd,SHUT_RD);
fds[0]=workfd,workfd=-1;
fds[1]=clientfd,clientfd=-1;
return(0);
}
int
win32pipe_read(int fd, char *buf, int count)
{
return(recv(fd,buf,count,0));
}
int
win32pipe_write(int fd, char *buf, int count)
{
return(send(fd,buf,count,0));
}