keypresses and signal handling

R

Rich

Hi,

In my program I want it so when the users presses the space bar (or
any other key if it is easier) they get a printf("hello, I am still
processing your request please wait") while the program is doing its
work. I added a signal handler to catch Ctrl-C and that works great
(i.e the program gracefully exits instead of crashes). Is there some
other signal I can use to do what I want?

Thanks,
 
E

Eric Sosman

Hi,

In my program I want it so when the users presses the space bar (or
any other key if it is easier) they get a printf("hello, I am still
processing your request please wait") while the program is doing its
work. I added a signal handler to catch Ctrl-C and that works great
(i.e the program gracefully exits instead of crashes). Is there some
other signal I can use to do what I want?

C itself has no such capability, although the systems C runs on
may offer something. Check your system's documentation.

By the way, you almost certainly do *not* want to call printf()
in a signal handler, nor any other library function that your system's
documentation does not specifically describe as "async signal safe" or
something along those lines. Trouble can occur (usually, does occur)
if the signal arrives while the program is executing printf(), or some
other function (malloc(), maybe?) that printf() calls internally. If
you're half-way through a realloc() call, go into the signal handler
while realloc() has flour scattered all over the kitchen and the fridge
door hanging open, and then try to call malloc() before anybody's
had a chance to tidy up -- well, the outcome is seldom a happy one.

An alternative you might consider is to display some kind of
animated progress indicator: A number that starts at 417 and counts
down to zero, or a little twirling baton, or something like that. See
Question 19.3 on the comp.lang.c Frequently Asked Questions (FAQ) page
at <http://www.c-faq.com/>.
 
S

Seebs

Hi,

In my program I want it so when the users presses the space bar (or
any other key if it is easier) they get a printf("hello, I am still
processing your request please wait") while the program is doing its
work. I added a signal handler to catch Ctrl-C and that works great
(i.e the program gracefully exits instead of crashes). Is there some
other signal I can use to do what I want?

Not in general, no. This is a FAQ. You may find it useful to read
the newsgroup's FAQ:

http://c-faq.com/

-s
 
U

Uno

Eric said:
By the way, you almost certainly do *not* want to call printf()
in a signal handler, nor any other library function that your system's
documentation does not specifically describe as "async signal safe" or
something along those lines. Trouble can occur (usually, does occur)
if the signal arrives while the program is executing printf(), or some
other function (malloc(), maybe?) that printf() calls internally. If
you're half-way through a realloc() call, go into the signal handler
while realloc() has flour scattered all over the kitchen and the fridge
door hanging open, and then try to call malloc() before anybody's
had a chance to tidy up -- well, the outcome is seldom a happy one.

I would claim the exception when you're testing it to see if it's ever
being used. I get stung on related issues regularly.


$ gcc -Wall -Wextra u4.c -o out
$ ./out
42
[file u4.c, line 14]: hey, x=-1207183232
$ cat u4.c
// debugging macros so we can pin down message provenance at a glance
#define WHERESTR "[file %s, line %d]: "
#define WHEREARG __FILE__, __LINE__
#define DEBUGPRINT2(...) fprintf(stderr, __VA_ARGS__)
#define DEBUGPRINT(_fmt, ...) DEBUGPRINT2(WHERESTR _fmt, WHEREARG,
__VA_ARGS__)

#include <stdio.h>

int main (void)
{
int x; //never gave it a value

printf("42\n");
DEBUGPRINT("hey, x=%d\n", x);
return 0;
}


// gcc -Wall -Wextra -dD -E u4.c >text1.txt
// gcc -Wall -Wextra u4.c -o out
$

Are __VA_ARGS__ and _fmt defined in a standard way?
 
G

Geoff

Why not answer the bloody question instead of passing him off to a
massive FAQ?

Probably because he doesn't know the specific FAQ that pertains to the
question and he refuses to do the OP's searching for him.

Perhaps also because a search of the linear FAQ index:
http://c-faq.com/questions.html for "keypress" or "signal" or
"handling" yields no results.
 
U

Uno

Ian said:
On 09/26/10 04:14 PM, Richard wrote:

Why don't you? Oh, I forgot you're only here to snipe.


So Ian, are you the second english information non-provider here on this
thread, because unlike seebs, I like you.

Crap Almighty, I think OP is fishing for something that begins with SEG
in caps.

You didn't forget, and you are here to snipe, which has a regional
interpretation.
 
L

luserXtrog

Hi,

In my program I want it so when the users presses the space bar (or
any other key if it is easier) they get a printf("hello, I am still
processing your request please wait") while the program is doing its
work.  I added a signal handler to catch Ctrl-C and that works great
(i.e the program gracefully exits instead of crashes).  Is there some
other signal I can use to do what I want?

Thanks,

If you've got POSIX, this might work.
You send a SIGINT with ^c (as you know)
and a SIGQUIT with ^\.



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

#include <termios.h>
#include <unistd.h>

struct termios ts;

void on_int (int sig) {
puts("bye");
tcsetattr(fileno(stdin), TCSANOW, &ts);
exit(0);
}

void on_quit (int sig) {
puts("hello, I am still processing your request please wait");
}

int main() {

{ /* Enable other signal keys */
struct termios tsb;
tcgetattr(fileno(stdin), &ts);
tsb = ts;
tsb.c_lflag = ISIG;
tcsetattr(fileno(stdin), TCSANOW, &tsb);
}

{ /* Install Signal Handlers */
signal(SIGINT, on_int);
signal(SIGQUIT, on_quit);
}

while(1) {
usleep(500);
}
return 0;
}

/* eof */
 
M

Malcolm McLean

In my program I want it so when the users presses the space bar (or
any other key if it is easier) they get a printf("hello, I am still
processing your request please wait") while the program is doing its
work.  I added a signal handler to catch Ctrl-C and that works great
(i.e the program gracefully exits instead of crashes).  Is there some
other signal I can use to do what I want?
kbhit() does what you want (I think, it's ages since I used it). It is
available on DOS.

just write if(khit()) printf("hello, I am still processing your
request please wait") somewhere in u=your inner loop. You might also
need to read the character.

If you don't have kbhit() this page gives an implementation for linux.

http://www.linux-sxs.org/programming/kbhit.html
 
S

Seebs

kbhit() does what you want (I think, it's ages since I used it). It is
available on DOS.

But on DOS, does ^C generate SIGINT?

The systems I've used where ^C can trigger a "signal handler" have not
been DOS... And the Linux "implementation" is sorta questionable.

This advice actually does a great job of showing why the FAQ is a
better answer than trying to write a specific answer. This is a pretty
tricky thing to get right for most platforms, and even on DOS, it's
not at all obvious that the kbhit() solution is a particularly good
choice. There are many ways of approaching this problem. The most
reasonable, for most targets, do not involve polling at all.

-s
 
B

Ben Bacarisse

luserXtrog said:
If you've got POSIX, this might work.
You send a SIGINT with ^c (as you know)
and a SIGQUIT with ^\.



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

#include <termios.h>
#include <unistd.h>

struct termios ts;

void on_int (int sig) {
puts("bye");
tcsetattr(fileno(stdin), TCSANOW, &ts);
exit(0);
}

void on_quit (int sig) {
puts("hello, I am still processing your request please wait");
}

Neither of these signal handlers is "safe". I don't think POSIX alters
what you can do in a signal handler -- puts is definitely out both in
standard C and in C+POSIX.

The general way to do this is to have the signal handler set a flag (of
type sig_atomic_t) and have this checked in the processing loop that is
taking so much time. That loop can print anything it likes. That's
both a C answer and a POSIX one.

<snip>
 
S

Sarin

I was just wondering why no one suggested using threads. May be its an
overkill. But, I think a thread should do it(?) Please tell me if I am
wrong.
 
S

Seebs

I was just wondering why no one suggested using threads. May be its an
overkill. But, I think a thread should do it(?) Please tell me if I am
wrong.

Because threads aren't (as of yet) a standard feature of C, and there
exist a fair number of implementations which don't have threading. Perhaps
more importantly, the threading implementations out there are largely
different from each other. As a result, any specific advice on this
is pretty much doomed to be system-specific.

So the best advice would be for the OP to ask about good ways to achieve
this result in a group specific to the target platform. The people here
are, unfortunately, sometimes a bit prone to confusion about the various
platforms, especially the ones they don't use...

-s
 
N

Nick

Uno said:
So Ian, are you the second english information non-provider here on
this thread, because unlike seebs, I like you.

Crap Almighty, I think OP is fishing for something that begins with
SEG in caps.

You didn't forget, and you are here to snipe, which has a regional
interpretation.

Did you help him.

The whole bloody point of a FAQ is that it holds good, detailed, answers
to FREQUENTLY ASKED QUESTIONS. It's almost always /far/ better to refer
someone to a FAQ than to try to answer the question yourself.
 
B

BartC

Malcolm McLean said:
kbhit() does what you want (I think, it's ages since I used it). It is
available on DOS.

Where the processing is complex you really don't want to sprinkle kbhit()s
all over the place (eg. in a library).

And I'm not sure it handles Ctrl-C properly.
 
B

BartC

The whole bloody point of a FAQ is that it holds good, detailed, answers
to FREQUENTLY ASKED QUESTIONS. It's almost always /far/ better to refer
someone to a FAQ than to try to answer the question yourself.

IME, no FAQ I've ever seen on a website has ever answered my specific
question.

This forces you to call a premium rate number to talk to an operator, and it
is incredibly annoying when the first minute is spent telling you to visit
the website! No-one ever calls these numbers unless they have to.

I remember this classic example of a completely useless (and lazy) response
to a pretty straightforward question:
 
K

Kenny McCormack

Richard said:
Why not answer the bloody question instead of passing him off to a
massive FAQ?

The various BS answers have been given, but the real reason why it is
better (heh heh) to just point at a FAQ is that if you actually answer
someone's question, you are entering into a support relationship with
the person. That is, you are expected to continue to handle the
followup questions until such time as the poster is happy. And that can
be a long slog.

--
But the Bush apologists hope that you won't remember all that. And they
also have a theory, which I've been hearing more and more - namely,
that President Obama, though not yet in office or even elected, caused the
2008 slump. You see, people were worried in advance about his future
policies, and that's what caused the economy to tank. Seriously.

(Paul Krugman - Addicted to Bush)
 
S

Seebs

IME, no FAQ I've ever seen on a website has ever answered my specific
question.

The comp.lang.c FAQ has repeatedly answered my specific questions. Often
in great detail.

And while I have often had support people refer me to a useless "FAQ" site,
I have also seen a few company-provided FAQs that really did cover my
problem.

-s
 
R

Rich

     C itself has no such capability, although the systems C runs on
may offer something.  Check your system's documentation.

     By the way, you almost certainly do *not* want to call printf()
in a signal handler, nor any other library function that your system's
documentation does not specifically describe as "async signal safe" or
something along those lines.  Trouble can occur (usually, does occur)
if the signal arrives while the program is executing printf(), or some
other function (malloc(), maybe?) that printf() calls internally.  If
you're half-way through a realloc() call, go into the signal handler
while realloc() has flour scattered all over the kitchen and the fridge
door hanging open, and then try to call malloc() before anybody's
had a chance to tidy up -- well, the outcome is seldom a happy one.

     An alternative you might consider is to display some kind of
animated progress indicator: A number that starts at 417 and counts
down to zero, or a little twirling baton, or something like that.  See
Question 19.3 on the comp.lang.c Frequently Asked Questions (FAQ) page
at <http://www.c-faq.com/>.

My interrupt handler sets a flag variable to 1 and the variable is
tested at key points in the program where the program can flush the
buffers and close all of the open files. As I understand signal
handling (which I admit is limited) if I am in a function that is
doing a malloc (I don't have realloc in my program) and I press Ctrl-C
during the malloc then my program jumps to my signal handler. My
signal handler sets my flag to 1 (flag is a global variable
initialized to 0, and the programs continues where it left off. So in
my case I should be safe. Do I understand this properly?

19.3 is a good start. I was hoping to avoid having something
(progress bar or baton) constantly showing while the program was
running as that would consume processor cycles making the program
slower. Slower by how much I don't know until I do some testing.

I am trying to keep my program OS independent so I really don't want
to use ncurses or some other OS specific library. I realize my
program is almost always used on Linux so POSIX should be available.
SIGQUIT looks promising but I don't know if it works the same the way
on windows 7 or XP.

I gave the FAQ a look over but I didn't read section 19. Displaying a
progress bar or baton doesn't seem like a system dependency to me. It
seems for like a stdio or Miscellaneous to me.

Thank you everyone for your input. I have quite a bit of research and
coding to do to see what will work best for me.

Thanks,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top