How dirty is setjmp+fopen+longjmp ?

  • Thread starter Thomas Baruchel
  • Start date
T

Thomas Baruchel

Hi,

wondering about:

func1: setjmp() ; func2();
func2: {FILE *f; f = fopen(); func3(); fclose(f)}
func3 : if() longjmp; else return;

Note that FILE *fis a local variable in func2.

How dirty is that ?
Will some dirty things remain in the RAM ?
file is in RAMDISK and is intended to be opened thousands of time;
don't ask me why.
Is there a risk to have fopen() fail because of too many times opened
without having been closed ?

Or in contrary, is it clean? After all, FILE *f is local, fopen is
after the setjmp...

System is unix in case it has some importance.
 
D

Dave Vandervies

Hi,

wondering about:

func1: setjmp() ; func2();
func2: {FILE *f; f = fopen(); func3(); fclose(f)}
func3 : if() longjmp; else return;

Note that FILE *fis a local variable in func2.

How dirty is that ?
Will some dirty things remain in the RAM ?
file is in RAMDISK and is intended to be opened thousands of time;
don't ask me why.
Is there a risk to have fopen() fail because of too many times opened
without having been closed ?

If the longjmp gets called, the file you opened in func2 won't get
closed. Typically this means that anything you wrote to the file
(through the stdio FILE) may not have made it into the actual file
in the OS's filesystem; there's also usually a limit on the number of
"file descriptors" a program can have open, and opening the same file
multiple times will use multiple file descriptors.
Or in contrary, is it clean? After all, FILE *f is local, fopen is
after the setjmp...

Local variables after a setjmp disappear without any cleanup. The
buffers, OS file descriptors, and other fun things that the FILE * points
at will leak, because the call to fclose gets skipped by the longjmp.


There are a few ways of making this work (others may come up with
even more):

-Remove the setjmp/longjmp
Usually (but not always) there's a better (where "better" includes
factors like "cleaner", "easier", and "leaves the code more maintainable",
balanced appropriately) way to do things than to use setjmp and longjmp.
You haven't provided enough information for me to comment on whether
your case is likely to be an exception to this.

-Move the fopen/fclose outside the setjmp/longjmp
If this is a temporary file that the program uses quite a bit, it may
be better to do something like:
--------
func1:
open temporary file
call setjmp
do stuff including calling func2 (possibly multiple times)
close temporary file

func2:
do stuff with FILE * that comes from func1, including calling
func3

func3:
do stuff, possibly including calling longjmp to go back to the
setjmp in func1
--------
rather than opening and closing it in func2

-Make the FILE * static and make sure anything from a previous call
is cleaned up or re-used when func2 starts. Variables with static
duration are required to act the way you'd expect variables to act even
in the presence of setjmp and longjmp, so you can rewrite func2 to look
something like this:
--------
return_type func2(args)
{
static FILE *f=NULL;
if(f)
{
/*We've left the file open from a previous call (either
by longjmping out, or by deciding not to close it
when we're done. We may want to check or reset
some status, like where in the file we're looking,
or maybe just close and re-open it.
*/
rewind(f);
}
else
{
/*We don't currently have the file open, so open it*/
f=fopen("filename",mode_flags);
}

/*Do stuff here, including calling func3 (which may longjmp back
to func1)
*/

if(we_want_to_close_the_file)
{
fclose(f);
/*Don't forget to clear the local pointer as well, so that
we don't think the file is still open on the next call.
*/
f=NULL;
}

return return_value;
}
--------

System is unix in case it has some importance.

This affects exactly what the consequences of leaving a file unclosed
are, but won't affect the problem with longjmp not cleaning them up.
In general, unix-specific questions (which this one isn't) should go
to comp.unix.programmer.


dave
 
E

Eric Sosman

Thomas said:
Hi,

wondering about:

func1: setjmp() ; func2();
func2: {FILE *f; f = fopen(); func3(); fclose(f)}
func3 : if() longjmp; else return;

Note that FILE *fis a local variable in func2.

How dirty is that ?

Filthy. Covered with mud and muck, not to mention
slime. Unhealthy, disease-ridden, and disgusting.
Will some dirty things remain in the RAM ?
file is in RAMDISK and is intended to be opened thousands of time;
don't ask me why.
Is there a risk to have fopen() fail because of too many times opened
without having been closed ?

Yes. If func3() jumps right back to func1(), func2()
never gets a chance to call fclose(). The implementation
is not required to support an infinite number of un-closed
streams.
Or in contrary, is it clean? After all, FILE *f is local, fopen is
after the setjmp...

This has nothing to do with anything, as far as I can see.
System is unix in case it has some importance.

It doesn't. If it did, the question would be off-topic.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top