Solved

fcloseall() on Solaris

Posted on 2003-12-09
14
872 Views
Last Modified: 2013-12-05
All

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
echard
0
Comment
Question by:echard
  • 4
  • 3
  • 2
  • +2
14 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
See the 'fcloseall()' manpage:

NAME
       fcloseall - close all open streams

SYNOPSIS
       #define _GNU_SOURCE

       #include <stdio.h>

       int fcloseall(void);

DESCRIPTION
       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
       closed.

RETURN VALUE
       This function always returns 0.

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

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


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

Expert Comment

by:Kdo
Comment Utility
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.


Kent
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>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)
0
 
LVL 45

Expert Comment

by:Kdo
Comment Utility

Hi jkr,

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

Much like most code involving Oracle.  :)

kent
0
 

Author Comment

by:echard
Comment Utility
All

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...

Kent

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.

echard
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>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...

0
 
LVL 45

Accepted Solution

by:
Kdo earned 125 total points
Comment Utility

>>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++));


Kent
0
 

Author Comment

by:echard
Comment Utility
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...

Thoughts?

echard
0
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
>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

/proc/<pid>/fd
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
0
 
LVL 1

Expert Comment

by:imstaff
Comment Utility
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++)
     fclose(fileNamePtr[i]);
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Um, why if I may ask?
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Introduction Regular patching is part of a system administrator's tasks. However, many patches require that the system be in single-user mode before they can be installed. A cluster patch in particular can take quite a while to apply if the machine…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

762 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

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now