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

Exception handling in C

5 views
Skip to first unread message

shadow

unread,
Jun 26, 2002, 4:51:26 AM6/26/02
to
Hi,

I need to implement exception handling (meaning no dr. watson boxes must
appear) in my application. I use standard C (so no C++). I heard something
about try and catch statements. Can I use these in standard C ? Or must I
use other statements instead ?

Shadow ;-)


Joona I Palaste

unread,
Jun 26, 2002, 5:03:48 AM6/26/02
to
shadow <sha...@nospam.com> scribbled the following:
> Hi,

Try and catch are C++ concepts and are not included in C. You will have
to implement your own exception catching mechanism instead.

--
/-- Joona Palaste (pal...@cc.helsinki.fi) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"I will never display my bum in public again."
- Homer Simpson

Dave Neary

unread,
Jun 26, 2002, 5:28:50 AM6/26/02
to

try and catch are Java (at least - they may be used in other
languages). The standard C signal-handling function is signal().
There are several standard, and thus portable, signals in ANSI C
- there are even more in POSIX, and there are probably a few more
for your platform. In any case, it works a little like this...

#include <signal.h> /* Signal stuff */
#include <errno.h> /* errno, perror */
#include <stdio.h> /* fprintf() */
#include <stdlib.h> /* exit() */

void interrupt(int sig)
{
fprintf(stderr, "Received a SIGINT signal - quitting\n");
exit(0);
}

int main(void)
{
if(signal(SIGINT, interrupt) == SIG_ERR)
fprintf(stderr, "Signal attach failed!!!\nerrno = %d\n", errno);

while(1); /* Infinite loop - to break it, interrupt (Ctrl-C on
* my machine) */

return 0;
}

Not quite exception handling - but with careful use, signal
trapping will probably suffice. You can, of course, make up your
own signals and raise() them on certain events to do something
similar.

As an example, add the following function before interrupt()...

void custom_signal(int sig)
{
fprintf(stderr, "My signal got raised. It's signal number %d.\n", sig);
exit(0);
}

and add the following line to the interrupt() function, before
the call to exit...

raise(42);

and add this after the signal() call in main...

if(signal(42, custom_signal) == SIG_ERR)
{
fprintf(stderr, "Custom signal attach failed!!!\nerrno = %d\n", errno);
exit(1);
}

Now signal 42 is yours, and yours alone, to raise when you have
an exception. And you catch it by assigning a sig_handler to it.

Hope this helps,
Dave.

--
David Neary,
E-Mail: bolsh at gimp dot org
CV: http://www.redbrick.dcu.ie/~bolsh/CV/CV.html

shadow

unread,
Jun 26, 2002, 5:57:07 AM6/26/02
to
What about __try ?

"Joona I Palaste" <pal...@cc.helsinki.fi> wrote in message
news:afc01k$jba$1...@oravannahka.helsinki.fi...

ke...@hplb.hpl.hp.com

unread,
Jun 26, 2002, 6:09:00 AM6/26/02
to
In article <3d199017$0$8350@heracles>,
"shadow" <sha...@nospam.com> writes:
> What about __try ?

What about not top-posting?

[__try is no more part of C than Buffy is part of the crew of Babylon 5.]

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html

Kevin Bracey

unread,
Jun 26, 2002, 6:48:29 AM6/26/02
to
In message <3d199017$0$8350@heracles>
"shadow" <sha...@nospam.com> wrote:

> What about __try ?

Do, or do not. There is no __try.

--
Kevin Bracey
http://www.bracey-griffith.freeserve.co.uk/

Jeremy Yallop

unread,
Jun 26, 2002, 7:06:23 AM6/26/02
to
* Dave Neary

| void interrupt(int sig)
| {
| fprintf(stderr, "Received a SIGINT signal - quitting\n");
| exit(0);

Calling these functions from a signal handler invokes undefined
behaviour (in this case).

Jeremy.

Dave Neary

unread,
Jun 26, 2002, 7:15:59 AM6/26/02
to

Would you mind pointing out why? I see no reason why it should...
My reading of the standard is that if you trap a signal
associatyed with a computational exception, and return, the
behaviour is undefined. But to me it seems clear that the
function interrupt is executed, and doesn't refer to any objects
with static storage duration. The standard says that (eventually)
"the equivalent of (*func)(sig); is executed" - I read that as
meaning that eventually exit(0); gets called eventually, and
"causes normal program termination to occur".

Would you mind enlightening me as to what exactly is undefined?

Dan Pop

unread,
Jun 26, 2002, 7:31:43 AM6/26/02
to
In <3d1980b1$0$8349@heracles> "shadow" <sha...@nospam.com> writes:

>I need to implement exception handling (meaning no dr. watson boxes must
>appear) in my application. I use standard C (so no C++). I heard something
>about try and catch statements. Can I use these in standard C ?

Nope.

>Or must I use other statements instead ?

Just don't generate exceptions and everything will be fine.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan...@ifh.de

Dan Pop

unread,
Jun 26, 2002, 7:35:00 AM6/26/02
to
In <slrnahj2jk.t6l.re...@bolsh.wanadoo.fr> Dave Neary <real.addre...@thisoneis.invalid> writes:

>On Wed, 26 Jun 2002 10:51:26 +0200, shadow said:
>>
>> I need to implement exception handling (meaning no dr. watson boxes must
>> appear) in my application. I use standard C (so no C++). I heard something
>> about try and catch statements. Can I use these in standard C ? Or must I
>> use other statements instead ?
>
>try and catch are Java (at least - they may be used in other
>languages). The standard C signal-handling function is signal().
>There are several standard, and thus portable, signals in ANSI C

Microsoft's support of signals is somewhat broken. It's best to avoid
using them on that platform, unless you like tracing bugs that aren't
yours.

Dave Neary

unread,
Jun 26, 2002, 7:55:42 AM6/26/02
to
On 26 Jun 2002 09:28:50 GMT, Dave Neary said:
> try and catch are Java (at least - they may be used in other
> languages). The standard C signal-handling function is signal().
> There are several standard, and thus portable, signals in ANSI C
> - there are even more in POSIX, and there are probably a few more
> for your platform. In any case, it works a little like this...

A question on the behaviour of signal which seems unspecified by
the standard, and therefore (I guess) undefined. Although that's
not clear...

Say I were to do this...

#include <stdio.h>
#include <signal.h>

void test(int sig)
{
printf("Get here\n");
return;
}

int main(void)
{
int i;
signal(SIGUSR1, test); /* Assume SIGUSR1 is a valid, existing,
* non-reserved signal, for arguments sake */

for(i=0;i<10;i++)
{
raise(SIGUSR1);
}

return 0;
}

On my particular C implementation (glibc2, gcc 3, with -std=c99
-pedantic -Wall), the second raise() results in the system exitting. In
other words, "Get here" gets output once, and the program terminates on
the second call to raise(). My reading of the standard was that on
return from raise() program execution continued as before. And I
read that as meaning that in this case, "Get here" should print
10 times. When I compile in non-ansi mode, the program works as I
had expected.

Is the behaviour of a second raising of a signal undefined? It
would appear so, I just want confirmation...

Cheers,

Dan Pop

unread,
Jun 26, 2002, 7:49:45 AM6/26/02
to
In <slrnahj8sk.v3p.re...@bolsh.wanadoo.fr> Dave Neary <real.addre...@thisoneis.invalid> writes:

>On 26 Jun 2002 11:06:23 GMT, Jeremy Yallop said:
>> * Dave Neary
>>| void interrupt(int sig)
>>| {
>>| fprintf(stderr, "Received a SIGINT signal - quitting\n");
>>| exit(0);
>>
>> Calling these functions from a signal handler invokes undefined
>> behaviour (in this case).
>
>Would you mind pointing out why? I see no reason why it should...

The usual answer: because the standard says so.

[#5] If the signal occurs other than as the result of
calling the abort or raise function, the behavior is
^^^^^^^^^^^^^^^^^
undefined if the signal handler refers to any object with
^^^^^^^^^
static storage duration other than by assigning a value to
an object declared as volatile sig_atomic_t, or the signal
^^^^^^^^^^^^^
handler calls any function in the standard library other
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
than the abort 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.

>Would you mind enlightening me as to what exactly is undefined?

The program's behaviour, of course.

The point is that the standard library need not be implemented in a
reentrant manner (with the exceptions mentioned above). If the
signal arrives while the program was already executing the fprintf
(or exit) function, complete chaos could happen.

Dave Neary

unread,
Jun 26, 2002, 8:27:46 AM6/26/02
to
On 26 Jun 2002 11:49:45 GMT, Dan Pop said:

> Dave Neary writes:
>>On 26 Jun 2002 11:06:23 GMT, Jeremy Yallop said:
>>> Calling [library] functions from a signal handler invokes undefined
>>> behaviour.

>>Would you mind pointing out why? I see no reason why it should...
>
> The usual answer: because the standard says so.
>
> [#5] If the signal occurs other than as the result of
> calling the abort or raise function, the behavior is
> undefined [if] the signal

> handler calls any function in the standard library other
> than the abort 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.

Ah. For some reason I was concentrating on #3. <ot>but it would
be OK to call (say) write() on a unix-like system?</ot> Anyway,
thanks for the information & enlightenment.

>>Would you mind enlightening me as to what exactly is undefined?
>
> The program's behaviour, of course.

I meant what part of it caused the program to have UB... but
never mind :)

> The point is that the standard library need not be implemented in a
> reentrant manner (with the exceptions mentioned above). If the
> signal arrives while the program was already executing the fprintf
> (or exit) function, complete chaos could happen.

Ah. Light dawns. Will avoid signal(). It's a pity there's no
portable, useful signal framework, though. <ot>Something like
sigaction...</ot>

Thanks again,

Dan Pop

unread,
Jun 26, 2002, 9:32:56 AM6/26/02
to
In <slrnahjd37.vng.re...@bolsh.wanadoo.fr> Dave Neary <real.addre...@thisoneis.invalid> writes:

>Ah. Light dawns. Will avoid signal(). It's a pity there's no
>portable, useful signal framework, though.

There is. Just do what the standard recommends: set a volatile
sig_atomic_t flag and immediately return from the signal handler.
Check the value of the flag in the program's main loop(s) to detect the
delivery of the signal and take the appropriate actions: at this point,
you can call any library function you want. If you decide to continue
the program execution, don't forget to reinstall the signal handler.

Here's a simple example:

#include <signal.h>
#include <stdio.h>

volatile sig_atomic_t flag;

void handler(int sig)
{
flag = 1;
}

int main()
{
signal(SIGINT, handler);
puts("Press the interrupt key to exit.");
while (!flag) ;
puts("Bye bye!");
return 0;

Dan Pop

unread,
Jun 26, 2002, 9:18:05 AM6/26/02
to
In <slrnahjb74.vd2.re...@bolsh.wanadoo.fr> Dave Neary <real.addre...@thisoneis.invalid> writes:

>A question on the behaviour of signal which seems unspecified by
>the standard, and therefore (I guess) undefined. Although that's
>not clear...
>
>Say I were to do this...
>
>#include <stdio.h>
>#include <signal.h>
>
>void test(int sig)
>{
> printf("Get here\n");

signal(SIGUSR1, test);


> return;
>}
>
>int main(void)
>{
> int i;
> signal(SIGUSR1, test); /* Assume SIGUSR1 is a valid, existing,
> * non-reserved signal, for arguments sake */
>
> for(i=0;i<10;i++)
> {
> raise(SIGUSR1);
> }
>
> return 0;
>}
>
>On my particular C implementation (glibc2, gcc 3, with -std=c99
>-pedantic -Wall), the second raise() results in the system exitting. In
>other words, "Get here" gets output once, and the program terminates on
>the second call to raise(). My reading of the standard was that on
>return from raise() program execution continued as before. And I
>read that as meaning that in this case, "Get here" should print
>10 times. When I compile in non-ansi mode, the program works as I
>had expected.
>
>Is the behaviour of a second raising of a signal undefined? It
>would appear so, I just want confirmation...

Again, your reading of the standard is defective.

[#3] When a signal occurs and func points to a function, it
is implementation-defined whether the equivalent of
signal(sig, SIG_DFL); is executed or the implementation
prevents some implementation-defined set of signals (at
least including sig) from occurring until the current signal
handling has completed; in the case of SIGILL, the
implementation may alternatively define that no action is
taken.

Apparently, your implementation has chosen to execute the equivalent
of signal(sig, SIG_DFL); rather than preventing some signals from
occuring until the current signal handling has completed. Since the
effect of signal(sig, SIG_DFL) is still in effect when the signal
handler returns, the second raise will invoke the default signal
handler, which terminates your program.

To get the behaviour you want, you have to reinstall the signal handler
yourself, which is typically done before returning from the signal
handler (the standard lets you call signal() from a signal handler).
Try your program again, with my insertion, and see what happens.

Of course, your program still invokes undefined behaviour by calling
printf in the signal handler, but, if Peter van der Linden could do that
in "Expert C Programming" (page 198), we shouldn't flame you too hard
for doing it ;-)

David C.

unread,
Jun 26, 2002, 11:38:55 AM6/26/02
to

The C language has no exception system.

If you want a C++-like exception system, you can roll your own using
setjmp/longjmp, but this is not a trivial exercise. This system will
only catch exceptions that it itself generates, of course.

You mentioned Dr. Watson boxes. This tells me that you're looking to
catch OS-generated exceptions. This is beyond the scope of the C
language. You should ask on a Windows programming newsgroup.

(The __try keyword is a Microsoft-proprietary extension to C. It is not
part of the C language. A newsgroup that deals with Windows and MSVC
may be able to help you with it.)

-- David

Dave Neary

unread,
Jun 26, 2002, 5:48:35 PM6/26/02
to
On 26 Jun 2002 13:18:05 GMT, Dan Pop said:

> Dave Neary writes:
>
>>A question on the behaviour of signal which seems unspecified by
>>the standard, and therefore (I guess) undefined. Although that's
>>not clear...
>
> Again, your reading of the standard is defective.

Yup. I figured this out (through the hint in the standard that
says that one of the few library functions we may safely call in
a sighandler is signal() with the same sig number as the
sighandler got called with).

> Apparently, your implementation has chosen to execute the equivalent
> of signal(sig, SIG_DFL); rather than preventing some signals from
> occuring until the current signal handling has completed. Since the
> effect of signal(sig, SIG_DFL) is still in effect when the signal
> handler returns, the second raise will invoke the default signal
> handler, which terminates your program.

Yup. Spot on. I was being a bit dense :)

> Of course, your program still invokes undefined behaviour by calling
> printf in the signal handler, but, if Peter van der Linden could do that
> in "Expert C Programming" (page 198), we shouldn't flame you too hard
> for doing it ;-)

So he did. Never noticed that :) Although he says in the footnote
that it's undefined and that the example is merely for
instructional purposes.

Thanks for the info,

Jens Troeger

unread,
Jun 26, 2002, 6:46:01 PM6/26/02
to

i did this a while ago with macros. you can use longset() and longjmp()
which is defined in ansi c. those are the macros

/**************************************************************************
** this lets you use simple exception handling with standard ansi-c
** note: never RAISE a value of zero (this would result into an infinite loop)
**
** TRY
** {
** ... RAISE(5); ...
** }
** CATCH
** {
** switch (exception)
** {
** ...
** case 5: ...
** ...
** }
** }
** ENDTRY
*/

#include <setjmp.h>
#define TRY { jmp_buf buf; int exception = setjmp(buf); if (!exception) {
#define CATCH } else {
#define ENDTRY } }
#define RAISE(e) longjmp(buf, e)

if i remember right this DOES ONLY work within a function, but i am not so
sure... give it a go

cheers,
jens

--
Jens Tröger Ph: +61 7 3864-9342
Programming Languages & Systems Research Center
School of Computing Science j.tr...@qut.edu.au
QUT, Brisbane, Australia http://www.fit.qut.edu.au/~troger

Ben Pfaff

unread,
Jun 26, 2002, 7:17:29 PM6/26/02
to
Jens Troeger <j.tr...@qut.edu.au> writes:

> #define TRY { jmp_buf buf; int exception = setjmp(buf); if (!exception) {

That's not a valid invocation of setjmp() and results in
undefined behavior. From the standard:

An invocation of the setjmp macro shall appear only in one
of the following contexts:

- the entire controlling expression of a selection or
iteration statement;

- one operand of a relational or equality operator with the
other operand an integer constant expression, with the
resulting expression being the entire controlling
expression of a selection or iteration statement;

- the operand of a unary ! operator with the resulting
expression being the entire controlling expression of a
selection or iteration statement; or

- the entire expression of an expression statement (possibly
cast to void).

--
"Give me a couple of years and a large research grant,
and I'll give you a receipt." --Richard Heathfield

Steve Gravrock

unread,
Jun 26, 2002, 7:34:59 PM6/26/02
to

For an example of an exception system implemented in portable C, do a web
search for kazlib. Note that such a system won't help with your Dr. Watson
errors, as others have said.


--
"For those who want to translate C to Pascal, it may be that a lobotomy
serves your needs better." --M. Ambuhl in comp.lang.c
"Here are the steps to create a C-to-Turbo-Pascal translator..." --H. Schildt

Dan Pop

unread,
Jun 27, 2002, 4:57:12 AM6/27/02
to
In <slrnahkdui.4kc.re...@bolsh.wanadoo.fr> Dave Neary <real.addre...@thisoneis.invalid> writes:

>On 26 Jun 2002 13:18:05 GMT, Dan Pop said:
>
>> Of course, your program still invokes undefined behaviour by calling
>> printf in the signal handler, but, if Peter van der Linden could do that
>> in "Expert C Programming" (page 198), we shouldn't flame you too hard
>> for doing it ;-)
>
>So he did. Never noticed that :)

I was rewarded with one buck for doing it :-)

>Although he says in the footnote
>that it's undefined and that the example is merely for
>instructional purposes.

There is no footnote on that page in the first printing of the book :-)

Phil Tregoning

unread,
Jun 27, 2002, 10:30:04 AM6/27/02
to
Dan...@ifh.de (Dan Pop) wrote in news:afceud$221$1...@sunnews.cern.ch:

> In <slrnahjb74.vd2.re...@bolsh.wanadoo.fr> Dave Neary <real.addre...@thisoneis.invalid> writes:
>
>>A question on the behaviour of signal which seems unspecified by
>>the standard, and therefore (I guess) undefined. Although that's
>>not clear...
>>
>>Say I were to do this...
>>
>>#include <stdio.h>
>>#include <signal.h>
>>
>>void test(int sig)
>>{
>> printf("Get here\n");
> signal(SIGUSR1, test);
>> return;
>>}
>>
>>int main(void)
>>{
>> int i;
>> signal(SIGUSR1, test); /* Assume SIGUSR1 is a valid, existing,
>> * non-reserved signal, for arguments sake */
>>
>> for(i=0;i<10;i++)
>> {
>> raise(SIGUSR1);
>> }
>>
>> return 0;
>>}
>>

[SNIP]

>
> Of course, your program still invokes undefined behaviour by calling
> printf in the signal handler, but, if Peter van der Linden could do that
> in "Expert C Programming" (page 198), we shouldn't flame you too hard
> for doing it ;-)
>

