⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unix.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however    // invalidate any other reasons why the executable file might be covered by// the GNU General Public License.    //// This exception applies only to the code released under the name GNU// Common C++.  If you copy code from other releases into a copy of GNU// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include <cc++/config.h>#include <cc++/address.h>#include <cc++/socket.h>#include <cc++/file.h>#include <cc++/thread.h>#include <cc++/exception.h>#include <cc++/export.h>#include <cc++/unix.h>#include <cc++/unix.h>#include <fcntl.h>#include <cerrno>#include <cstdlib>#ifndef	WIN32#include <netinet/tcp.h>#include <sys/un.h>#endif#ifdef	WIN32#include <io.h>#endif#ifdef	CCXX_NAMESPACESnamespace ost {using namespace std;#endif#ifndef WIN32UnixSocket::UnixSocket(const char* pathname, int backlog) : Socket(AF_UNIX, SOCK_STREAM, 0) {	struct sockaddr_un addr;	socklen_t len;	unsigned slen = strlen(pathname);	if(slen > sizeof(addr.sun_path))		slen = sizeof(addr.sun_path);	path = NULL; 	memset(&addr, 0, sizeof(addr)); 	addr.sun_family = AF_UNIX; 	memcpy( addr.sun_path, pathname, slen );#ifdef	__SUN_LEN	len = sizeof(addr.sun_len) + strlen(addr.sun_path) + sizeof(addr.sun_family) + 1;	addr.sun_len = len;#else	len = strlen(addr.sun_path) + sizeof(addr.sun_family) + 1;#endif	remove(pathname); 	if(bind(so, (struct sockaddr *)&addr, len)) 	{ 		endSocket(); 		error(errBindingFailed); 		return; 	}	path = new char[slen + 1];	strcpy(path, pathname); 	if(listen(so, backlog)) 	{ 		endSocket(); 		error(errBindingFailed); 		return; 	} 	state = BOUND; }UnixSocket::~UnixSocket(){	close();}void UnixSocket::close(void){	endSocket();	if(path)	{		remove(path);		delete[] path;		path = NULL;	}}UnixStream::UnixStream(UnixSocket &server, int size, bool throwflag, timeout_t to) : 	Socket(accept(server.so, NULL, NULL)) 	,streambuf() #ifdef	HAVE_OLD_IOSTREAM 	,iostream() #else 	,iostream((streambuf *)this) #endif 	,bufsize(0) 	,gbuf(NULL) 	,pbuf(NULL) { #ifdef	HAVE_OLD_IOSTREAM 	init((streambuf *)this); #endif 	timeout = to; 	setError(throwflag); 	allocate(size); 	Socket::state = CONNECTED; } UnixStream::UnixStream(const char* pathname, int size, bool throwflag, timeout_t to) : 	Socket(AF_UNIX, SOCK_STREAM, 0), 	streambuf(), #ifdef	HAVE_OLD_IOSTREAM 	iostream(), #else         iostream((streambuf *)this), #endif 	bufsize(0),gbuf(NULL),pbuf(NULL) { #ifdef	HAVE_OLD_IOSTREAM 	init((streambuf *)this); #endif 	timeout = to; 	setError(throwflag); 	connect(pathname, size); } UnixStream::~UnixStream() {	endStream(); } void UnixStream::connect(const char* pathname, int size) {        struct sockaddr_un addr;        socklen_t len;	unsigned slen = strlen(pathname);	if(slen > sizeof(addr.sun_path))		slen = sizeof(addr.sun_path); 	memset(&addr, 0, sizeof(addr)); 	addr.sun_family = AF_UNIX; 	memcpy( addr.sun_path, pathname, slen );#ifdef	__SUN_LEN	len = sizeof(addr.sun_len) + strlen(addr.sun_path) + sizeof(addr.sun_family) + 1;	addr.sun_len = len;#else	len = strlen(addr.sun_path) + sizeof(addr.sun_family);#endif 	if(::connect(so, (struct sockaddr *)&addr, len) != 0) 	{ 		connectError(); 		endSocket(); 		return; 	} 	allocate(size); 	Socket::state = CONNECTED; } UnixStream::UnixStream(bool throwflag) : 	Socket(PF_UNIX, SOCK_STREAM, 0), 	streambuf(), #ifdef	HAVE_OLD_IOSTREAM 	iostream(), #else         iostream((streambuf *)this), #endif 	 timeout(0),         bufsize(0),gbuf(NULL),pbuf(NULL) { #ifdef	HAVE_OLD_IOSTREAM 	init((streambuf *)this); #endif 	setError(throwflag); } UnixStream::UnixStream(const UnixStream &source) : Socket(dup(source.so)), streambuf(), #ifdef	HAVE_OLD_IOSTREAM iostream() #else iostream((streambuf *)this) #endif { #ifdef	HAVE_OLD_IOSTREAM 	init((streambuf *)this); #endif 	bufsize = source.bufsize; 	allocate(bufsize); } void UnixStream::endStream(void) { 	if(bufsize) sync();	if(gbuf)	 	delete[] gbuf;	if(pbuf)	 	delete[] pbuf; 	gbuf = pbuf = NULL; 	bufsize = 0; 	endSocket(); } void UnixStream::allocate(int size) { 	if(size < 2) 	{ 		bufsize = 1; 		return; 	} 	gbuf = new char[size]; 	pbuf = new char[size]; 	if(!pbuf || !gbuf) 	{ 		error(errResourceFailure); 		return; 	} 	bufsize = size; 	clear(); #if (defined(__GNUC__) && (__GNUC__ < 3)) && !defined(WIN32) && !defined(STLPORT) 	setb(gbuf, gbuf + size, 0); #endif 	setg(gbuf, gbuf + size, gbuf + size); 	setp(pbuf, pbuf + size); } int UnixStream::doallocate() { 	if(bufsize) 		return 0; 	allocate(1); 	return 1; } int UnixStream::uflow(void) { 	int ret = underflow(); 	if (ret == EOF) 		return EOF; 	if (bufsize != 1) 		gbump(1); 	return ret; } int UnixStream::underflow(void) { 	int rlen = 1; 	unsigned char ch; 	if(bufsize == 1) 	{ 		if(Socket::state == STREAM) 			rlen = ::read(so, (char *)&ch, 1); 		else if(timeout && !Socket::isPending(pendingInput, timeout))         {             clear(ios::failbit | rdstate());             error(errTimeout);             return EOF; 		} 		else 			rlen = ::recv(so, (char *)&ch, 1, 0); 		if(rlen < 1) 		{ 			if(rlen < 0) 			{ 				clear(ios::failbit | rdstate()); 				error(errInput); 			} 			return EOF; 		} 		return ch; 	} 	if(!gptr()) 		return EOF; 	if(gptr() < egptr()) 		return (unsigned char)*gptr(); 	rlen = (gbuf + bufsize) - eback(); 	if(Socket::state == STREAM) 		rlen = ::read(so, (char *)eback(), rlen); 	else if(timeout && !Socket::isPending(pendingInput, timeout)) 	{ 		clear(ios::failbit | rdstate()); 		error(errTimeout); 		return EOF; 	} 	else 		rlen = ::recv(so, (char *)eback(), rlen, 0); 	if(rlen < 1) 	{ 		if(rlen < 0) 		{ 			clear(ios::failbit | rdstate()); 			error(errInput); 		} 		return EOF; 	} 	setg(eback(), eback(), eback() + rlen); 	return (unsigned char) *gptr(); } bool UnixStream::isPending(Pending pending, timeout_t timeout) { 	if(pending == pendingInput && in_avail()) 		return true; 	else if(pending == pendingOutput) 		flush(); 	return Socket::isPending(pending, timeout); } int UnixStream::sync(void) { 	overflow(EOF); 	setg(gbuf, gbuf + bufsize, gbuf + bufsize); 	return 0; } int UnixStream::overflow(int c) { 	unsigned char ch; 	int rlen, req; 	if(bufsize == 1) 	{ 		if(c == EOF) 			return 0; 		ch = (unsigned char)(c); 		if(Socket::state == STREAM) 			rlen = ::write(so, (const char *)&ch, 1); 		else 			rlen = ::send(so, (const char *)&ch, 1, 0); 		if(rlen < 1) 		{ 			if(rlen < 0) 			{ 				clear(ios::failbit | rdstate()); 				error(errOutput); 			} 			return EOF; 		} 		else 			return c; 	} 	if(!pbase()) 		return EOF; 	req = pptr() - pbase(); 	if(req) 	{ 		if(Socket::state == STREAM) 			rlen = ::write(so, (const char *)pbase(), req); 		else 			rlen = ::send(so, (const char *)pbase(), req, 0); 		if(rlen < 1) 		{ 			if(rlen < 0) 			{ 				clear(ios::failbit | rdstate()); 				error(errOutput); 			} 			return EOF; 		} 		req -= rlen; 	} 	// if write "partial", rebuffer remainder 	if(req) 		memcpy(pptr(), pptr() + rlen, req); 	setp(pbuf + req, pbuf + bufsize); 	if(c != EOF) 	{ 		*pptr() = (unsigned char)c; 		pbump(1); 	} 	return c; } unixstream::unixstream() : UnixStream() { 	setError(false);	/* no exceptions */ } unixstream::unixstream(const char *pathname, int buf) : UnixStream() { 	setError(false); 	open(pathname, buf); } unixstream::unixstream(UnixSocket &server, int buf) : UnixStream() { 	setError(false); 	open(server, buf); } bool unixstream::operator!() const { 	return (Socket::state != CONNECTED) ? true : false; } void unixstream::open(UnixSocket &unixsock, int buf) { 	endStream(); 	so = accept(unixsock.so, NULL, NULL); 	if(so == INVALID_SOCKET) 		return; 	allocate(buf); 	Socket::state = CONNECTED; } void unixstream::close(void) { 	if(Socket::state == AVAILABLE) 		return; 	endStream(); 	so = socket(AF_UNIX, SOCK_STREAM, 0); 	if(so != INVALID_SOCKET) 		Socket::state = AVAILABLE; } UnixSession::UnixSession(const char* pathname, int size, int pri, int stack) : Thread(pri, stack), UnixStream() {        struct sockaddr_un addr;	unsigned slen = strlen(pathname);	if(slen > sizeof(addr.sun_path))		slen = sizeof(addr.sun_path); 	socklen_t len; 	setCompletion(false); 	setError(false); 	allocate(size); 	memset(&addr, 0, sizeof(addr)); 	addr.sun_family = AF_UNIX; 	memcpy( addr.sun_path, pathname, slen );#ifdef	__SUN_LEN	len = sizeof(addr.sun_len) + strlen(addr.sun_path) + sizeof(addr.sun_family) + 1;	addr.sun_len = len;#else	len = strlen(addr.sun_path) + sizeof(addr.sun_family);#endif 	if(::connect(so, (struct sockaddr *)&addr, len ) != 0) 	{ #ifdef WIN32 		if( WSAGetLastError() == WAEISCONN ) #else 		if( EINPROGRESS == errno ) #endif 		{ 			Socket::state = CONNECTING; 		} 		else 		{ 			endSocket(); 			Socket::state = INITIAL; 		} 		return; 	} 	setCompletion(true); 	Socket::state = CONNECTED; } UnixSession::UnixSession(UnixSocket &s,int size, int pri, int stack) : Thread(pri, stack), UnixStream(s, size) { 	setCompletion(true); 	setError(false); } UnixSession::~UnixSession() {	terminate();	endStream(); } int UnixSession::waitConnection(timeout_t timeout) { 	long sockopt = 0; 	socklen_t len = sizeof(sockopt); 	switch(Socket::state) 	{ 	case INITIAL: 		return -1; 	case CONNECTED: 		break; 	case CONNECTING: 		if(!Socket::isPending(pendingOutput, timeout)) 		{ 			endSocket(); 			Socket::state = INITIAL; 			return -1; 		} 		getsockopt(so, SOL_SOCKET, SO_ERROR, (char *)&sockopt, &len); 		if(sockopt) 		{ 			endSocket(); 			Socket::state = INITIAL; 			return -1; 		}	case AVAILABLE:	case BOUND:	case STREAM:		break;		 	} 	Socket::state = CONNECTED; 	return 0; } void UnixSession::initial(void) { 	if(waitConnection(60000)) 		exit(); }#endif // ndef WIN32 #ifdef	CCXX_NAMESPACES}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -