From b1955a081e35515f388e04acdfd9418c5c14eef4 Mon Sep 17 00:00:00 2001 From: randomdan Date: Thu, 15 Dec 2011 01:32:39 +0000 Subject: Don't override Glib IOChannel interfaces in procrows, that's deprecated. Instead, fork and exec, adds support for passing parameters to a command explicitly with a parameter set --- project2/common/fileStarGlibIoChannel.cpp | 66 ------------------------------- project2/common/fileStarGlibIoChannel.h | 26 ------------ project2/files/fileRows.cpp | 20 +++++----- project2/files/fileRows.h | 5 ++- project2/processes/procRows.cpp | 38 +++++++++++------- project2/processes/procRows.h | 10 +++-- 6 files changed, 45 insertions(+), 120 deletions(-) delete mode 100644 project2/common/fileStarGlibIoChannel.cpp delete mode 100644 project2/common/fileStarGlibIoChannel.h diff --git a/project2/common/fileStarGlibIoChannel.cpp b/project2/common/fileStarGlibIoChannel.cpp deleted file mode 100644 index 15f9f06..0000000 --- a/project2/common/fileStarGlibIoChannel.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include "fileStarGlibIoChannel.h" -#include -#include -#include -#include - -FileStarChannel::FileStarChannel(FILE * f, bool seekable, int (*closer)(FILE*)) : - Glib::IOChannel(), - file(f, closer) -{ - gobj()->is_seekable = seekable ? 1 : 0; - gobj()->is_readable = 1; - gobj()->is_writeable = 0; -} - -FileStarChannel::~FileStarChannel() -{ -} - -Glib::IOStatus -FileStarChannel::close_vfunc() -{ - if (file) { - file.reset(); - } - return Glib::IO_STATUS_NORMAL; -} - -Glib::IOStatus -FileStarChannel::set_flags_vfunc(Glib::IOFlags) -{ - return Glib::IO_STATUS_NORMAL; -} - -Glib::IOFlags -FileStarChannel::get_flags_vfunc() -{ - return Glib::IO_FLAG_IS_SEEKABLE | Glib::IO_FLAG_IS_READABLE; -} - -Glib::IOStatus -FileStarChannel::seek_vfunc(gint64 offset, Glib::SeekType type) -{ - if (fseek(file.get(), offset, type)) { - return Glib::IO_STATUS_ERROR; - } - return Glib::IO_STATUS_NORMAL; -} - -Glib::IOStatus -FileStarChannel::read_vfunc(char* buf, gsize count, gsize& bytes_read) -{ - bytes_read = fread(buf, 1, count, file.get()); - if (bytes_read == 0) { - if (feof(file.get())) { - return Glib::IO_STATUS_EOF; - } - if (ferror(file.get())) { - return Glib::IO_STATUS_ERROR; - } - return Glib::IO_STATUS_AGAIN; - } - return Glib::IO_STATUS_NORMAL; -} - diff --git a/project2/common/fileStarGlibIoChannel.h b/project2/common/fileStarGlibIoChannel.h deleted file mode 100644 index 77b6282..0000000 --- a/project2/common/fileStarGlibIoChannel.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef FILESTARGLIBIOCHANNEL_H -#define FILESTARGLIBIOCHANNEL_H - -#include -#include -#include -#include -#include "intrusivePtrBase.h" - -class FileStarChannel : public Glib::IOChannel, public virtual IntrusivePtrBase { - public: - FileStarChannel(FILE * f, bool seekable, int (*closer)(FILE *) = fclose); - virtual ~FileStarChannel(); - - virtual Glib::IOStatus close_vfunc(); - virtual Glib::IOStatus set_flags_vfunc(Glib::IOFlags flags); - virtual Glib::IOFlags get_flags_vfunc(); - virtual Glib::IOStatus seek_vfunc(gint64 offset, Glib::SeekType type); - virtual Glib::IOStatus read_vfunc(char* buf, gsize count, gsize& bytes_read); - protected: - typedef boost::shared_ptr FilePtr; - FilePtr file; -}; - -#endif - diff --git a/project2/files/fileRows.cpp b/project2/files/fileRows.cpp index af11f55..4afbbb3 100644 --- a/project2/files/fileRows.cpp +++ b/project2/files/fileRows.cpp @@ -1,5 +1,6 @@ #include "fileRows.h" #include "logger.h" +#include "scopeObject.h" #include "rowProcessor.h" #include "xmlObjectLoader.h" #include "exceptions.h" @@ -26,22 +27,23 @@ FileRows::setFilter(const Glib::ustring &) void FileRows::execute(const Glib::ustring &, const RowProcessor * rp) const { - FileStarChannel c(doOpen()); - c.set_encoding(encoding); + Glib::RefPtr c(doOpen()); + ScopeObject so(boost::bind(&FileRows::doClose, this, c)); + c->set_encoding(encoding); gunichar ch; ParseState ps(this, rp); - while (c.read(ch) == Glib::IO_STATUS_NORMAL) { + while (c->read(ch) == Glib::IO_STATUS_NORMAL) { this->pushChar(ch, ps); } } -FileStarChannel +Glib::RefPtr FileRows::doOpen() const { - FILE * f = fopen(path(), "r"); - if (!f) { - throw FileNotReadable(path()); - } - return FileStarChannel(f, true, fclose); + return Glib::IOChannel::create_from_file(path(), "r"); } +void +FileRows::doClose(Glib::RefPtr c) const { + c->close(); +} diff --git a/project2/files/fileRows.h b/project2/files/fileRows.h index fccbd08..e58b855 100644 --- a/project2/files/fileRows.h +++ b/project2/files/fileRows.h @@ -2,7 +2,7 @@ #define FILEROWS_H #include "streamRows.h" -#include "fileStarGlibIoChannel.h" +#include class CommonObjects; @@ -18,7 +18,8 @@ class FileRows : public StreamRows { const Variable path; protected: - virtual FileStarChannel doOpen() const; + virtual Glib::RefPtr doOpen() const; + virtual void doClose(Glib::RefPtr) const; }; #endif diff --git a/project2/processes/procRows.cpp b/project2/processes/procRows.cpp index a8b6829..2e1f643 100644 --- a/project2/processes/procRows.cpp +++ b/project2/processes/procRows.cpp @@ -2,14 +2,17 @@ #include "xmlObjectLoader.h" #include "scripts.h" #include +#include +#include DECLARE_LOADER("procrows", ProcRows); SimpleMessageException(SubProcessFailedToStart); -SimpleNumericException(SubProcessFailed); +SimpleMessageException(SubProcessFailed); ProcRows::ProcRows(ScriptNodePtr p) : - FileRows(p) + FileRows(p), + IHaveParameters(p) { } @@ -17,26 +20,33 @@ ProcRows::~ProcRows() { } -FileStarChannel +Glib::RefPtr ProcRows::doOpen() const { - FILE * f = popen(path(), "re"); - if (!f) { - throw SubProcessFailedToStart(path()); + const char * callProc[parameters.size() + 2]; + callProc[0] = path(); + int pidx = 1; + BOOST_FOREACH(const Parameters::value_type & p, parameters) { + callProc[pidx++] = p.second(); } - return FileStarChannel(f, false, doClose); + callProc[pidx] = NULL; + popenrw(callProc, fds); + return Glib::IOChannel::create_from_fd(fds[1]); } -int -ProcRows::doClose(FILE * f) +void +ProcRows::doClose(Glib::RefPtr c) const { - int pclo = pclose(f); - // pclose returns an error if the application is still running, + FileRows::doClose(c); + close(fds[0]); + close(fds[1]); + int status; + wait(&status); + // ignore any error if the application is still running, // but if there is already an exception being thrown, we don't // want to throw another. - if (pclo != 0 && !std::uncaught_exception()) { - throw SubProcessFailed(pclo); + if (status != 0 && !std::uncaught_exception()) { + throw SubProcessFailed(strerror(status)); } - return 0; } diff --git a/project2/processes/procRows.h b/project2/processes/procRows.h index f39749d..b2085b8 100644 --- a/project2/processes/procRows.h +++ b/project2/processes/procRows.h @@ -2,15 +2,19 @@ #define PROCROWS_H #include "fileRows.h" +#include "iHaveParameters.h" /// Project2 component to create a row set from the output of a locally executed program -class ProcRows : public FileRows { +class ProcRows : public FileRows, IHaveParameters { public: ProcRows(ScriptNodePtr p); ~ProcRows(); - virtual FileStarChannel doOpen() const; - static int doClose(FILE*); + Glib::RefPtr doOpen() const; + void doClose(Glib::RefPtr) const; + + protected: + mutable int fds[2]; }; #endif -- cgit v1.2.3