[Cluster-devel] conga/ricci/common ClientSocket.cpp Except.cpp ...
rmccabe at sourceware.org
rmccabe at sourceware.org
Thu Aug 30 22:50:14 UTC 2007
CVSROOT: /cvs/cluster
Module name: conga
Changes by: rmccabe at sourceware.org 2007-08-30 22:50:14
Modified files:
ricci/common : ClientSocket.cpp Except.cpp File.cpp Socket.cpp
executils.cpp
Log message:
- More cleanup
- Better error messages
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/ClientSocket.cpp.diff?cvsroot=cluster&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/Except.cpp.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/File.cpp.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/Socket.cpp.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/executils.cpp.diff?cvsroot=cluster&r1=1.9&r2=1.10
--- conga/ricci/common/ClientSocket.cpp 2007/06/25 16:03:42 1.8
+++ conga/ricci/common/ClientSocket.cpp 2007/08/30 22:50:13 1.9
@@ -13,7 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
MA 02139, USA.
*/
/*
@@ -35,200 +35,214 @@
#include <netdb.h>
-
ClientSocket::ClientSocket() :
- Socket(-1)
+ Socket(-1)
{}
ClientSocket::ClientSocket(int sock, u_int32_t addr) :
- Socket(sock),
- _addr(addr)
+ Socket(sock),
+ _addr(addr)
{}
ClientSocket::ClientSocket(const String& sock_path) :
- Socket(-1)
+ Socket(-1)
{
- _sock = socket(PF_UNIX, SOCK_STREAM, 0);
- if (_sock == -1)
- throw String("ClientSocket(String): socket() failed");
-
- struct sockaddr_un {
- sa_family_t sun_family;
- char sun_path[100];
- } addr;
- addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, sock_path.c_str(), sock_path.size()+1);
-
- if (connect(_sock, (struct sockaddr*) &addr, sizeof(addr))) {
- throw String("ClientSocket(String): connect() failed");
- }
-
- // String msg = String("created client socket ") + _sock;
- // msg += ", and connected to " + sock_path;
- // log(msg, LogSocket);
-}
-
-ClientSocket::ClientSocket(const String& hostname,
- unsigned short port,
- unsigned int timeout_ms) :
- Socket(-1)
-{
- _sock = socket(PF_INET, SOCK_STREAM, 0);
- if (_sock == -1)
- throw String("ClientSocket(hostname, port, timeout): socket() failed");
-
- if (timeout_ms)
- nonblocking(true);
-
- counting_auto_ptr<Network::Hostent> ent = Network::getHostByName(hostname);
-
- char** addrs = (*ent)->h_addr_list;
- for (int i=0; addrs[i]; i++) {
- struct sockaddr_in addr_in;
- addr_in.sin_family = AF_INET;
- addr_in.sin_port = htons(port);
- addr_in.sin_addr.s_addr = *((u_int32_t*) addrs[i]);
-
- if (connect(_sock, (struct sockaddr*) &addr_in, sizeof(addr_in)) == 0) {
- // connected
- nonblocking(false);
- _addr = addr_in.sin_addr.s_addr;
- return;
- }
-
- // connect() error
- if (errno != EINPROGRESS)
- continue;
- bool can_read=false, can_write=true;
- poll(can_read, can_write, timeout_ms);
- if (can_write == false) {
- // connect() not completed
- throw String("ClientSocket(hostname, port, timeout): connect() timed out");
- }
- // connect() completed, check successfulness
- int err = 1;
- socklen_t err_size = sizeof(err);
- getsockopt(_sock, SOL_SOCKET, SO_ERROR,
- &err, &err_size);
- if (err)
- continue;
-
- // connected
- nonblocking(false);
- _addr = addr_in.sin_addr.s_addr;
- return;
- }
- throw String("ClientSocket(hostname, port, timeout): connect() failed");
+ _sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (_sock == -1) {
+ throw String("ClientSocket(String): socket() failed: ")
+ + String(strerror(errno));
+ }
+
+ struct sockaddr_un addr;
+ addr.sun_family = AF_UNIX;
+ if (sock_path.size() >= sizeof(addr.sun_path))
+ throw String("path to client unix socket is too long");
+ memcpy(addr.sun_path, sock_path.c_str(), sock_path.size()+1);
+
+ if (connect(_sock, (struct sockaddr*) &addr, sizeof(addr))) {
+ throw String("ClientSocket(String): connect() failed: ")
+ + String(strerror(errno));
+ }
+
+ //String msg = String("created client socket ") + _sock;
+ //msg += ", and connected to " + sock_path;
+ //log(msg, LogSocket);
+}
+
+ClientSocket::ClientSocket( const String& hostname,
+ unsigned short port,
+ unsigned int timeout_ms) :
+ Socket(-1)
+{
+ _sock = socket(PF_INET, SOCK_STREAM, 0);
+ if (_sock == -1) {
+ throw String("ClientSocket(hostname, port, timeout): socket() failed")
+ + String(strerror(errno));
+ }
+
+ if (timeout_ms)
+ nonblocking(true);
+
+ counting_auto_ptr<Network::Hostent> ent = Network::getHostByName(hostname);
+
+ char **addrs = (*ent)->h_addr_list;
+ for (int i = 0 ; addrs[i] ; i++) {
+ struct sockaddr_in addr_in;
+
+ addr_in.sin_family = AF_INET;
+ addr_in.sin_port = htons(port);
+ addr_in.sin_addr.s_addr = *((u_int32_t*) addrs[i]);
+
+ if (connect(_sock, (struct sockaddr *) &addr_in, sizeof(addr_in)) == 0)
+ {
+ // connected
+ nonblocking(false);
+ _addr = addr_in.sin_addr.s_addr;
+ return;
+ }
+
+ // connect() error
+ if (errno != EINPROGRESS)
+ continue;
+
+ bool can_read = false, can_write = true;
+ poll(can_read, can_write, timeout_ms);
+
+ if (can_write == false) {
+ // connect() not completed
+ throw String("ClientSocket(hostname, port, timeout): connect() timed out") + String(strerror(errno));
+ }
+
+ // connect() completed, check successfulness
+ int err = 1;
+ socklen_t err_size = sizeof(err);
+ getsockopt(_sock, SOL_SOCKET, SO_ERROR, &err, &err_size);
+
+ if (err)
+ continue;
+
+ // connected
+ nonblocking(false);
+ _addr = addr_in.sin_addr.s_addr;
+ return;
+ }
+
+ throw String("ClientSocket(hostname, port, timeout): connect() failed");
}
ClientSocket::ClientSocket(const ClientSocket& s) :
- Socket(s),
- _addr(s._addr)
+ Socket(s),
+ _addr(s._addr)
{}
-ClientSocket&
+ClientSocket&
ClientSocket::operator= (const ClientSocket& s)
{
- if (&s != this) {
- this->Socket::operator= (s);
- _addr = s._addr;
- }
- return *this;
+ if (&s != this) {
+ this->Socket::operator= (s);
+ _addr = s._addr;
+ }
+ return *this;
}
ClientSocket::~ClientSocket()
{}
-
-bool
+bool
ClientSocket::connected_to(const String& hostname)
{
- try {
- counting_auto_ptr<Network::Hostent> ent = Network::getHostByName(hostname);
- char** addrs = (*ent)->h_addr_list;
- for (int i=0; addrs[i]; i++)
- if (*((u_int32_t*) addrs[i]) == _addr)
- return true;
- } catch ( ... ) {}
- return false;
+ try {
+ counting_auto_ptr<Network::Hostent> ent = Network::getHostByName(hostname);
+ char **addrs = (*ent)->h_addr_list;
+ for (int i = 0 ; addrs[i] ; i++) {
+ if (*((u_int32_t *) addrs[i]) == _addr)
+ return true;
+ }
+ } catch ( ... ) {}
+
+ return false;
}
-String
+String
ClientSocket::recv()
{
- if (_sock == -1)
- throw String("ClientSocket::recv(): socket already closed");
-
- while (true) {
- char buffer[4096];
- int ret = ::recv(_sock, buffer, sizeof(buffer), 0);
- if (ret == -1) {
- if (errno == EINTR)
- continue;
- else if (errno == EAGAIN)
- return "";
- throw String("ClientSocket::recv(): recv error: ") + String(strerror(errno));
- }
-
- if (ret == 0) {
- close();
- throw String("ClientSocket::recv(): socket has been shutdown");
- }
-
- // log(String("received ") + ret + " bytes from socket " + _sock,
- // LogLevel(LogSocket|LogTransfer));
- String data(buffer, ret);
- shred(buffer, ret);
- return data;
- }
+ if (_sock == -1)
+ throw String("ClientSocket::recv(): socket already closed");
+
+ while (true) {
+ char buffer[4096];
+ int ret = ::recv(_sock, buffer, sizeof(buffer), 0);
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+ else if (errno == EAGAIN)
+ return "";
+ throw String("ClientSocket::recv(): recv error: ")
+ + String(strerror(errno));
+ }
+
+ if (ret == 0) {
+ close();
+ throw String("ClientSocket::recv(): socket has been shutdown");
+ }
+
+ //log(String("received ") + ret + " bytes from socket " + _sock,
+ //LogLevel(LogSocket|LogTransfer));
+ String data(buffer, ret);
+ shred(buffer, ret);
+ return data;
+ }
}
String
ClientSocket::recv(int timeout)
{
- bool in=true, out=false;
- poll(in, out, timeout);
- if (in)
- return recv();
- else
- return "";
+ bool in = true, out = false;
+
+ poll(in, out, timeout);
+ if (in)
+ return recv();
+ else
+ return "";
}
-String
+String
ClientSocket::send(const String& msg)
{
- if (_sock == -1)
- throw String("ClientSocket::send(): socket already closed");
-
- while (true) {
- int ret = ::send(_sock, msg.c_str(), msg.size(), 0);
- if (ret == -1) {
- if (errno == EINTR)
- continue;
- else if (errno == EAGAIN || errno == EWOULDBLOCK)
- return msg;
- throw String("ClientSocket::send(): socket error: ") + String(strerror(errno));
- }
-
- // log(String("sent ") + ret + " bytes thru socket " + _sock,
- // LogLevel(LogSocket|LogTransfer));
- return msg.substr(ret);
- }
+ if (_sock == -1)
+ throw String("ClientSocket::send(): socket already closed");
+
+ while (true) {
+ int ret = ::send(_sock, msg.c_str(), msg.size(), 0);
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+ else if (errno == EAGAIN || errno == EWOULDBLOCK)
+ return msg;
+ throw String("ClientSocket::send(): socket error: ")
+ + String(strerror(errno));
+ }
+
+ //log(String("sent ") + ret + " bytes thru socket " + _sock,
+ //LogLevel(LogSocket|LogTransfer));
+ return msg.substr(ret);
+ }
}
String
ClientSocket::send(const String& msg, int timeout)
{
- bool in=false, out=true;
- poll(in, out, timeout);
- if (out)
- return send(msg);
- else
- return msg;
+ bool in = false, out = true;
+
+ poll(in, out, timeout);
+ if (out)
+ return send(msg);
+ else
+ return msg;
}
-void
+void
ClientSocket::ready(bool& recv, bool& send, int timeout)
{
- poll(recv, send, timeout);
+ poll(recv, send, timeout);
}
--- conga/ricci/common/Except.cpp 2006/08/10 22:53:07 1.2
+++ conga/ricci/common/Except.cpp 2007/08/30 22:50:13 1.3
@@ -1,5 +1,5 @@
/*
- Copyright Red Hat, Inc. 2005
+ Copyright Red Hat, Inc. 2005-2007
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
@@ -13,7 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
MA 02139, USA.
*/
/*
@@ -27,26 +27,24 @@
using namespace std;
-
-Except::Except(long long error_code,
- const String& msg) :
- _code(error_code), _msg(msg)
+Except::Except(long long error_code, const String& msg) :
+ _code(error_code), _msg(msg)
{
- if (_code == generic_error)
- throw String("Exception() invalid error_code");
+ if (_code == generic_error)
+ throw String("Exception() invalid error_code");
}
Except::~Except()
{}
-long long
+long long
Except::code() const
{
- return _code;
+ return _code;
}
-String
+String
Except::description() const
{
- return _msg;
+ return _msg;
}
--- conga/ricci/common/File.cpp 2007/08/24 22:05:13 1.4
+++ conga/ricci/common/File.cpp 2007/08/30 22:50:13 1.5
@@ -1,5 +1,5 @@
/*
- Copyright Red Hat, Inc. 2006
+ Copyright Red Hat, Inc. 2006-2007
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
@@ -13,7 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
MA 02139, USA.
*/
/*
@@ -29,194 +29,197 @@
using namespace std;
-File_pimpl::File_pimpl(void* fs,
- bool& owner) :
- fs(fs)
-{
- if (fs == 0)
- throw String("fs_ptr is null!!!");
- owner = true;
+File_pimpl::File_pimpl(void *fs, bool& owner) :
+ fs(fs)
+{
+ if (fs == NULL)
+ throw String("fs_ptr is null");
+ owner = true;
}
File_pimpl::~File_pimpl()
{
- fstream* ptr = (fstream*) fs;
- delete ptr;
+ fstream *ptr = (fstream *) fs;
+ delete ptr;
}
+File
+File::open(const String& filepath, bool rw)
+{
+ if (access(filepath.c_str(), R_OK))
+ throw String("unable to read file ") + filepath;
+ ios_base::openmode mode = ios_base::in;
+ if (rw)
+ mode |= ios_base::out;
+
+ counting_auto_ptr<File_pimpl> pimpl;
+ bool ownership_taken = false;
+ fstream *fs = new fstream(filepath.c_str(), mode);
+ try {
+ pimpl = counting_auto_ptr<File_pimpl>(new File_pimpl(fs, ownership_taken));
+ } catch ( ... ) {
+ if (!ownership_taken)
+ delete fs;
+ throw;
+ }
+ return File(pimpl, filepath, rw);
+}
File
-File::open(const String& filepath,
- bool rw)
+File::create(const String& filepath, bool truncate)
{
- if (access(filepath.c_str(), R_OK))
- throw String("unable to read file ") + filepath;
- ios_base::openmode mode = ios_base::in;
- if (rw)
- mode |= ios_base::out;
-
- counting_auto_ptr<File_pimpl> pimpl;
- bool ownership_taken = false;
- fstream* fs = new fstream(filepath.c_str(), mode);
- try {
- pimpl = counting_auto_ptr<File_pimpl>(new File_pimpl(fs, ownership_taken));
- } catch ( ... ) {
- if (!ownership_taken)
- delete fs;
- throw;
- }
- return File(pimpl, filepath, rw);
-}
-
-File
-File::create(const String& filepath,
- bool truncate)
-{
- int t = ::open(filepath.c_str(),
- O_CREAT|O_RDWR,
- S_IRUSR|S_IWUSR|S_IRGRP);
- if (t != -1)
- while (close(t) && errno == EINTR)
- ;
-
- ios_base::openmode mode = ios_base::in;
- mode |= ios_base::out;
- if (truncate)
- mode |= ios_base::trunc;
-
- counting_auto_ptr<File_pimpl> pimpl;
- bool ownership_taken = false;
- fstream* fs = new fstream(filepath.c_str(), mode);
- try {
- pimpl = counting_auto_ptr<File_pimpl>(new File_pimpl(fs, ownership_taken));
- } catch ( ... ) {
- if (!ownership_taken)
- delete fs;
- throw;
- }
- return File(pimpl, filepath, true);
-}
-
-File::File(counting_auto_ptr<File_pimpl> pimpl,
- const String& path,
- bool writable) :
- _mutex(counting_auto_ptr<Mutex>(new Mutex())),
- _pimpl(pimpl),
- _path(path),
- _writable(writable)
-{
- if (!((fstream*) _pimpl->fs)->is_open())
- throw String("unable to open ") + _path;
- check_failed();
+ int t = ::open(filepath.c_str(), O_CREAT | O_RDWR, 0640);
+ if (t != -1) {
+ while (close(t) && errno == EINTR)
+ ;
+ }
+
+ ios_base::openmode mode = ios_base::in;
+ mode |= ios_base::out;
+ if (truncate)
+ mode |= ios_base::trunc;
+
+ counting_auto_ptr<File_pimpl> pimpl;
+ bool ownership_taken = false;
+ fstream *fs = new fstream(filepath.c_str(), mode);
+
+ try {
+ pimpl = counting_auto_ptr<File_pimpl>(new File_pimpl(fs, ownership_taken));
+ } catch ( ... ) {
+ if (!ownership_taken)
+ delete fs;
+ throw;
+ }
+ return File(pimpl, filepath, true);
+}
+
+File::File( counting_auto_ptr<File_pimpl> pimpl,
+ const String& path,
+ bool writable) :
+ _mutex(counting_auto_ptr<Mutex>(new Mutex())),
+ _pimpl(pimpl),
+ _path(path),
+ _writable(writable)
+{
+ if (!((fstream *) _pimpl->fs)->is_open())
+ throw String("unable to open ") + _path;
+ check_failed();
}
File::~File()
{
- if (_writable)
- ((fstream*) _pimpl->fs)->flush();
+ if (_writable)
+ ((fstream*) _pimpl->fs)->flush();
}
-String
+String
File::path() const
{
- MutexLocker l(*_mutex);
-
- return _path;
+ MutexLocker l(*_mutex);
+ return _path;
}
-long
+long
File::size() const
{
- MutexLocker l(*_mutex);
- ((fstream*) _pimpl->fs)->seekg(0, ios::end);
- check_failed();
- long s = ((fstream*) _pimpl->fs)->tellg();
- check_failed();
- if (s < 0)
- throw String("size of file ") + _path + " is negative!!!";
- return s;
+ MutexLocker l(*_mutex);
+ ((fstream *) _pimpl->fs)->seekg(0, ios::end);
+ check_failed();
+
+ long s = ((fstream *) _pimpl->fs)->tellg();
+ check_failed();
+
+ if (s < 0)
+ throw String("size of file ") + _path + " is negative";
+ return s;
}
-String
+String
File::read() const
{
- MutexLocker l(*_mutex);
-
- long len = size();
- const auto_ptr<char> buff(new char[len]);
- try {
- ((fstream*) _pimpl->fs)->seekg(0, ios::beg);
- check_failed();
- ((fstream*) _pimpl->fs)->read(buff.get(), len);
- check_failed();
- String ret(buff.get(), len);
- ::shred(buff.get(), len);
- return ret;
- } catch ( ... ) {
- ::shred(buff.get(), len);
- throw;
- }
+ MutexLocker l(*_mutex);
+
+ long len = size();
+ const auto_ptr<char> buff(new char[len]);
+ try {
+ ((fstream *) _pimpl->fs)->seekg(0, ios::beg);
+ check_failed();
+ ((fstream *) _pimpl->fs)->read(buff.get(), len);
+ check_failed();
+ String ret(buff.get(), len);
+ ::shred(buff.get(), len);
+ return ret;
+ } catch ( ... ) {
+ ::shred(buff.get(), len);
+ throw;
+ }
}
-File&
+File&
File::append(const String& data)
{
- MutexLocker l(*_mutex);
- if (!_writable)
- throw String("not writable");
- ((fstream*) _pimpl->fs)->seekp(0, ios::end);
- check_failed();
- ((fstream*) _pimpl->fs)->write(data.c_str(), data.size());
- check_failed();
- ((fstream*) _pimpl->fs)->flush();
- check_failed();
- return *this;
+ MutexLocker l(*_mutex);
+ if (!_writable)
+ throw String("not writable");
+
+ ((fstream *) _pimpl->fs)->seekp(0, ios::end);
+ check_failed();
+
+ ((fstream *) _pimpl->fs)->write(data.c_str(), data.size());
+ check_failed();
+
+ ((fstream *) _pimpl->fs)->flush();
+ check_failed();
+ return *this;
}
-String
+String
File::replace(const String& data)
{
- MutexLocker l(*_mutex);
- if (!_writable)
- throw String("not writable");
- String old(read());
- create(_path, true);
- append(data);
- return old;
+ MutexLocker l(*_mutex);
+ if (!_writable)
+ throw String("not writable");
+
+ String old(read());
+ create(_path, true);
+ append(data);
+ return old;
}
-void
+void
File::shred()
{
- MutexLocker l(*_mutex);
- if (!_writable)
- throw String("not writable");
- unsigned int len = size();
- ((fstream*) _pimpl->fs)->seekp(0, ios::beg);
- check_failed();
- // should use random source (paranoid)
- // doesn't work on journaled fss anyways
- ((fstream*) _pimpl->fs)->write(String(len, 'o').c_str(), len);
- check_failed();
+ MutexLocker l(*_mutex);
+ if (!_writable)
+ throw String("not writable");
+
+ unsigned int len = size();
+ ((fstream *) _pimpl->fs)->seekp(0, ios::beg);
+ check_failed();
+
+ // should use random source (paranoid)
+ // doesn't work on journaled fss anyways
+ ((fstream *) _pimpl->fs)->write(String(len, 'o').c_str(), len);
+ check_failed();
}
-void
+void
File::unlink()
{
- MutexLocker l(*_mutex);
- if (::unlink(_path.c_str()))
- throw String("unlink failed: " + String(strerror(errno)));
+ MutexLocker l(*_mutex);
+ if (::unlink(_path.c_str()))
+ throw String("unlink failed: " + String(strerror(errno)));
}
File::operator const String () const
{
- return read();
+ return read();
}
void
File::check_failed() const
{
- if (((fstream*) _pimpl->fs)->fail())
- throw String("IO error");
+ if (((fstream *) _pimpl->fs)->fail())
+ throw String("IO error");
}
--- conga/ricci/common/Socket.cpp 2007/08/24 22:05:14 1.7
+++ conga/ricci/common/Socket.cpp 2007/08/30 22:50:13 1.8
@@ -13,7 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
MA 02139, USA.
*/
/*
@@ -35,147 +35,152 @@
#include <fcntl.h>
#include <sys/poll.h>
-typedef struct pollfd poll_fd;
-
+typedef struct pollfd poll_fd;
-Socket::Socket(int sock) :
- _sock(sock)
+Socket::Socket(int sock) :
+ _sock(sock)
{
- try {
- _counter = counting_auto_ptr<int>(new int(1));
- } catch ( ... ) {
- close();
- throw String("Socket(int sock) failed");
- }
+ try {
+ _counter = counting_auto_ptr<int>(new int(1));
+ } catch ( ... ) {
+ close();
+ throw String("Socket(int sock) failed");
+ }
}
Socket::Socket(const Socket& s) :
- _sock(s._sock),
- _counter(s._counter)
+ _sock(s._sock),
+ _counter(s._counter)
{
- (*_counter)++;
+ (*_counter)++;
}
-Socket&
+Socket&
Socket::operator= (const Socket& s)
{
- if (&s != this) {
- decrease_counter();
- _sock = s._sock;
- _counter = s._counter;
- (*_counter)++;
- }
- return *this;
+ if (&s != this) {
+ decrease_counter();
+ _sock = s._sock;
+ _counter = s._counter;
+ (*_counter)++;
+ }
+
+ return *this;
}
Socket::~Socket()
{
- decrease_counter();
+ decrease_counter();
}
-void
+void
Socket::decrease_counter()
{
- if (--(*_counter) == 0)
- close();
+ if (--(*_counter) == 0)
+ close();
}
-
+
void
Socket::close()
{
- if (_sock != -1) {
- log(String("closing socket ") + _sock, LogSocket);
- shutdown(_sock, SHUT_RDWR);
- int e;
- do {
- e = ::close(_sock);
- } while (e && (errno == EINTR));
- }
- _sock = -1;
+ if (_sock != -1) {
+ log(String("closing socket ") + _sock, LogSocket);
+ shutdown(_sock, SHUT_RDWR);
+
+ int e;
+ do {
+ e = ::close(_sock);
+ } while (e && (errno == EINTR));
+ }
+ _sock = -1;
}
-
-bool
+bool
Socket::operator== (const Socket& obj)
{
- return obj._sock == _sock;
+ return obj._sock == _sock;
}
-int
+int
Socket::get_sock()
{
- return _sock;
+ return _sock;
}
-bool
+bool
Socket::nonblocking()
{
- if (!valid())
- throw String("socket not valid");
- int flags = fcntl(_sock, F_GETFL);
- if (flags == -1)
- throw String("fcntl(F_GETFL): " + String(strerror(errno)));
- return flags & O_NONBLOCK;
+ if (!valid())
+ throw String("socket not valid");
+
+ int flags = fcntl(_sock, F_GETFL);
+ if (flags == -1)
+ throw String("fcntl(F_GETFL): " + String(strerror(errno)));
+ return (flags & O_NONBLOCK) != 0;
}
-bool
+bool
Socket::nonblocking(bool mode)
{
- if (!valid())
- throw String("socket not valid");
- int old_flags = fcntl(_sock, F_GETFL);
- if (old_flags == -1)
- throw String("fcntl(F_GETFL): " + String(strerror(errno)));
- int new_flags;
- if (mode)
- new_flags = old_flags | O_NONBLOCK;
- else
- new_flags = old_flags & ~O_NONBLOCK;
- if (fcntl(_sock, F_SETFL, new_flags))
- throw String("fcntl(F_SETFL): " + String(strerror(errno)));
- return old_flags & O_NONBLOCK;
+ if (!valid())
+ throw String("socket not valid");
+
+ int old_flags = fcntl(_sock, F_GETFL);
+ if (old_flags == -1)
+ throw String("fcntl(F_GETFL): " + String(strerror(errno)));
+
+ int new_flags;
+ if (mode)
+ new_flags = old_flags | O_NONBLOCK;
+ else
+ new_flags = old_flags & ~O_NONBLOCK;
+
+ if (fcntl(_sock, F_SETFL, new_flags))
+ throw String("fcntl(F_SETFL): " + String(strerror(errno)));
+ return (old_flags & O_NONBLOCK) != 0;
}
void
Socket::poll(bool& read, bool& write, int timeout)
{
- if (!valid())
- throw String("socket not valid");
-
- poll_fd poll_data;
- poll_data.fd = _sock;
- poll_data.events = (read ? POLLIN : 0) | (write ? POLLOUT : 0);
-
- read = write = false;
- int beg = time_mil();
-
- while ( true ) {
- int time2wait;
- if (timeout <= 0)
- time2wait = timeout;
- else {
- time2wait = beg + timeout - time_mil();
- if (time2wait < 0)
- return;
- }
- poll_data.revents = 0;
- int ret = ::poll(&poll_data, 1, time2wait);
- if (ret == 0)
- return;
- else if (ret == -1) {
- if (errno == EINTR)
- continue;
- else
- throw String("poll() error: " + String(strerror(errno)));
- } else {
- if (poll_data.revents & POLLIN)
- read = true;
- if (poll_data.revents & POLLOUT)
- write = true;
- if (poll_data.revents & (POLLERR | POLLHUP | POLLNVAL))
- read = write = true;
- return;
- }
- }
+ if (!valid())
+ throw String("socket not valid");
+
+ poll_fd poll_data;
+ poll_data.fd = _sock;
+ poll_data.events = (read ? POLLIN : 0) | (write ? POLLOUT : 0);
+
+ read = write = false;
+ int beg = time_mil();
+
+ while (true) {
+ int time2wait;
+ if (timeout <= 0)
+ time2wait = timeout;
+ else {
+ time2wait = beg + timeout - time_mil();
+ if (time2wait < 0)
+ return;
+ }
+ poll_data.revents = 0;
+
+ int ret = ::poll(&poll_data, 1, time2wait);
+ if (ret == 0)
+ return;
+ else if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+ else
+ throw String("poll() error: " + String(strerror(errno)));
+ } else {
+ if (poll_data.revents & POLLIN)
+ read = true;
+ if (poll_data.revents & POLLOUT)
+ write = true;
+ if (poll_data.revents & (POLLERR | POLLHUP | POLLNVAL))
+ read = write = true;
+ return;
+ }
+ }
}
--- conga/ricci/common/executils.cpp 2007/06/25 16:03:42 1.9
+++ conga/ricci/common/executils.cpp 2007/08/30 22:50:13 1.10
@@ -13,7 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
MA 02139, USA.
*/
/*
@@ -36,223 +36,223 @@
-static void
-read_data(struct pollfd& poll_info,
- bool& fd_closed,
- String& data);
-static void
-close_fd(int fd);
+static void read_data(struct pollfd& poll_info, bool& fd_closed, String& data);
+static void close_fd(int fd);
-
-int
-execute(const String& path,
- const std::vector<String>& args,
- String& out,
- String& err,
- int& status,
- int timeout)
+int
+execute(const String& path,
+ const std::vector<String>& args,
+ String& out,
+ String& err,
+ int& status,
+ int timeout)
{
- if (access(path.c_str(), X_OK))
- return 1;
-
- out = err = "";
-
- int _stdout_pipe[2];
- int _stderr_pipe[2];
- if (pipe(_stdout_pipe) == -1)
- return 2;
- if (pipe(_stderr_pipe) == -1) {
- close_fd(_stdout_pipe[0]);
- close_fd(_stdout_pipe[1]);
- return 2;
- }
-
- int pid = fork();
- if (pid == -1) {
- close_fd(_stdout_pipe[0]);
- close_fd(_stdout_pipe[1]);
- close_fd(_stderr_pipe[0]);
- close_fd(_stderr_pipe[1]);
- return 3;
- }
-
- unsigned int time_beg = time_mil();
- unsigned int time_to_kill = time_beg + timeout;
-
- if (pid == 0) {
- /* child */
-
- close_fd(1);
- close_fd(_stdout_pipe[0]);
- dup2(_stdout_pipe[1], 1);
- close_fd(_stdout_pipe[1]);
-
- close_fd(2);
- close_fd(_stderr_pipe[0]);
- dup2(_stderr_pipe[1], 2);
- close_fd(_stderr_pipe[1]);
-
- int devnull = open("/dev/null", O_RDWR);
- if (devnull == -1) {
- perror("ricci::execute(): Can't open /dev/null");
- _exit(1);
- }
- close_fd(0);
- dup2(devnull, 0);
- close_fd(devnull);
-
- // close open fds
- for (unsigned int i=3; i<__FD_SETSIZE; i++)
- close_fd(i);
-
- // restore signals
- for (int x = 1; x < _NSIG; x++)
- signal(x, SIG_DFL);
- sigset_t set;
- sigfillset(&set);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
-
- setenv("LANG", "C", 1);
- setenv("LC_ALL", "C", 1);
-
- /* exec */
-
- try {
- unsigned int size = args.size() + 2;
- char** argv = new char*[size];
- argv[0] = (char*) path.c_str();
- for (unsigned int i=0; i<args.size(); i++)
- argv[i+1] = (char*) args[i].c_str();
- argv[size-1] = NULL;
-
- execv(path.c_str(), argv);
- } catch ( ... ) {}
- _exit(1);
- }
-
- /* parent */
- close_fd(_stdout_pipe[1]);
- close_fd(_stderr_pipe[1]);
- bool out_closed=false, err_closed=false;
-
- while (true) {
- // kill child if timeout elapsed
- if (timeout >= 0 &&
- time_mil() > time_to_kill)
- kill(pid, SIGKILL);
-
- // prepare poll structs
- struct pollfd poll_data[2];
- int s = 0;
- if (!out_closed) {
- poll_data[s].fd = _stdout_pipe[0];
- poll_data[s].events = POLLIN;
- poll_data[s].revents = 0;
- s += 1;
- }
- if (!err_closed) {
- poll_data[s].fd = _stderr_pipe[0];
- poll_data[s].events = POLLIN;
- poll_data[s].revents = 0;
- s += 1;
- }
- if (s == 0)
- break;
-
- // wait for events
- int ret = poll(poll_data, s, 500);
- if (ret == 0)
- continue;
- else if (ret == -1) {
- if (errno == EINTR)
- continue;
- else {
- if (!out_closed)
- close_fd(_stdout_pipe[0]);
- if (!err_closed)
- close_fd(_stderr_pipe[0]);
- return 4;
- }
- }
-
- // process events
- for (int i=0; i<s; i++) {
- struct pollfd& poll_info = poll_data[i];
- if (poll_info.fd == _stdout_pipe[0])
- read_data(poll_info, out_closed, out);
- if (poll_info.fd == _stderr_pipe[0])
- read_data(poll_info, err_closed, err);
- }
- } // while (true)
-
- // command
- String comm(path);
- for (unsigned int i=0; i<args.size(); i++)
- comm += " " + args[i];
-
- // get status
- int ret;
- do {
- ret = waitpid(pid, &status, 0);
- } while ((ret < 0) && (errno == EINTR));
-
- if (WIFEXITED(status)) {
- // log("executed \"" + comm + "\" in " + (time_mil() - time_beg) + " milliseconds", LogExecute);
- status = WEXITSTATUS(status);
- return 0;
- } else if (WIFSIGNALED(status)) {
- // log("\"" + comm + "\" killed after " + (time_mil() - time_beg) + " milliseconds", LogExecute);
- return 5;
- } else {
- // log("unknown cause of \"" + comm + "\"'s exit after " + (time_mil() - time_beg) + " milliseconds", LogExecute);
- return 6;
- }
+ if (access(path.c_str(), X_OK))
+ return 1;
+
+ out = err = "";
+
+ int _stdout_pipe[2];
+ int _stderr_pipe[2];
+
+ if (pipe(_stdout_pipe) == -1)
+ return 2;
+
+ if (pipe(_stderr_pipe) == -1) {
+ close_fd(_stdout_pipe[0]);
+ close_fd(_stdout_pipe[1]);
+ return 2;
+ }
+
+ int pid = fork();
+ if (pid == -1) {
+ close_fd(_stdout_pipe[0]);
+ close_fd(_stdout_pipe[1]);
+ close_fd(_stderr_pipe[0]);
+ close_fd(_stderr_pipe[1]);
+ return 3;
+ }
+
+ unsigned int time_beg = time_mil();
+ unsigned int time_to_kill = time_beg + timeout;
+
+ if (pid == 0) {
+ /* child */
+
+ close_fd(1);
+ close_fd(_stdout_pipe[0]);
+ dup2(_stdout_pipe[1], 1);
+ close_fd(_stdout_pipe[1]);
+
+ close_fd(2);
+ close_fd(_stderr_pipe[0]);
+ dup2(_stderr_pipe[1], 2);
+ close_fd(_stderr_pipe[1]);
+
+ int devnull = open("/dev/null", O_RDWR);
+ if (devnull == -1) {
+ perror("ricci::execute(): Can't open /dev/null");
+ _exit(1);
+ }
+
+ close_fd(0);
+ dup2(devnull, 0);
+ close_fd(devnull);
+
+ // close open fds
+ for (unsigned int i = 3; i < __FD_SETSIZE ; i++)
+ close_fd(i);
+
+ // restore signals
+ for (int x = 1 ; x < _NSIG ; x++)
+ signal(x, SIG_DFL);
+
+ sigset_t set;
+ sigfillset(&set);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+
+ setenv("LANG", "C", 1);
+ setenv("LC_ALL", "C", 1);
+
+ /* exec */
+ try {
+ unsigned int size = args.size() + 2;
+ char **argv = new char*[size];
+
+ argv[0] = (char *) path.c_str();
+ for (unsigned int i = 0 ; i < args.size() ; i++)
+ argv[i + 1] = (char *) args[i].c_str();
+ argv[size - 1] = NULL;
+ execv(path.c_str(), argv);
+ } catch ( ... ) {}
+ _exit(1);
+ }
+
+ /* parent */
+ close_fd(_stdout_pipe[1]);
+ close_fd(_stderr_pipe[1]);
+ bool out_closed = false, err_closed = false;
+
+ while (true) {
+ // kill child if timeout elapsed
+ if (timeout >= 0 && time_mil() > time_to_kill) {
+ kill(pid, SIGTERM);
+ sleep(1);
+ kill(pid, SIGKILL);
+ }
+
+ // prepare poll structs
+ struct pollfd poll_data[2];
+ int s = 0;
+ if (!out_closed) {
+ poll_data[s].fd = _stdout_pipe[0];
+ poll_data[s].events = POLLIN;
+ poll_data[s].revents = 0;
+ s += 1;
+ }
+
+ if (!err_closed) {
+ poll_data[s].fd = _stderr_pipe[0];
+ poll_data[s].events = POLLIN;
+ poll_data[s].revents = 0;
+ s += 1;
+ }
+
+ if (s == 0)
+ break;
+
+ // wait for events
+ int ret = poll(poll_data, s, 500);
+ if (ret == 0)
+ continue;
+ else if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+ else {
+ if (!out_closed)
+ close_fd(_stdout_pipe[0]);
+ if (!err_closed)
+ close_fd(_stderr_pipe[0]);
+ return 4;
+ }
+ }
+
+ // process events
+ for (int i = 0 ; i < s ; i++) {
+ struct pollfd& poll_info = poll_data[i];
+
+ if (poll_info.fd == _stdout_pipe[0])
+ read_data(poll_info, out_closed, out);
+ if (poll_info.fd == _stderr_pipe[0])
+ read_data(poll_info, err_closed, err);
+ }
+ } // while (true)
+
+ // command
+ String comm(path);
+ for (unsigned int i = 0 ; i < args.size() ; i++)
+ comm += " " + args[i];
+
+ // get status
+ int ret;
+ do {
+ ret = waitpid(pid, &status, 0);
+ } while ((ret < 0) && (errno == EINTR));
+
+ if (WIFEXITED(status)) {
+ //log("executed \"" + comm + "\" in " + (time_mil() - time_beg) + " milliseconds", LogExecute);
+ status = WEXITSTATUS(status);
+ return 0;
+ } else if (WIFSIGNALED(status)) {
+ //log("\"" + comm + "\" killed after " + (time_mil() - time_beg) + " milliseconds", LogExecute);
+ return 5;
+ } else {
+ //log("unknown cause of \"" + comm + "\"'s exit after " + (time_mil() - time_beg) + " milliseconds", LogExecute);
+ return 6;
+ }
}
-void
-read_data(struct pollfd& poll_info,
- bool& fd_closed,
- String& data)
+void
+read_data(struct pollfd& poll_info, bool& fd_closed, String& data)
{
- int fd = poll_info.fd;
-
- if (poll_info.revents & POLLIN) {
- try {
- char data_in[4096];
- int ret = read(fd, data_in, sizeof(data_in));
- if (ret < 0)
- return;
- if (ret == 0) {
- close_fd(fd);
- fd_closed = true;
- return;
- }
- data.append(data_in, ret);
- if (ret == sizeof(data_in))
- return;
- } catch ( ... ) {
- close_fd(fd);
- fd_closed = true;
- }
- }
-
- if (poll_info.revents & (POLLERR | POLLHUP | POLLNVAL)) {
- close_fd(fd);
- fd_closed = true;
- return;
- }
+ int fd = poll_info.fd;
+
+ if (poll_info.revents & POLLIN) {
+ try {
+ char data_in[4096];
+ int ret = read(fd, data_in, sizeof(data_in));
+ if (ret < 0)
+ return;
+ if (ret == 0) {
+ close_fd(fd);
+ fd_closed = true;
+ return;
+ }
+ data.append(data_in, ret);
+ if (ret == sizeof(data_in))
+ return;
+ } catch ( ... ) {
+ close_fd(fd);
+ fd_closed = true;
+ }
+ }
+
+ if (poll_info.revents & (POLLERR | POLLHUP | POLLNVAL)) {
+ close_fd(fd);
+ fd_closed = true;
+ return;
+ }
}
void
close_fd(int fd)
{
- int e;
- do {
- e = close(fd);
- } while (e && (errno == EINTR));
+ int e;
+ do {
+ e = close(fd);
+ } while (e && (errno == EINTR));
}
-
/*
#include <iostream>
using namespace std;
@@ -260,25 +260,25 @@
int
main(int argc, char** argv)
{
- String out, err;
- int status;
- vector<String> arguments;
-
- String path;
- if (argc < 2) {
- cout << "enter path to execute: ";
- cin >> path;
- } else
- path = argv[1];
-
- for (int i=2; i<argc; i++)
- arguments.push_back(argv[i]);
-
- cout << "executing " << path << endl;
- cout << execute(path, arguments, out, err, status) << endl;
-
- cout << "stdout:" << endl << out << endl << endl;
- cout << "stderr:" << endl << err << endl << endl;
- cout << "status: " << status << endl;
+ String out, err;
+ int status;
+ vector<String> arguments;
+
+ String path;
+ if (argc < 2) {
+ cout << "enter path to execute: ";
+ cin >> path;
+ } else
+ path = argv[1];
+
+ for (int i=2; i<argc; i++)
+ arguments.push_back(argv[i]);
+
+ cout << "executing " << path << endl;
+ cout << execute(path, arguments, out, err, status) << endl;
+
+ cout << "stdout:" << endl << out << endl << endl;
+ cout << "stderr:" << endl << err << endl << endl;
+ cout << "status: " << status << endl;
}
*/
More information about the Cluster-devel
mailing list