I thought this was OK if the signal was the result of calling raise.

C99 7.14.1.1p5:

If the signal occurs _other_than_as_the_result_of_calling_the
abort_or_raise_function_, the behavior is undefined if the
signal handler refers to any object with static storage duration
[...], or the signal handler calls any function in the standard
library other than the abort function, the _Exit function, or
[...].

Phil T

Dan Pop

unread,
Jun 27, 2002, 11:09:10 AM6/27/02
to

What part of the standard guarantees that the signal will occur *only*
as the result of calling the abort or raise during program's execution?

Once you have installed a signal handler, all the bets are off, unless
the implementation guarantees no asynchronously delivered signals.

Phil Tregoning

unread,
Jun 27, 2002, 12:10:15 PM6/27/02
to
Dan...@ifh.de (Dan Pop) wrote in news:aff9qm$l6h$1...@sunnews.cern.ch:

>
> What part of the standard guarantees that the signal will occur *only*
> as the result of calling the abort or raise during program's execution?
>
> Once you have installed a signal handler, all the bets are off, unless
> the implementation guarantees no asynchronously delivered signals.
>

The implementation only need guarantee that the signal in
question will not be delivered asynchronously. Mine does
this for SIGUSR1 as used by the OP.

Phil T

Dan Pop

unread,
Jun 27, 2002, 12:51:22 PM6/27/02
to

>Dan...@ifh.de (Dan Pop) wrote in news:aff9qm$l6h$1...@sunnews.cern.ch:
>
>>
>> What part of the standard guarantees that the signal will occur *only*
>> as the result of calling the abort or raise during program's execution?
>>
>> Once you have installed a signal handler, all the bets are off, unless
>> the implementation guarantees no asynchronously delivered signals.
>
>The implementation only need guarantee that the signal in
>question will not be delivered asynchronously.

Obviously.

>Mine does this for SIGUSR1 as used by the OP.

On a Unix platform, any process running with root privileges can send the
SIGUSR1 signal to any other process.

Sean Eby

unread,
Jun 29, 2002, 12:40:06 AM6/29/02
to
"Dan Pop" <Dan...@ifh.de> wrote in message
news:afc9op$im7$1...@sunnews.cern.ch...

Excellent point Dan. It is nice to see someone point this out even
though we have sort of ventured off-topic. OTOH, the undefined behavior
here (although this program would probably work okay :) ) is that when
the infinite loop is running and someone hits CTRL-C, the signal handles
gets called and ANY functions that the signal handles calls that are not
re-entrant could cause problems, even the program's own functions. I
guess it is pretty dangerous. I'd be interested to find out if many of
the stdio functions are capable of re-entrancy so that someone's signal
handlers could at least safely output some useful message before calling
exit() or abort().

