mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 01:59:02 +00:00
- 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:
parent
d7dbc63467
commit
3635ff7370
3
CHANGES
3
CHANGES
@ -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)
|
||||
|
20
ChangeLog
20
ChangeLog
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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:
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
12
src/lyx_cb.C
12
src/lyx_cb.C
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
///
|
||||
|
@ -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;
|
||||
}
|
||||
|
12
src/menus.C
12
src/menus.C
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user