Code Comments
Programming Forum and web based access to our favorite programming groups.I am trying to write some code that writes to a FIFO (whenever there is
a reader, of course) but can't figure out how I can be able to block in
the call to open() (waiting for a reader), and at the same time check
the value of a variable (sig_atomic_t exit_flag, set to 1 when SIGINT or
SIGTERM is recieved).
I did find one way to do it, but it uses too much CPU polling (adding a
call to sleep(1) does help tremendously but just doesn't seem like The
Right Way to me):
while(!exit_flag) {
..
fd = open(file, O_WRONLY | O_NONBLOCK);
if(fd < 0) {
if(errno == ENXIO)
continue;
..
}
..
}
I thought of possibly using select() (?), but I've never used it before
and it seems complicated from reading the manual page. I checked in
UNPv2 and got the basic concept of select(), however, Mr. Stevens uses
it in a network context. From reading the manual page, though, I think
it would still end up blocking somewhere.
I'm out of ideas... can someone spare any?
Thanks
--
"And remember: Evil will always prevail, because Good is dumb." --
Spaceballs
/* Aaron Walker
* http://ka0ttic.butsugenjitemple.org/
*/
Post Follow-up to this messageAaron Walker <ka0ttic@butsugenjitemple.org> writes: > I am trying to write some code that writes to a FIFO (whenever there > is a reader, of course) but can't figure out how I can be able to > block in the call to open() (waiting for a reader), and at the same > time check the value of a variable (sig_atomic_t exit_flag, set to 1 > when SIGINT or SIGTERM is recieved). Blocking system calls usually return with an errno of EINTR if a signal arrives. > I thought of possibly using select() (?), but I've never used it > before and it seems complicated from reading the manual page. Just bite the bullet, you'll have to learn how to use select() sooner or later. > I checked in UNPv2 and got the basic concept of select(), however, > Mr. Stevens uses it in a network context. select() can be used with any file descriptor. > From reading the manual page, though, I think it would still end up > blocking somewhere. Of course, that's the idea with select(). However, select(), unlike open/read/write etc., allows you to specify a timeout. -- Måns Rullgård mru@kth.se
Post Follow-up to this messageAaron Walker <ka0ttic@butsugenjitemple.org> wrote: > I am trying to write some code that writes to a FIFO (whenever there is > a reader, of course) but can't figure out how I can be able to block in > the call to open() (waiting for a reader), and at the same time check > the value of a variable (sig_atomic_t exit_flag, set to 1 when SIGINT or > SIGTERM is recieved). If I am understanding you correctly you have a signal handler in the background that sets 'exit_flag' when the signal arrives. If the signal arrives also the open() call should return and you get a -1 return value and errno is set to EINTR. Now you can check if the value of 'exit_flag' has been changed and thus determine if the signal you were waiting for has arrived. So I would guess you don't need select() or anything complicated at all - just call open() in blocking mode and wait for it to return. If it's because of the signal you'll know because of the return value and errno being set to EINTR. Regards, Jens -- \ Jens Thoms Toerring ___ Jens.Toerring@physik.fu-berlin.de \__________________________ http://www.toerring.de
Post Follow-up to this messageMåns Rullgård wrote: > Aaron Walker <ka0ttic@butsugenjitemple.org> writes: > > > > Firstly, thanks for such a quick response. > Blocking system calls usually return with an errno of EINTR if a > signal arrives. That's what I thought too, however, when adding a check for EINTR, into a normal (blocking) call to open(), nothing happens at all when the program is thrown a SIGINT or SIGTERM. > > > > > Just bite the bullet, you'll have to learn how to use select() sooner > or later. That's what I'm trying to do ;p > > > > > select() can be used with any file descriptor. I know that, I was just mainlyabout one thing. Wouldn't you have to open() the descriptor before placing it in a fd_set and calling select()? If that's the case then I have the same problem. > > > > > Of course, that's the idea with select(). However, select(), unlike > open/read/write etc., allows you to specify a timeout. > what's the best way of going about choosing a timeout? I'm clueless here... Thanks again -- BOFH Excuse #404: Sy
min accidentally destroyed pager with a large hammer. /* Aaron Walker * http://ka0ttic.butsugenjitemple.org/ */
Post Follow-up to this messageJens.Toerring@physik.fu-berlin.de wrote:
> Aaron Walker <ka0ttic@butsugenjitemple.org> wrote:
>
>
>
> If I am understanding you correctly you have a signal handler in
> the background that sets 'exit_flag' when the signal arrives. If
> the signal arrives also the open() call should return and you
> get a -1 return value and errno is set to EINTR. Now you can
> check if the value of 'exit_flag' has been changed and thus
> determine if the signal you were waiting for has arrived. So
> I would guess you don't need select() or anything complicated
> at all - just call open() in blocking mode and wait for it to
> return. If it's because of the signal you'll know because of
> the return value and errno being set to EINTR.
>
> Regards, Jens
As I said in my other post a second ago, I tried this, expecting it to
work as well, but it didn't. Here's the code I had attempting to do this:
sig_atomic_t exit_flag = FALSE;
void
signal_handler(int signal)
{
exit_flag = TRUE;
}
int
main(int argc, char **argv)
{
int fd, exit_status;
struct sigaction sig;
..
sig.sa_handler = &signal_handler;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
..
while(!exit_flag) {
..
fd = open(file, O_WRONLY);
if(fd < 0) {
if(errno == EINTR) {
if(exit_flag)
break;
else continue;
}
perror("open");
exit_status = EXIT_FAILURE;
break;
}
..
}
..
}
Any reason why this wouldn't work?
Thanks again
--
Knocked, you weren't in. -- Opportunity
/* Aaron Walker
* http://ka0ttic.butsugenjitemple.org/
*/
Post Follow-up to this messageAaron Walker <ka0ttic@butsugenjitemple.org> wrote:
> As I said in my other post a second ago, I tried this, expecting it to
> work as well, but it didn't. Here's the code I had attempting to do this:
> sig_atomic_t exit_flag = FALSE;
> void
> signal_handler(int signal)
> {
> exit_flag = TRUE;
> }
> int
> main(int argc, char **argv)
> {
> int fd, exit_status;
> struct sigaction sig;
> ...
> sig.sa_handler = &signal_handler;
> sigemptyset(&sig.sa_mask);
> sig.sa_flags = 0;
> ...
> while(!exit_flag) {
> ...
> fd = open(file, O_WRONLY);
> if(fd < 0) {
> if(errno == EINTR) {
> if(exit_flag)
> break;
> else continue;
> }
> perror("open");
> exit_status = EXIT_FAILURE;
> break;
> }
> ...
> }
> ...
> }
After filling in the missing pieces (i.e. actually installing the
signal handler etc.) it works perfectly well for me - when I send
it a SIGINT or SIGTERM I can see that errno is set to EINTR and
that 'exit_flag' has been set to 1. I don't know why it isn't
working for you - can you post a complete program that doesn't
interrupts open() on a signal? Otherwise it's going to be hard to
figure out what's wrong.
Regards, Jens
--
\ Jens Thoms Toerring ___ Jens.Toerring@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Post Follow-up to this messageJens.Toerring@physik.fu-berlin.de wrote: > > After filling in the missing pieces (i.e. actually installing the > signal handler etc.) it works perfectly well for me - when I send > it a SIGINT or SIGTERM I can see that errno is set to EINTR and > that 'exit_flag' has been set to 1. I don't know why it isn't > working for you - can you post a complete program that doesn't > interrupts open() on a signal? Otherwise it's going to be hard to > figure out what's wrong. > Regards, Jens http://cvs.butsugenjitemple.org/vie....viewcvs-markup once again, thanks for your help. Cheers
Post Follow-up to this messageAaron Walker <ka0ttic@butsugenjitemple.org> wrote: > Jens.Toerring@physik.fu-berlin.de wrote: > http://cvs.butsugenjitemple.org/vie....viewcvs-markup Sorry, but jens@john:~> ping cvs.butsugenjitemple.org ping: unknown host cvs.butsugenjitemple.org Regards, Jens -- \ Jens Thoms Toerring ___ Jens.Toerring@physik.fu-berlin.de \__________________________ http://www.toerring.de
Post Follow-up to this messageJens.Toerring@physik.fu-berlin.de wrote: > Aaron Walker <ka0ttic@butsugenjitemple.org> wrote: > > > > > > Sorry, but > > jens@john:~> ping cvs.butsugenjitemple.org > ping: unknown host cvs.butsugenjitemple.org > > Regards, Jens Hmm... maybe virtual hosting isn't working as well as I thought ;) This one *should* work: http://butsugenjitemple.org/viewcvs....viewcvs-markup Apologies Aaron
Post Follow-up to this messageAaron Walker <ka0ttic@butsugenjitemple.org> writes: > Jens.Toerring@physik.fu-berlin.de wrote: > > Hmm... maybe virtual hosting isn't working as well as I thought ;) > > This one *should* work: > > http://butsugenjitemple.org/viewcvs....viewcvs-markup Remove these lines: #ifdef SA_RESTART sig.sa_flags |= SA_RESTART; #endif The SA_RESTART flag tells the OS that you do not want system calls to return on signals. -- Måns Rullgård mru@kth.se
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.