Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Proper use of the _kernel_ERROR macro value

2 views
Skip to first unread message

chris...@bigfoot.com

unread,
Oct 29, 2009, 7:37:09 PM10/29/09
to
Hello,

The _kernel_ERROR macro is defined as (-2) by the header "kernel.h",
which is part of Acorn C/C++. I had never given much thought to its
correct usage until yesterday, when I was rewriting a signal handler
to comply with the spirit of this edict:

https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers

(It says that behaviour is undefined if "...the signal handler calls
any function in the standard library other than the abort function,
the _Exit function, or the signal function with the first argument
equal to the signal number corresponding to the signal that caused the
invocation of the handler.")

I want to log debugging information in my signal handler. Since I'm
not allowed to use standard library I/O functions (or even the likes
of 'strcpy'), this is a bit tricky! I decided for the sake of my own
sanity that it is safe to call functions belonging to Acorn's language-
independent library kernel (e.g. _kernel_osgbpb, _kernel_osfind, etc.)
It would be nice if there were a list of asynchronous-safe functions,
but AFAIK there isn't. The result is that I've been using the library
kernel more than ever before.

Hitherto, I have always compared the return value of library kernel
functions with _kernel_ERROR, like in the following (invented)
function to flush the keyboard buffer:

bool flush_kb(void)
{
if (_kernel_osbyte(21, 0, 0) == _kernel_ERROR)
{
report_error(_kernel_last_oserror());
return false; /* failure */
}
return true; /* success */
}

The comments in the "kernel.h" header do not explain the significance
of return values between INT_MIN and -3 inclusive. They say ">= 0 if
the call succeeds... -1 if the call fails but causes no os error... -2
if the call causes an os error". The corollary of the first part of
the above description is that all values < 0 indicate failure of some
kind (in which checking for -2 in particular gives the wrong
semantics). However, the description is incomplete and an alternative
interpretation is that values < -2 have an undefined meaning.

I am curious to know how other people write code that calls library
kernel functions? Do you typically check for return value < 0 or
return value == _kernel_ERROR? Obviously, it depends partly on the
circumstances; a caller of _kernel_osfind might instead check for <= 0
since it can fail to open a file without causing an os error. But what
is standard practice?

I suspect the following version of my example function may be more
strictly correct, but I am loathe to adopt this practice because it
will make my code more bloated and (programmer) error-prone than
before:

bool flush_kb(void)
{
int e = _kernel_osbyte(21, 0, 0);
if (e < 0)
{
if (e == _kernel_ERROR)
report_error(_kernel_last_oserror());
return false; /* failure */
}
return true; /* success */
}

Incidentally, I am aware that _kernel_osbyte can never return a value
of -1; I just adopted it as a convenient example. The comments in
"kernel.h" merely state that "Not all functions are capable of
generating this result" - they don't guarantee that certain functions
will never do so. _kernel_osrdch, _kernel_osbget and _kernel_osgbpb
are all capable of returning -1. Of these, the most interesting is
_kernel_osrdch, which returns -27 if escape was pressed!

--
Christopher Bazley

John Tytgat

unread,
Oct 30, 2009, 9:51:10 AM10/30/09
to
chris...@bigfoot.com wrote:
> I am curious to know how other people write code that calls library
> kernel functions? Do you typically check for return value < 0 or
> return value == _kernel_ERROR? Obviously, it depends partly on the
> circumstances; a caller of _kernel_osfind might instead check for <= 0
> since it can fail to open a file without causing an os error. But what
> is standard practice?

Have those _kernel_*() routines any additional value compared to the
OSLib veneers of the corresponding SWI calls ?

John.

Christopher Bazley

unread,
Oct 31, 2009, 5:40:18 AM10/31/09
to
In message <hcer0e$ub5$1...@news.eternal-september.org>
John Tytgat <th...@is.invalid> wrote:

Probably not, except that they are in ROM on all RISC OS machines and
they record any OS error in a buffer which _kernel_last_oserror()
returns a pointer to. I might have used OSLib in my projects if it
were part of Acorn C/C++ but it isn't (and at the time I didn't have
an internet connection).

--
Chris Bazley
Star Fighter 3000: http://starfighter.acornarcade.com/

0 new messages