On 16 Sep 1999 18:50:58 +0200, Lars Gullik Bj°nnes wrote:
>
>When 1.0.4 is released we will open up development on the new 1.1.x
>series and shortly after that some new stable releases with no new
>users features will be released (except to modules that are under
>continued development DocBook and reLyX.)
BTW:
Switching to static linking of xpm3.4g (found the header on sunsite, if
somebody is interested, I can mail it) made LyX rock-solid here.
I'm really happy with the port now, though several issues in figinset.C (display is
somehow blocked for gs rendering of inline eps) are yet to be solved; if it is
worthwile (Xlib prints out an io error).
I'm interested to know if this effect is a generic problem with some X
Servers and Xlib. I had some ideas where EACCES might be set, but all those fn
turned out to work correctly. Isolating a bit with perror() and then gdb 'stepi'
through childs might be the only solution, but this is very time consuming. And I
won't be able to fix core X11 server (SVGA with Virge DX driver enabled) code.
Maybe parts of the following to be integrated into 104, or you may want to implement
in a more standard C++ way:
The FileInfo bug:
Non-Posix (and even Posix) systems do not define all sys/stat macros.
The solution:
Do not rely upon existance of all (special) files.
LyX uses the usual protection, which was inconsistently
implemented, because some were simply forgotten.
The positive effect for me is, that I don't longer need two
'unorthodox' defines in os2_defines.h. (I changed them to #undef to be
sure and to be more standard conformant):
#undef S_ISLNK(x)
#undef S_ISBLK(x)
I added the omitted guards as follows:
------snip-----
diff -p -N -r -u -X excl.tmp lyx103/src/FileInfo.C modified/FileInfo.C
--- lyx103/src/FileInfo.C Tue Feb 16 04:54:00 1999
+++ modified/FileInfo.C Thu Aug 26 15:32:06 1999
@@ -339,15 +339,23 @@ bool FileInfo::isOK() const
}
+
bool FileInfo::isLink() const
{
+#if defined(S_ISLNK)
return S_ISLNK(buf->st_mode);
+#else
+ return false;
+#endif
}
@@ -359,19 +367,31 @@ bool FileInfo::isDir() const
bool FileInfo::isChar() const
{
+#if defined(S_ISCHR)
return S_ISCHR(buf->st_mode);
+#else
+ return false;
+#endif
}
bool FileInfo::isBlock() const
{
+#if defined(S_ISBLK)
return S_ISBLK(buf->st_mode);
+#else
+ return false;
+#endif
}
bool FileInfo::isFifo() const
{
+#if defined(S_ISFIFO)
return S_ISFIFO(buf->st_mode);
+#else
+ return false;
+#endif
}
-----snap-------
Here's included a small patch to class Syscalls that uses spawnxx() for emx
instead of fork(), as recommended by emx Lib C Reference. This reduces the chance
of memory corruption or crashes when spawning childs, uses less memory and is
faster. IMHO it should be safe, nevertheless have a close look at before applying
it.
Changes should be self-explaining/well documented. I was careful to reverse all
reformatting and assure readability. 80% of the changes are just added comments.
Unix should not be affected, everything should be typesafe.
-----snip-----------
diff -p -N -r -u -X excl.tmp lyx103/src/syscall.C modified/syscall.C
--- lyx103/src/syscall.C Tue Nov 10 09:44:48 1998
+++ modified/syscall.C Thu Aug 26 12:30:58 1999
@@ -9,6 +14,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <process.h>
#include "syscall.h"
#include "syscontr.h"
@@ -54,15 +60,19 @@ int Systemcalls::Startscript()
Callback();
break;
case Wait:
- pid = Fork();
+ pid = Fork(P_WAIT);
if (pid>0) { // Fork succesful. Wait for child
+#ifndef __EMX__
waitForChild();
+#else
+ retval = pid;
+#endif
Callback();
} else
retval = 1;
break;
case DontWait:
- pid=Fork();
+ pid=Fork(P_NOWAIT);
if (pid>0) {
// Now integrate into Controller
SystemcallsSingletoncontroller::Startcontroller starter;
@@ -81,9 +91,10 @@ int Systemcalls::Startscript()
// Wait for child process to finish. Returns returncode from child.
+#ifndef __EMX__
void Systemcalls::waitForChild()
{
- // We'll pretend that the child returns 1 on all errorconditions.
+ // We'll pretend that the child returns -1 on all errorconditions.
retval = 1;
int status;
bool wait = true;
@@ -111,17 +122,20 @@ void Systemcalls::waitForChild()
}
}
}
+#endif
// generate child in background
-pid_t Systemcalls::Fork()
+pid_t Systemcalls::Fork(int spawnFlag)
{
+#ifndef __EMX__
pid_t cpid=fork();
if (cpid == 0) { // child
+#endif
LString childcommand(command); // copy
LString rest = command.split(childcommand, ' ');
const int MAX_ARGV = 255;
char *syscmd = NULL;
char *argv[MAX_ARGV];
int index = 0;
@@ -138,10 +151,15 @@ pid_t Systemcalls::Fork()
} while (Abbruch);
argv[index] = NULL;
// replace by command. Expand using PATH-environment-var.
+#ifndef __EMX__
execvp(syscmd, argv);
// If something goes wrong, we end up here:
perror("LyX: execvp failed");
- } else if (cpid < 0) { // error
+ } else
+#else
+ pid_t cpid = spawnvp(spawnFlag, syscmd, argv);
+#endif
+ if (cpid < 0) { // error
perror("LyX: Could not fork");
} else { // parent
return cpid;
diff -p -N -r -u -X excl.tmp lyx103/src/syscall.h modified/syscall.h
--- lyx103/src/syscall.h Thu Aug 26 18:01:04 1999
+++ modified/syscall.h Thu Aug 26 18:02:32 1999
@@ -2,12 +2,30 @@
#include <sys/types.h>
#include <LString.h>
+/** AHanses: Eliminate unneeded parameter for Unix: 'fork(void)'
+ This can be safely commented out but is useful as a comment, I think.
+ (Please note: This macro implementation is fully type-safe;
+ the code pre-processor sorts out which OS-specific function
+ interface will be used and passes it to the compiler. The
+ C++-parser of the compiler then sees strictly typed C++-methods)
+ Cf. os2_defines.h for 'spawnvp(spawnFlag, ...)' emx interface.
+
+#ifndef FORK_SPAWN
+#define Fork(f) Fork() // Note: CPP passes strictly typed code to compiler
+#endif
+ */
#ifdef __GNUG__
#pragma interface
#endif
-/*@Doc:
+/// Class to controll system-calls according to OS-specific interface
+/**@Doc:
+ Class, which controlls a system-call according to the specific interface of
+ your operating system. Hides OS-dependant hacks by providing a common
+ interface for calling. Should become part of a LyX-tools support library:
+ OS-dependant hacks should be completely opaque to the rest of LyX (AHanses).
+
Instance starts and represents childprocesses.
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
@@ -28,7 +46,7 @@ public:
///
Systemcalls();
- /** Geberate instance and start childprocess
+ /** Generate instance and start childprocess
The string "what" contains a commandline with arguments separated
by spaces.
When the requested program finishes, the callback-function is
@@ -71,9 +89,17 @@ private:
///
int Startscript();
- ///
- pid_t Fork();
+
+ /// Spawn child according to the interface of your OS (AHanses)
+ pid_t Fork(int spawnFlag);
/// Wait for child process to finish. Updates returncode from child.
+#ifndef __EMX__
+ /**
+ Waitforchild not necessary with spawnvp() of emx.
+ Note (concerning OS/2 specifics): Emx interface implementation of
+ spawnvp(P_WAIT, ...) returns returncode from child (AHanses).
+ */
void waitForChild();
+#endif
};
---------snap-------------------------