You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libUDPTCPNetwork/unix.cc

211 lines
3.6 KiB

/*
*
*/
#include <stdio.h>
#include <unistd.h> /* close() */
#include <stdlib.h>
#include <string.h> /* memset() */
#include <errno.h>
#include <string.h>
#include "UDPTCPNetwork.h"
// for now no support on windows
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#warning UNIX socket are not supported on windows.
#else
UNIX::~UNIX() {
Close();
}
UNIX::UNIX() {
sock = 0;
fname = "";
writecnt = 0;
readcnt = 0;
};
UNIX::UNIX (int fd, string filename) {
sock = fd;
fname = filename;
writecnt = 0;
readcnt = 0;
};
int UNIX::Listen(string filename) {
char buffer[NET_BUFFERSIZE];
int err, i;
struct sockaddr_un addr;
if (sock > 0) Close();
unlink(filename.c_str());
memset (&addr,0, sizeof addr);
addr.sun_family = AF_UNIX;
strncpy (addr.sun_path, filename.c_str(), sizeof (addr.sun_path));
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
sock = 0;
return 0;
}
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
close (sock);
sock = 0;
return 0;
}
if (listen(sock, 8) == -1) {
close (sock);
sock = 0;
return 0;
}
return 1;
};
UNIX* UNIX::Accept() {
fd_set rfds;
struct timeval tv;
int retval, newsock, err, i;
char host[NET_BUFFERSIZE];
char port[NET_BUFFERSIZE];
UNIX *named = NULL;
struct sockaddr_storage cli_addr;
unsigned int cli_len;
if (sock <= 0) return NULL;
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 1000;
retval = select (sock+1, &rfds, NULL, NULL, &tv);
if (retval == -1 && errno == EINTR) {
retval = 0;
}
else if (retval == -1) {
return NULL;
}
else if (retval) {
newsock = accept (sock, NULL, NULL);
if (newsock < 0) {
return NULL;
}
named = new UNIX(newsock, fname);
return named;
}
return NULL;
}
int UNIX::Connect(string filename) {
struct sockaddr_un addr;
if (sock > 0) Close();
memset (&addr,0, sizeof addr);
addr.sun_family = AF_UNIX;
strncpy (addr.sun_path, filename.c_str(), sizeof (addr.sun_path));
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
return 0;
}
if (connect(sock,(struct sockaddr *) &addr, sizeof (addr)) == -1) {
close (sock);
sock = -1;
return 0;
}
return 1;
};
long int UNIX::Read(char *buffer, long int len) {
long int len_ = len;
if (sock <= 0) return -2;
len_ = read (sock, (void*)buffer, len);
if (len_ < 0 && errno == EAGAIN) len_ = 0;
else if (len_ < 0 && errno != EAGAIN) {
len_ = -2;
}
else if (len_ == 0) len_ = -1;
if (len_ < 0) Close();
readcnt += len_;
return len_;
};
long int UNIX::ReadTimeout(char *buffer, long int len, int timeout) {
int data = IsData (timeout);
if (data > 0) return Read (buffer, len);
else if (data < 0) return -1;
else return 0;
};
//////////////////////////////////////////////////////////
//
// write data, generate no signal if some error occures
long int UNIX::Write(char *buffer, long int len) {
int i;
int to = NET_MAX_RETRY;
if (sock <= 0) return -1;
do {
i = send (sock, buffer, len, MSG_NOSIGNAL);
} while (i == -1 && (to--) > 0 && errno == EINTR);
if (i < 0) Close ();
writecnt += i;
return i;
};
void UNIX::Close() {
if (sock > 0) close (sock);
sock = -1;
};
int UNIX::IsConnected() {
return (sock > 0);
};
int UNIX::IsData(int timeout) {
fd_set sockset;
struct timeval tval;
if (sock <= 0) return -1;
FD_ZERO (&sockset);
FD_SET (sock, &sockset);
tval.tv_sec = timeout / 1000;
tval.tv_usec = (timeout % 1000);
if ((select (sock + 1, &sockset, NULL, NULL, &tval)) != -1) {
if (FD_ISSET (sock, &sockset)) return 1;
return 0;
}
else {
if (errno == EBADF) sock = -1;
}
return 0;
};
#endif