Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


fcloseall() on Solaris

Posted on 2003-12-09
Medium Priority
Last Modified: 2013-12-05

I have a program that loads an Oracle shared object, after performing a truss on the process I noticed that Oracle is not closing all the files it is opening, thus after numerous iterations (255 unclosed file handles) the program quits responding to any future file requests... Thus I want to attempt to close these left open file handles after they are done being used... I have read about a function fcloseall() that should help in accomplishing what I am trying to do, however, I can not get it to work on Solaris 8... At compile time I get an undefined symbol... Does anyone either know how to get fcloseall() to work on Solaris, or have a piece of code that will accomplish this (i.e. closing all file handles generated by the current proces or subprocesses)?

Best regards
Question by:echard
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +2
LVL 86

Expert Comment

ID: 9906199
See the 'fcloseall()' manpage:

       fcloseall - close all open streams

       #define _GNU_SOURCE

       #include <stdio.h>

       int fcloseall(void);

       The  fcloseall  function dissociates all open streams from
       its underlying file or set  of  functions.   Any  buffered
       output  data is written first, using fflush(3).  Note that
       the standard streams (stdin, stdout and stderr)  are  also

       This function always returns 0.

       fclose(3), close(2), fflush(3), fopen(3), setbuf(3)

       The fcloseall function is a GNU extension. <-------!

This means that unless you can use gcc and its runtime library, you are pretty much lost.
LVL 46

Expert Comment

by:Kent Olsen
ID: 9906390
Hi echard,

I'm going to caution you that fcloseall() is inherently dangerous and will very likely not produce the effect that you seek.

fcloseall() closes ALL the streams associated with your task.  This includes stdin, stdout, and stderr.  Many library routines depend on these standard streams so you would have to immediately reopen these streams to prevent a routine from attempting I/O to a standard stream only to find that the FILE pointer now contains garbage.

Can you guarantee that the other streams are abandoned?  Closing a stream (or file handle) when another portion of the application is expecting a valid pointer can also be catastrophic.

My suggestion would be to structure your program so that it fork()s off a child process that handles the Oracle interface.  Data is passed to/from parent and child via pipes.  Your application is free to operate in a rational manner while the child task(s) get to handle all of the I/O including the database interfaces.  Open streams are automatically closed when the child terminates so the ugly side effects that you're seeing now can be avoided.

LVL 86

Expert Comment

ID: 9906433
>>fcloseall() closes ALL the streams associated with your task.

That's why I did not suggest 'for ( int i = 3; i < NFILES; close (i++));' as a workaround :o)
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 46

Expert Comment

by:Kent Olsen
ID: 9906578

Hi jkr,

Yeah... There is no good and easy solution to his problem.

Much like most code involving Oracle.  :)


Author Comment

ID: 9907296

I was under the impressions that fcloseall() would leave stdin, stdout, stderr all open and close all other files. However I accept what you said above Kent and jkr... The only good thing about this mess is that I know that I can safely close all file handles above the stdin, stdout, stderr handles (0,1,2) thus a solution similar to jkr's of 'for ( int i = 3; i < NFILES; close (i++));'  may work as an ugly fix until Oracle addresses the issue. I do realize and jkr please forgive this statement that it is an ugly solution and highly undesirable, but it is pertinent that I get these open file handles closed before reaching the soft limit of 256...

I do have a question assuming I use jkr's solution what is the easiest way to determine the current value of NFILES... in other words is it a macro that contains the value? where is it defined? etc...


I have thought about forking a child process, however that solution is goint o take a little time to implement and I need a short term solution.

Guys please provide thoughts as desired.

LVL 86

Expert Comment

ID: 9907372
>>what is the easiest way to determine the current value of NFILES

You answered that by writing 'before reaching the soft limit of 256...' :o)

However, this method is not recommended, even though it is common practise when starting a daemon...

LVL 46

Accepted Solution

Kent Olsen earned 500 total points
ID: 9907455

>>what is the easiest way to determine the current value of NFILES

C assigns file handles incrementally starting with the lowest available handle.  Since you believe that Oracle is never closing a file you can open a file which should therefore return a handle one higher than the last one used by Oracle.  The use this handle as the upper limit.

int  UpperLimit;
int  idx;

  UpperLimit = open ("LimitCheck", O_CREAT|O_TRUNC);
  for (idx = 3; i <= UpperLimit; close (idx++));


Author Comment

ID: 9908650
Kent and jkr

Thanks for all of your help to this point...

The more I think about it I am wondering if there is a way to close all open file handles pointing to a specific file... For example on of the problem files in {$ORACLE_HOME}/xdk/xdk/mesg/lsxus.msb that is being left open is there a way that either of you may be aware of to "query" for all open file handles that end in *.msb and get the file id for them and then close them accordingly? Just thinking this may be way safer since I am using such an undesirable approach to begin with...


LVL 45

Expert Comment

ID: 9910001
>The more I think about it I am wondering if there is a way to close all open file handles pointing to a specific file
do you have /proc file system on solaris ... or some equivalent information source ...

if yes, then

has list of all fds and their corresponding files ... you need to parse the result , search for the specific file and close all associated fds

Expert Comment

ID: 9922215
This function is an extension to fclose. Even though Solaris supports fclose, fcloseall is not supported. You can use fclose to implement fcloseall: Assuming there is an array of FILE *streams, called fileNamePtr[i]:

for(i = 0; i < MAXSTREAMS; i++)
LVL 86

Expert Comment

ID: 10999831
Um, why if I may ask?

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Why Shell Scripting? Shell scripting is a powerful method of accessing UNIX systems and it is very flexible. Shell scripts are required when we want to execute a sequence of commands in Unix flavored operating systems. “Shell” is the command line i…
Every server (virtual or physical) needs a console: and the console can be provided through hardware directly connected, software for remote connections, local connections, through a KVM, etc. This document explains the different types of consol…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
Suggested Courses

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question