📄 pnpipe.cxx
字号:
/* * * C++ Portable Types Library (PTypes) * Version 1.7.5 Released 9-Mar-2003 * * Copyright (c) 2001, 2002, 2003 Hovik Melikyan * * http://www.melikyan.com/ptypes/ * http://ptypes.sourceforge.net/ * */#ifdef WIN32# include <windows.h>#else# include <sys/types.h># include <sys/socket.h># include <sys/un.h>#endif#include "pstreams.h"PTYPES_BEGIN#ifdef WIN32string namedpipe::realpipename(const string& pipename, const string& svrname){ if (isempty(pipename)) return nullstring; string realname = pipename; if (*pconst(pipename) == '/') { int i = rpos('/', realname); del(realname, 0, i + 1); } string s; if (isempty(svrname)) s = '.'; else s = svrname; return "\\\\" + s + "\\pipe\\" + realname;}#elsestring namedpipe::realpipename(const string& pipename){ if (isempty(pipename)) return nullstring; if (*pconst(pipename) == '/') return pipename; else return DEF_NAMED_PIPES_DIR + pipename;}bool namedpipe::setupsockaddr(const string& pipename, void* isa){ sockaddr_un* sa = (sockaddr_un*)isa; memset(sa, 0, sizeof(sockaddr_un)); sa->sun_family = AF_UNIX;#ifdef __FreeBSD__ sa->sun_len = length(pipename);#endif // copy the path name into the sockaddr structure, 108 chars max (?) if (length(pipename) + 1 > (int)sizeof(sa->sun_path)) return false; strcpy(sa->sun_path, pipename); return true;}#endifnamedpipe::namedpipe() : fdxstm(), pipename(), svhandle(invhandle){ initovr();}namedpipe::namedpipe(const string& ipipename) : fdxstm(), pipename(), svhandle(invhandle){ pipename = realpipename(ipipename); initovr();}#ifdef WIN32namedpipe::namedpipe(const string& ipipename, const string& servername) : fdxstm(), pipename(), svhandle(invhandle){ pipename = realpipename(ipipename, servername); initovr();}void namedpipe::initovr(){ ovr.hEvent = CreateEvent(0, false, false, 0);}#endifnamedpipe::~namedpipe(){ cancel();#ifdef WIN32 CloseHandle(ovr.hEvent);#endif}string namedpipe::get_streamname(){ return pipename;}void namedpipe::set_pipename(const string& newvalue){ close(); pipename = realpipename(newvalue);}void namedpipe::set_pipename(const char* newvalue){ close(); pipename = realpipename(newvalue);}int namedpipe::doseek(int, ioseekmode){ return -1;}void namedpipe::doopen(){#ifdef WIN32 if (svhandle != invhandle) handle = svhandle; else { int tries = DEF_PIPE_OPEN_RETRY; int delay = DEF_PIPE_OPEN_TIMEOUT / 2;retry: SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; handle = int(CreateFile(pipename, GENERIC_READ | GENERIC_WRITE, 0, &sa, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0)); if (handle == invhandle) { if (GetLastError() == ERROR_PIPE_BUSY) { if (--tries > 0) { delay *= 2; Sleep(delay); goto retry; } else error(EIO, "Pipe busy"); } else error(uerrno(), "Couldn't open named pipe"); } }#else if (svhandle != invhandle) { if ((handle = ::accept(svhandle, 0, 0)) < 0) error(uerrno(), "Couldn't create local socket"); } else { sockaddr_un sa; if (!setupsockaddr(pipename, &sa)) error(ERANGE, "Socket name too long"); // cteate a client socket if ((handle = ::socket(sa.sun_family, SOCK_STREAM, 0)) < 0) error(uerrno(), "Couldn't create local socket"); // ... and connect to the local socket if (::connect(handle, (sockaddr*)&sa, sizeof(sa)) < 0) { int e = uerrno(); doclose(); error(e, "Couldn't connect to local socket"); } }#endif}#ifdef WIN32int namedpipe::dorawread(char* buf, int count){ unsigned long ret = uint(-1); ovr.Offset = 0; ovr.OffsetHigh = 0; if (!ReadFile(HANDLE(handle), buf, count, &ret, &ovr)) { if (GetLastError() == ERROR_IO_PENDING) { if (WaitForSingleObject(ovr.hEvent, DEF_PIPE_TIMEOUT) == WAIT_TIMEOUT) error(EIO, "Timed out"); if (!GetOverlappedResult(HANDLE(handle), &ovr, &ret, false)) error(uerrno(), "Couldn't read"); } else error(uerrno(), "Couldn't read"); } return ret;}int namedpipe::dorawwrite(const char* buf, int count){ unsigned long ret = uint(-1); ovr.Offset = 0; ovr.OffsetHigh = 0; if (!WriteFile(HANDLE(handle), buf, count, &ret, &ovr)) { if (GetLastError() == ERROR_IO_PENDING) { if (WaitForSingleObject(ovr.hEvent, DEF_PIPE_TIMEOUT) == WAIT_TIMEOUT) error(EIO, "Timed out"); if (!GetOverlappedResult(HANDLE(handle), &ovr, &ret, false)) error(uerrno(), "Couldn't write"); } else error(uerrno(), "Couldn't write"); } return ret;}#endifvoid namedpipe::doclose(){#ifdef WIN32 if (svhandle != invhandle) DisconnectNamedPipe(HANDLE(handle)); #endif svhandle = invhandle; fdxstm::doclose();}void namedpipe::flush(){#ifdef WIN32 if (!cancelled) FlushFileBuffers(HANDLE(handle));#endif fdxstm::flush();}PTYPES_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -