May 22, 2019

Grinder - hoven error 30

hoven error 30
Here we have it. The most famous (or infamous) error message that gets spit out by the oven software. Almost anything would be equally informative. My suggestion is:
Game over, insert coin.
What I am trying to do is to run the ograph command offline to plot information in data files. Unfortunately ograph expects to find a shared memory segment. It is only designed to run in real time with access to a real oven. I am tempted to fix this. But there may be ways to trick it. An idea is to set up a shared memory segment for a non-existant oven using a command like:
oven noven=2
It will accept oven numbers from 0-9, but all of them give the dreaded "hoven error 30" message.

Nobody knows what this really means. Well, somebody does, but he lives in another country half way around the world. We could ask him, but there may be ways to figure this out.

"Help oven" tells us that oven is a parameter editor, which is not terribly informative. This description may become more clear if we ever get it to run. If we type "help oven", we are told that this command will create shared memory segments if they do not exist, and fill them with zeros. My bet is this "error 30" is something to do with the shared memory setup. Nobody knows for sure what "hoven" is.

Go to the source

On my system, this is in directory /u1/iraf/iraf_2.16.1/extern/mirror/src/oven. A search there for "oven error" takes me to t_hoven.x where I find this code:
	status = hoven (noven, ncomp, readonly, remove, period, offset)
        if (status != 0) {
            call printf ("hoven error %d\n")
                call pargi (status)
        }
Chasing this from a different direction, there is a file errnum.h that has the line:
#define ERRPCI  30
This turns out to be something else entirely. So we grep for "30" and get lucky. In init.c, in init_database() we see:
	db = (database *)shmalloc (sizeof(database), noven, ncomp, readonly);
        status = (int)db;
        switch (status) {
        case 0:
            return (status+30);
            break;
        default:
            status = 0;
            break;
        }

The code for shmalloc() is in shmalloc.c. I yank this subroutine out, wrap it with a bit of test code and experiment. The conclusion is as follows:

The conclusion

The following code (in init.c) is crucial. If you are not the pilot, the software will attempt to attach to an already existing shared memory segment. Only the pilot can actually create the segment. So if you are an ordinary joe (or tom), you are out of luck. If you are the pilot, you just forgot to run the oven command to create the shared memory segment.
	if (!iamthepilot())
            readonly = 1;
The code for iamthepilot() is at the end of init.c and looks like this:
iamthepilot ()
{
        char    *getenv ();
        char    *user = getenv ("USER");

#define TEST
#ifndef TEST
        return (user && (!strcmp (user, "pilot") || !strcmp (user, "pilot2")));
#else
        /*
        return (user && !strcmp (user, "skip"));
        return (user && !strcmp (user, "tom"));
        */
        return 1;
#endif
}

To do testing, I have two choices. I can create a "pilot" user and run as that user to create the shared memory segment. Alternately, I can modify the iamthepilot () routine to allow "tom" to be considered a pilot, just like pilot and pilot2. Then I will have to rebuild the package.

Create a pilot user

On my linux system, I useradd "pilot" and then trying running "oven" to set up the shared memory. I get:
mirror> oven
TJT error: shmget: 263748 256 1 -1
hoven error 30
The line with my initials gives the arguments to shmget -- a size of 263748 bytes, a key of 256, readonly set to 1, and the return value from shmget (-1). The problem here is the readonly=1 business. I repeat the oven command as follows and I am in business. I get no error message, and am presented with the top level menu.
oven readonly=no

Have any comments? Questions? Drop me a line!

Tom's home page / tom@mmto.org