Unix on Mocka, part 2
Many years ago I did some rudimentary tests with running Unix system commands from within Modula-2. They worked, as
can be seen in
unix.html
but it was cumbersome. And I definitely need some sleep for Mocka. Yes I can start and calibrate a timing loop
based on an infinite loop, but such a loop is only allowed on single user single tasking systems like "Good Old
Dos". On Linux we should not lock up the machine for such a silly task. Therefore the Unix sleep command (which
simply HALT the processor for a finite time and then wake it up again.
A sleeping process does noit eat up cpu cycles so it doesn't slow down the rest. With a 'sleep' command around, it
is possible to poll I/O's in a sensible way. I decided to name the module 'unix' (lower case letters only) since I
want a sleep command and perhaps some other goodies like 'printf' since it works a little bit easier than a series
of InOut commands.
Unix functions for Mocka Modula-2
Here is the module that does all the work:
/* Unix functions for Modula-2 */
#define billion 1000000000;
#include <stdio.h>
#include <time.h>
void Printf (char * text)
{
printf (text);
}
void nSleep (int s, int ns)
{
struct timespec ts;
ts.tv_sec = (s > 0) ? s : -s;
ts.tv_nsec = ns % billion;
nanosleep (&ts, NULL);
}
void uSleep (unsigned int delay)
{
usleep (delay);
}
Compile it to an object module with
gcc unix.c -c -o unix.oWe're half way done now. Just create a DEFINITION MODULE. At least, the file has a 'def' extension, the contents are as follows:
FOREIGN MODULE unix; (* Unix functions for Modula-2 *) PROCEDURE Printf ( text : ARRAY OF CHAR); PROCEDURE nSleep (s, ns : CARDINAL); PROCEDURE uSleep (delay : CARDINAL); END unix.Now start mocka and compile the foreign module:
jan@nitrogen ~/Modula/lib$ mocka Mocka 0608m >> s unix .. Compiling Definition of unix >> qDone. Now we can IMPORT the functions....
Testing the new unix functions
Below is a small program to test the new functions:
MODULE unto;
IMPORT unix, InOut;
BEGIN
InOut.WriteString ("testing new Unix module. Going to sleep for 1.5 seconds now");
InOut.WriteLn;
unix.uSleep (1500000);
InOut.WriteString ("Just woke up after an eternity.. still feeling sleepy. Time foe a 5.3 second nap the time.");
InOut.WriteLn;
unix.nSleep (5, 300000000);
unix.Printf ("Done sleeping, time to get some grub.\n")
END unto.
See it compile
I always use the mocka 'IDE' since it works so easy.
jan@nitrogen ~/Modula/lib$ mocka Mocka 0608m >> i unto >> p unto .. Compiling Program Module unto I/0001 II/0001 .. Linking unto gcc: error: ./m2bin/unix.o: No such file or directory strip: 'unto': No such file >> cp unix.o m2bin >> p unto .. Linking unto >> q jan@nitrogen ~/Modula/lib$ ./untoSo far the compiling. As you see, the linker expects the object file in the ./m2bin directory so I help it a little bit. And then it immediately performs a clean compile.
See it run
testing new Unix module. Going to sleep for 1.5 seconds now Just woke up after an eternity.. still feeling sleepy. Time foe a 5.3 second nap the time. Done sleeping, time to get some grub.\njan@nitrogen ~/Modula/lib$Three things: