- Backported the HTML export feature (Jean-Marc, can configure

check for "tth"?)
- Cleaned up the systemcall stuff a bit
- Better documentation for support/FileInfo.h


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@188 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Asger Ottar Alstrup 1999-10-12 21:37:10 +00:00
parent d7dbc63467
commit 3635ff7370
25 changed files with 290 additions and 201 deletions

View File

@ -1,3 +1,6 @@
since 1.0.4
- New feature: "File->Export->As HTML..." using tth (Asger)
since 1.0.4pre8
- small fix to qoutes in DocBook. (Jose)
- blurb about DocBook in LaTeXConfig (Jose)

View File

@ -1,3 +1,23 @@
1999-10-12 Asger Alstrup Nielsen <alstrup@alstrup.galaxy.dk>
* src/sys*: Cleaned up the Systemcall stuff a bit. Added "kill(int)"
method to the SystemCall class which can kill a process, but it's
not fully implemented yet.
* src/*.C: Changed Systemcalls::Startscript() to startscript()
* src/support/FileInfo.h: Better documentation
* src/lyxfunc.C: Added support for buffer-export html
* src/menus.C: Added Export->As HTML...
* lib/bind/*.bind: Added short-cut for buffer-export html
* src/lyxrc.*: Added support for new \tth_command
* lib/lyxrc.example: Added stuff for new \tth_command
1999-10-12 Lars Gullik Bjønnes <larsbj@lyx.org>
* src/LaTeX.C: some no-op changes moved declaration of some

View File

@ -66,6 +66,7 @@
\bind "M-d e p" "buffer-export postscript"
\bind "M-d e l" "buffer-export linuxdoc"
\bind "M-d e t" "buffer-export ascii"
\bind "M-d e h" "buffer-export html"
\bind "M-d e b" "buffer-export custom"
\bind "M-d b" "lyx-quit"
\bind "M-d space" "menu-open Datei"

View File

@ -49,6 +49,7 @@
\bind "M-f x d" "buffer-export dvi"
\bind "M-f x p" "buffer-export postscript"
\bind "M-f x a" "buffer-export ascii"
\bind "M-f x h" "buffer-export html"
\bind "M-f x s" "buffer-export custom"
\bind "M-f q" "lyx-quit"
\bind "M-f space" "menu-open Fichier"

View File

@ -44,6 +44,7 @@
\bind "M-f l" "buffer-export latex"
\bind "M-f u" "buffer-export linuxdoc"
\bind "M-f c" "buffer-export ascii"
\bind "M-f h" "buffer-export html"
\bind "M-f s" "buffer-export custom"
\bind "M-f k" "lyx-quit"
\bind "M-f x" "lyx-quit"

View File

@ -48,6 +48,7 @@
\bind "M-f e p" "buffer-export postscript"
\bind "M-f e d" "buffer-export linuxdoc"
\bind "M-f e t" "buffer-export ascii"
\bind "M-f e h" "buffer-export html"
\bind "M-f e m" "buffer-export custom"
\bind "M-f x" "lyx-quit"
\bind "M-f space" "menu-open File"

View File

@ -51,6 +51,7 @@
\bind "M-a e p" "buffer-export postscript"
\bind "M-a e d" "buffer-export linuxdoc"
\bind "M-a e t" "buffer-export ascii"
\bind "M-a e h" "buffer-export html"
\bind "M-a e m" "buffer-export custom"
\bind "M-a s" "lyx-quit"
\bind "M-a space" "menu-open Arquivo"

View File

@ -53,6 +53,7 @@
\bind "M-f l" "buffer-export latex"
\bind "M-f x" "buffer-export linuxdoc"
\bind "M-f S-T" "buffer-export ascii"
\bind "M-f h" "buffer-export html"
\bind "M-f S-A" "buffer-export custom"
\bind "M-f a" "lyx-quit"
\bind "M-f space" "menu-open Fil"

View File

@ -119,6 +119,11 @@
# Example: use this to ignore warnings about using "\ldots" instead of "..."
#\chktex_command "chktex -n11 -n1 -n3 -n6 -n9 -22 -n25 -n30 -n38"
# Define which program to use to run "tth", the LaTeX to HTML converter
# You should include options. The default is "tth -t"
# Example: use this to let math be italic
#\tth_command "tth -t -i"
# If you want to pass extra flags to the LinuxDoc sgml scripts, insert them
# here.
# Example: the next line activates iso-latin1 support:

View File

@ -46,7 +46,7 @@ int Chktex::run(TeXErrors &terr)
string log = ChangeExtension(file, ".log", true);
string tmp = cmd + " -q -v0 -b0 -x " + file + " -o " + log;
Systemcalls one;
int result= one.Startscript(Systemcalls::System, tmp);
int result= one.startscript(Systemcalls::System, tmp);
if (result == 0) {
result = scanLogFile(terr);
} else {

View File

@ -42,7 +42,7 @@ Buffer * ImportLaTeX::run()
string tmp = lyxrc->relyx_command + " -f " + file;
Systemcalls one;
Buffer * buf = 0;
int result= one.Startscript(Systemcalls::System, tmp);
int result= one.startscript(Systemcalls::System, tmp);
if (result==0) {
string filename = ChangeExtension(file, ".lyx", false);
// File was generated without problems. Load it.

View File

@ -37,7 +37,7 @@ Buffer * ImportNoweb::run()
documentclass() + " -f " + file;
Systemcalls one;
Buffer * buf = 0;
int result= one.Startscript(Systemcalls::System, tmp);
int result= one.startscript(Systemcalls::System, tmp);
if (result==0) {
string filename = file + ".lyx";
// File was generated without problems. Load it.

View File

@ -425,7 +425,7 @@ int LaTeX::operator()()
string tmp = cmd + ' ' + file + " > nul";
#endif
Systemcalls one;
return one.Startscript(Systemcalls::System, tmp);
return one.startscript(Systemcalls::System, tmp);
}
@ -442,7 +442,7 @@ bool LaTeX::runMakeIndex(string const &file)
string tmp = "makeindex -c -q ";
tmp += file;
Systemcalls one;
one.Startscript(Systemcalls::System, tmp);
one.startscript(Systemcalls::System, tmp);
return true;
}
@ -468,7 +468,7 @@ bool LaTeX::runBibTeX(string const &file)
string tmp="bibtex ";
tmp += ChangeExtension(file, string(), true);
Systemcalls one;
one.Startscript(Systemcalls::System, tmp);
one.startscript(Systemcalls::System, tmp);
return true;
}

View File

@ -63,8 +63,8 @@ int Literate::weave(TeXErrors &terr, MiniBuffer *minib)
//
tmp1 = literate_cmd + " < " + litfile + " > " + file + " 2> " + litfile + ".out";
tmp2 = literate_filter + " < " + litfile + ".out" + " > " + litfile + ".log";
ret1 = one.Startscript(Systemcalls::System, tmp1);
ret2 = two.Startscript(Systemcalls::System, tmp2);
ret1 = one.startscript(Systemcalls::System, tmp1);
ret2 = two.startscript(Systemcalls::System, tmp2);
lyxerr.debug() << "LITERATE {" << tmp1 << "} {" << tmp2 << "}" << endl;
scanres = scanLiterateLogFile(terr);
if (scanres & Literate::ERRORS) return scanres; // return on literate error
@ -96,8 +96,8 @@ int Literate::build(TeXErrors &terr, MiniBuffer *minib)
//
tmp1 = build_cmd + ' ' + litfile + " > " + litfile + ".out 2>&1";
tmp2 = build_filter + " < " + litfile + ".out" + " > " + litfile + ".log";
ret1 = one.Startscript(Systemcalls::System, tmp1);
ret2 = two.Startscript(Systemcalls::System, tmp2);
ret1 = one.startscript(Systemcalls::System, tmp1);
ret2 = two.startscript(Systemcalls::System, tmp2);
scanres = scanBuildLogFile(terr);
lyxerr[Debug::LATEX] << "Done." << endl;

View File

@ -616,10 +616,10 @@ bool RunScript(Buffer *buffer, bool wait,
#warning What should we do here?
#endif
minibuffer->Set(_("Executing command:"), cmd);
result = one.Startscript(Systemcalls::System, cmd);
result = one.startscript(Systemcalls::System, cmd);
} else {
minibuffer->Set(_("Executing command:"), cmd);
result = one.Startscript(wait ? Systemcalls::Wait
result = one.startscript(wait ? Systemcalls::Wait
: Systemcalls::DontWait, cmd);
}
PathPop();
@ -1277,21 +1277,21 @@ int RunLinuxDoc(int flag, string const & filename)
MakeDisplayPath(filename), "'...");
s2 = "sgml2lyx " + lyxrc->sgml_extra_options + ' '
+ name;
if (one.Startscript(Systemcalls::System, s2))
if (one.startscript(Systemcalls::System, s2))
errorcode = 1;
break;
case 0: /* TeX output asked */
minibuffer->Set(_("Converting LinuxDoc SGML to TeX file..."));
s2 = "sgml2latex " + add_flags + " -o tex "
+ lyxrc->sgml_extra_options + ' ' + name;
if (one.Startscript(Systemcalls::System, s2))
if (one.startscript(Systemcalls::System, s2))
errorcode = 1;
break;
case 1: /* dvi output asked */
minibuffer->Set(_("Converting LinuxDoc SGML to dvi file..."));
s2 = "sgml2latex " + add_flags + " -o dvi "
+ lyxrc->sgml_extra_options + ' ' + name;
if (one.Startscript(Systemcalls::System, s2)) {
if (one.startscript(Systemcalls::System, s2)) {
errorcode = 1;
} else
current_view->currentBuffer()->markDviClean();
@ -1348,7 +1348,7 @@ int RunDocBook(int flag, string const & filename)
case 1: /* dvi output asked */
minibuffer->Set(_("Converting DocBook SGML to dvi file..."));
s2 = "sgmltools --backend dvi " + name;
if (one.Startscript(Systemcalls::System, s2)) {
if (one.startscript(Systemcalls::System, s2)) {
errorcode = 1;
} else
current_view->currentBuffer()->markDviClean();

View File

@ -58,6 +58,7 @@
#include "trans_mgr.h"
#include "ImportLaTeX.h"
#include "ImportNoweb.h"
#include "support/syscall.h"
extern bool cursor_follows_scrollbar;
@ -730,6 +731,27 @@ string LyXFunc::Dispatch(int ac,
MenuSendto();
break;
}
// HTML
else if (extyp == "html") {
// First, create LaTeX file
MenuMakeLaTeX(owner->currentBuffer());
// And now, run tth
string file = owner->currentBuffer()->getFileName();
file = ChangeExtension(file, ".tex", false);
string result = ChangeExtension(file, ".html", false);
string tmp = lyxrc->tth_command + " < " + file
+ " > " + result ;
Systemcalls one;
int res = one.startscript(Systemcalls::System, tmp);
if (res == 0) {
setMessage(string(
N_("Document exported as HTML to file: ")) + result);
} else {
setErrorMessage(string(
N_("An unexpected error occured while converting document to HTML in file:")) + result);
}
}
else {
setErrorMessage(string(N_("Unknown export type: "))
+ extyp);

View File

@ -98,6 +98,8 @@ public:
LYX_PAPER_SIZE default_papersize;
/// command to run chktex incl. options
string chktex_command;
/// command to run tth incl. options
string tth_command;
///
string sgml_extra_options;
///

View File

@ -386,7 +386,7 @@ int LyXVC::doVCCommand(string const & cmd)
lyxerr[Debug::LYXVC] << "doVCCommand: " << cmd << endl;
Systemcalls one;
PathPush(_owner->filepath);
int ret = one.Startscript(Systemcalls::System, cmd);
int ret = one.startscript(Systemcalls::System, cmd);
PathPop();
return ret;
}

View File

@ -423,7 +423,8 @@ void Menus::ShowFileMenu(FL_OBJECT *ob, long)
"|as DVI...%x41"
"|as PostScript...%x42"
"|as Ascii Text...%x43"
"|Custom...%x44"));
"|as HTML...%x44"
"|Custom...%x45"));
else if(LinuxDoc)
SubFileExport=fl_defpup(FL_ObjWin(ob),
_("Export%t"
@ -443,7 +444,10 @@ void Menus::ShowFileMenu(FL_OBJECT *ob, long)
fl_setpup_shortcut(SubFileExport, 41, scex(_("FEX|Dd#d#D")));
fl_setpup_shortcut(SubFileExport, 42, scex(_("FEX|Pp#p#P")));
fl_setpup_shortcut(SubFileExport, 43, scex(_("FEX|Tt#t#T")));
fl_setpup_shortcut(SubFileExport, 44, scex(_("FEX|mM#m#M")));
if (!LinuxDoc && !DocBook) {
fl_setpup_shortcut(SubFileExport, 44, scex(_("FEX|Hh#h#H")));
fl_setpup_shortcut(SubFileExport, 45, scex(_("FEX|mM#m#M")));
}
int FileMenu = fl_defpup(FL_ObjWin(ob),
_("New..."
@ -592,7 +596,9 @@ void Menus::ShowFileMenu(FL_OBJECT *ob, long)
break;
case 43: tmpfunc->Dispatch(LFUN_EXPORT, "ascii");
break;
case 44: tmpfunc->Dispatch(LFUN_EXPORT, "custom");
case 44: tmpfunc->Dispatch(LFUN_EXPORT, "html");
break;
case 45: tmpfunc->Dispatch(LFUN_EXPORT, "custom");
break;
case 17: tmpfunc->Dispatch(LFUN_QUIT); break;
// Lastfiles:

View File

@ -31,28 +31,28 @@ public:
the file that is obtained by tracing the links. */
FileInfo(string const & path, bool link = false);
///
/// File descriptor
FileInfo(int fildes);
///
~FileInfo();
///
/// Query a new file
FileInfo& newFile(string const & path, bool link = false);
///
/// Query a new file descriptor
FileInfo& newFile(int fildes);
/// returns a character describing file type (ls -F)
/// Returns a character describing file type (ls -F)
char const * typeIndicator() const;
///
/// File protection mode
mode_t getMode() const;
///
/// Get "preferred" block size for efficient file system I/O
long getBlockSize() const;
/// constructs standard mode string (ls style)
/// Constructs standard mode string (ls style)
void modeString(char * szString) const;
/// returns a letter describing a file type (ls style)
@ -73,34 +73,37 @@ public:
///
time_t getStatusChangeTime() const;
///
/// Total file size in bytes
off_t getSize() const;
///
/// Number of hard links
nlink_t getNumberOfLinks() const;
///
/// User ID of owner
uid_t getUid() const;
///
/// Group ID of owner
gid_t getGid() const;
///
/// Is the file information correct? Did the query succeed?
bool isOK() const;
///
/// Permission flags
enum perm_test {
rperm = R_OK, // test for read permission
wperm = W_OK, // test for write permission
xperm = X_OK, // test for execute (search) permission
eperm = F_OK // test for existence of file
};
///
/// Test whether the current user has a given set of permissions
bool access(int p);
///
/// Is the file writable for the current user?
bool writable() { return access(FileInfo::wperm); }
///
/// Is the file readable for the current user?
bool readable() { return access(FileInfo::rperm); }
///
/// Is the file executable for the current user?
bool executable() { return access(FileInfo::xperm); }
///
/// Does the file exist?
bool exist() { return access(FileInfo::eperm); }
///
bool isLink() const;
@ -139,4 +142,3 @@ private:
};
#endif

View File

@ -4,87 +4,101 @@
#pragma implementation
#endif
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <cstdlib>
#include <cstdio>
#include "debug.h"
#include <unistd.h>
#include "debug.h"
#include "syscall.h"
#include "syscontr.h"
#include "support/lstrings.h"
//----------------------------------------------------------------------
// Class, which controlls a system-call
//----------------------------------------------------------------------
// constructor
Systemcalls::Systemcalls()
{
pid = (pid_t) 0; // yet no child
Systemcalls::Systemcalls() {
pid = (pid_t) 0; // No child yet
}
// constructor
//
// starts child
Systemcalls::Systemcalls(Starttype how, string what, Callbackfct cback)
Systemcalls::Systemcalls(Starttype how, string const & what, Callbackfct cback)
{
start = how;
command = what;
cbk = cback;
pid = (pid_t) 0; // no child yet
pid = (pid_t) 0;
retval = 0;
Startscript();
startscript();
}
// destructor
// not yet implemented (?)
Systemcalls::~Systemcalls()
{
Systemcalls::~Systemcalls() {
#if 0
// If the child is alive, we have to brutally kill it
if (getpid() != 0) {
::kill(getpid(), SIGKILL);
}
#endif
}
// Start a childprocess
//
// if child runs in background, add information to global controller.
int Systemcalls::Startscript()
{
int Systemcalls::startscript() {
retval = 0;
switch (start) {
case System:
retval = system(command.c_str());
Callback();
callback();
break;
case Wait:
pid = Fork();
pid = fork();
if (pid>0) { // Fork succesful. Wait for child
waitForChild();
Callback();
callback();
} else
retval = 1;
break;
case DontWait:
pid=Fork();
pid = fork();
if (pid>0) {
// Now integrate into Controller
SystemcallsSingletoncontroller::Startcontroller starter;
SystemcallsSingletoncontroller *contr=
starter.GetController();
// Add this to contr
contr->AddCall(*this);
SystemcallsSingletoncontroller * contr = starter.getController();
// Add this to controller
contr->addCall(*this);
} else
retval = 1;
break;
//default: // error();
//break;
}
return retval;
}
void Systemcalls::kill(int tolerance) {
if (getpid() == 0) {
lyxerr << "LyX: Can't kill non-existing process." << endl;
return;
}
int ret = ::kill(getpid(), SIGHUP);
bool wait_for_death = true;
if (ret != 0) {
if (errno == ESRCH) {
// The process is already dead!
wait_for_death = false;
} else {
// Something is rotten - maybe we lost permissions?
}
}
if (wait_for_death) {
// Here, we should add the PID to a list of
// waiting processes to kill if they are not
// dead without tolerance seconds
#warning Implement this using the timer of the singleton systemcontroller (Asger)
}
}
// Wait for child process to finish. Returns returncode from child.
void Systemcalls::waitForChild()
{
void Systemcalls::waitForChild() {
// We'll pretend that the child returns 1 on all errorconditions.
retval = 1;
int status;
@ -92,7 +106,7 @@ void Systemcalls::waitForChild()
while (wait) {
pid_t waitrpid = waitpid(pid, &status, WUNTRACED);
if (waitrpid == -1) {
perror("LyX: Error waiting for child");
lyxerr << "LyX: Error waiting for child:" << strerror(errno) << endl;
wait = false;
} else if (WIFEXITED(status)) {
// Child exited normally. Update return value.
@ -100,18 +114,17 @@ void Systemcalls::waitForChild()
wait = false;
} else if (WIFSIGNALED(status)) {
lyxerr << "LyX: Child didn't catch signal "
<< WTERMSIG(status)
<<" and died. Too bad." << endl;
<< WTERMSIG(status)
<< "and died. Too bad." << endl;
wait = false;
} else if (WIFSTOPPED(status)) {
lyxerr << "LyX: Child (pid: " << pid
lyxerr << "LyX: Child (pid: " << pid
<< ") stopped on signal "
<< WSTOPSIG(status)
<< WSTOPSIG(status)
<< ". Waiting for child to finish." << endl;
} else {
lyxerr << "LyX: Something rotten happened while "
"waiting for child "
<< pid << endl;
"waiting for child " << pid << endl;
wait = false;
}
}
@ -120,9 +133,9 @@ void Systemcalls::waitForChild()
// generate child in background
pid_t Systemcalls::Fork()
pid_t Systemcalls::fork()
{
pid_t cpid=fork();
pid_t cpid= ::fork();
if (cpid == 0) { // child
string childcommand(command); // copy
string rest = split(command, childcommand, ' ');
@ -130,7 +143,7 @@ pid_t Systemcalls::Fork()
char *syscmd = 0;
char *argv[MAX_ARGV];
int index = 0;
bool Abbruch;
bool more;
do {
if (syscmd == 0) {
syscmd = new char[childcommand.length() + 1];
@ -142,17 +155,17 @@ pid_t Systemcalls::Fork()
tmp[childcommand.length()] = '\0';
argv[index++] = tmp;
// reinit
Abbruch = !rest.empty();
if (Abbruch)
more = !rest.empty();
if (more)
rest = split(rest, childcommand, ' ');
} while (Abbruch);
} while (more);
argv[index] = 0;
// replace by command. Expand using PATH-environment-var.
execvp(syscmd, argv);
// If something goes wrong, we end up here:
perror("LyX: execvp failed");
lyxerr << "LyX: execvp failed: " << strerror(errno) << endl;
} else if (cpid < 0) { // error
perror("LyX: Could not fork");
lyxerr << "LyX: Could not fork: " << strerror(errno) << endl;
} else { // parent
return cpid;
}
@ -162,14 +175,15 @@ pid_t Systemcalls::Fork()
// Reuse of instance
int Systemcalls::Startscript(Starttype how, string what, Callbackfct cback)
int Systemcalls::startscript(Starttype how, string const & what,
Callbackfct cback)
{
start = how;
command = what;
cbk = cback;
pid = (pid_t) 0; // yet no child
retval = 0;
return Startscript();
return startscript();
}

View File

@ -1,78 +1,105 @@
// -*- C++ -*-
#include <sys/types.h>
#include <LString.h>
#include "LString.h"
#ifdef __GNUG__
#pragma interface
#endif
/**
This class can be used to start child processes.
/*@Doc:
Instance starts and represents childprocesses.
An instance of the class represents a child process.
You should use this class if you need to start an external program in LyX.
You can start a child in the background and have a callback function
executed when the child finishes by using the DontWait starttype.
If you wish, you can have a callback function executed when the process
finishes.
You can chose between three kinds of child processes:
1) System processes, which are initiated with the "system" call,
where the main thread waits for the system call to return.
2) Wait for child process, which are forked, but the main thread waits for
the child to end.
3) Don't wait, which are forked, but the main thread is not stopped.
The process can be considered a background process.
A timer will make sure that any callback function is called when
the child process ends.
Notice that any callback associated with a process is called whatever
the kind of child process.
*/
class Systemcalls {
public:
///
enum Starttype {
System,
Wait,
DontWait
System, // Uses system() which uses /bin/sh
Wait, // Uses fork() and execvp()
DontWait // Uses fork() and execvp()
};
/// Callback function gets commandline and returnvalue from child
/// Callback function gets commandline and return value from child
typedef void (*Callbackfct)(string cmd, int retval);
///
Systemcalls();
/** Geberate instance and start childprocess
/** Generate instance and start child process.
The string "what" contains a commandline with arguments separated
by spaces.
When the requested program finishes, the callback-function is
called with the commandline and the returnvalue from the program.
The instance is automatically added to a timercheck if starttype is
DontWait (i.e. background execution). When a background child
finishes, the timercheck will automatically call the callback
called with the commandline and the return value from the program.
The instance is automatically added to a timer check if starttype
is DontWait (i.e. background execution). When a background child
finishes, the timer check will automatically call the callback
function.
*/
Systemcalls(Starttype how, string what, Callbackfct call = 0);
Systemcalls(Starttype how, string const & what, Callbackfct call = 0);
///
~Systemcalls();
/** Start childprocess. what contains a command on systemlevel.
/** Start childprocess. "what" contains a command at system level.
* This is for reuse of the Systemcalls instance.
*/
int Startscript(Starttype how, string what, Callbackfct call = 0); // for reuse
int startscript(Starttype how, string const & what,
Callbackfct call = 0);
/** gets PID of childprocess. Used by timer */
inline pid_t Getpid() { return pid; }
pid_t getpid() { return pid; }
/// Start callback
inline void Callback() { if (cbk) cbk(command, retval); }
void callback() { if (cbk) cbk(command, retval); }
/** Set return value. Used by timer */
inline void setRetValue(int r) { retval = r; }
void setRetValue(int r) { retval = r; }
/** Kill child prematurely.
First, a SIGHUP is sent to the child.
If that does not end the child process within "tolerance"
seconds, the SIGKILL signal is sent to the child.
When the child is dead, the callback is called.
*/
void kill(int tolerance = 5);
private:
/// Type of execution: system, wait for child or background
Starttype start;
Starttype start;
/// Callback function
Callbackfct cbk;
Callbackfct cbk;
/// Commmand line
string command;
string command;
/// Process ID of child
pid_t pid;
pid_t pid;
/// Return value from child
int retval;
///
int Startscript();
int startscript();
///
pid_t Fork();
pid_t fork();
/// Wait for child process to finish. Updates returncode from child.
void waitForChild();

View File

@ -1,62 +1,59 @@
#include <config.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include "syscontr.h"
#include "syscall.h"
#include "debug.h"
#ifdef __GNUG__
#pragma implementation
#endif
//----------------------------------------------------------------------
// Controller-Implementation
//----------------------------------------------------------------------
//
// default contstructor
// Default constructor
//
SystemcallsSingletoncontroller::SystemcallsSingletoncontroller()
{
SysCalls = 0;
sysCalls = 0;
}
//
// destructor
// Destructor
//
// destroy structs for leaving program
// open question: should we stop here childs?
// open question: should we stop childs here?
// Asger says no: I like to have my xdvi open after closing LyX. Maybe
// I want to print or something.
SystemcallsSingletoncontroller::~SystemcallsSingletoncontroller()
{
ControlledCalls *next;
while (SysCalls)
while (sysCalls)
{
next = SysCalls->next;
delete SysCalls;
SysCalls = next;
next = sysCalls->next;
delete sysCalls;
sysCalls = next;
}
}
//
// Add childprocessinformation into controlled list
// Add child process information into controlled list
//
void
SystemcallsSingletoncontroller::AddCall(Systemcalls const &newcall)
{
// not yet implemented
ControlledCalls *newCall = new ControlledCalls;
SystemcallsSingletoncontroller::addCall(Systemcalls const &newcall) {
ControlledCalls * newCall = new ControlledCalls;
if (newCall == 0) // sorry, no idea
return;
newCall->next = SysCalls;
newCall->next = sysCalls;
newCall->call = new Systemcalls(newcall);
SysCalls = newCall;
sysCalls = newCall;
}
//
@ -66,33 +63,43 @@ SystemcallsSingletoncontroller::AddCall(Systemcalls const &newcall)
//
void
SystemcallsSingletoncontroller::Timer()
{
SystemcallsSingletoncontroller::timer() {
// check each entry of our list, if it's finished
ControlledCalls *prev = 0;
for (ControlledCalls *actCall=SysCalls; actCall; actCall=actCall->next)
{
pid_t pid=actCall->call->Getpid();
int stat_loc;
waitpid(pid, &stat_loc, WNOHANG);
if (WIFEXITED(stat_loc) || WIFSIGNALED(stat_loc)) {
for (ControlledCalls *actCall=sysCalls; actCall; actCall=actCall->next)
{
pid_t pid=actCall->call->getpid();
int stat_loc;
int waitrpid = waitpid(pid, &stat_loc, WNOHANG);
if (waitrpid == -1) {
lyxerr << "LyX: Error waiting for child:"
<< strerror(errno) << endl;
} else if (WIFEXITED(stat_loc) || WIFSIGNALED(stat_loc)) {
if (WIFEXITED(stat_loc)) {
// Ok, the return value goes into retval.
if (WIFEXITED(stat_loc)) {
actCall->call->setRetValue(WEXITSTATUS(stat_loc));
} else {
// Child died, so pretend it returned 1
actCall->call->setRetValue(1);
}
// callback and release
actCall->call->Callback();
if (actCall == SysCalls) {
SysCalls = actCall->next;
} else {
prev->next = actCall->next;
}
delete actCall;
actCall = prev;
actCall->call->setRetValue(WEXITSTATUS(stat_loc));
} else {
// Child died, so pretend it returned 1
actCall->call->setRetValue(1);
}
prev = actCall;
// Callback and release
actCall->call->callback();
if (actCall == sysCalls) {
sysCalls = actCall->next;
} else {
prev->next = actCall->next;
}
delete actCall;
actCall = prev;
} else if (WIFSTOPPED(stat_loc)) {
lyxerr << "LyX: Child (pid: " << pid
<< ") stopped on signal "
<< WSTOPSIG(stat_loc)
<< ". Waiting for child to finish." << endl;
} else {
lyxerr << "LyX: Something rotten happened while "
"waiting for child " << pid << endl;
}
prev = actCall;
}
}

View File

@ -9,42 +9,27 @@
class Systemcalls;
///
class SystemcallsSingletoncontroller{
class SystemcallsSingletoncontroller {
public:
///
class Startcontroller{
class Startcontroller {
public:
///
Startcontroller();
///
~Startcontroller();
///
static SystemcallsSingletoncontroller *GetController();
///
void ReduceRefcount() { refcount--; }
static SystemcallsSingletoncontroller * getController();
void reduceRefcount() { refcount--; }
private:
///
static SystemcallsSingletoncontroller *contr;
///
static SystemcallsSingletoncontroller * contr;
static int refcount;
};
///
~SystemcallsSingletoncontroller();
///
void AddCall(Systemcalls const &newcall);
///
void Timer();
void addCall(Systemcalls const & newcall);
void timer();
// private: // DEC cxx does not like that (JMarc)
///
SystemcallsSingletoncontroller();
private:
///
struct ControlledCalls {
///
Systemcalls *call;
///
ControlledCalls *next; };
///
ControlledCalls *SysCalls;
ControlledCalls *next;
};
ControlledCalls * sysCalls;
};

View File

@ -1,8 +1,5 @@
#include <config.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include "syscontr.h"
@ -19,30 +16,23 @@ contr = 0;
int SystemcallsSingletoncontroller::Startcontroller::
refcount = 0;
// default constructor.
// Nothing to do at moment.
SystemcallsSingletoncontroller::Startcontroller::
Startcontroller()
{
Startcontroller() {
}
// default destructor.
// Nothing to do at moment
SystemcallsSingletoncontroller::Startcontroller::
~Startcontroller()
{
~Startcontroller() {
}
// Give reference to global controller-instance
//
SystemcallsSingletoncontroller *
SystemcallsSingletoncontroller::Startcontroller::
GetController()
SystemcallsSingletoncontroller::Startcontroller::getController()
{
if (! contr)
{ // generate the global controller
contr = new SystemcallsSingletoncontroller;
}
if (!contr) {
// Create the global controller
contr = new SystemcallsSingletoncontroller;
}
refcount++;
return contr;
}