Sean Eby


Tor Rustad

unread,
Jun 30, 2002, 12:25:54 PM6/30/02
to
"Dave Neary" <real.addre...@thisoneis.invalid> wrote in message
> On 26 Jun 2002 11:06:23 GMT, Jeremy Yallop said:
> > * Dave Neary
> >| void interrupt(int sig)
> >| {
> >| fprintf(stderr, "Received a SIGINT signal - quitting\n");
> >| exit(0);
> >
> > Calling these functions from a signal handler invokes undefined
> > behaviour (in this case).
>
> Would you mind pointing out why?

The reason is rather obviouse, standard C doesn't require that
functions in the standard library like printf, to be reentrant.

So what? Well, the point is that if a function isn't reentrant _and_
get intrrupted _and_ then get called again from a signal handler,
you have a terrible mess...


> Would you mind enlightening me as to what exactly is undefined?

Even under POSIX.1, printf isn't garanteed to be reentrant. Also,
an implementation doesn't have to generate SIGINT (or any other
for that matter), for example Win32 doesn't.

--
Tor <torust AT online DOT no>

Dan Pop

unread,
Jul 1, 2002, 10:58:25 AM7/1/02
to
In <miGT8.970$HR.1...@news4.ulv.nextra.no> "Tor Rustad" <tor...@online.no.spam> writes:

>Even under POSIX.1, printf isn't garanteed to be reentrant. Also,
>an implementation doesn't have to generate SIGINT (or any other
>for that matter), for example Win32 doesn't.

The only conforming hosted Win32 implementations are the console mode
ones. They do generate SIGINT when CTRL-C is pressed, but the signal
is handled with subtly different semantics than one expects (at least,
this is documented by Microsoft).

Kevin Goodsell

unread,
Jul 1, 2002, 10:42:35 PM7/1/02
to

I think I know what Dan is talking about here. IIRC, the MS docs say
that the system spawns a new thread to handle the signal. The other
day I was playing around with a simple program that ran in an infinite
loop (capturing input from the COM port and displaying it) and I tried
to cause a signal handler to be called by CTRL-C. The handler was
supposed to cause the program to halt until the user pressed a key
(yes, I used non-standard functions - it was a quick-and-dirty
program), then exit. When I tested it, I was a little surprised at
first to see that the handler was called, but the main loop continued
to execute, displaying the data from the COM port.

-Kevin

0 new messages