/* * */ #include #include /* close() */ #include #include /* memset() */ #include #include #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