Link to home
Start Free TrialLog in
Avatar of luoys
luoys

asked on

How to delete a file automatically when the application terminates

I want to use create a file in a known place when application starts so I can know how many instance of the application is running by doing the following:

class ResourceCount
{
private:
      int m_h;
      
public:
      void Init(int id)
      {
            char buf[1000];
            sprintf(buf, "/tmp/process_%d.cnt", getpid());
            
            int flags = O_CREAT|O_WRONLY;
            int mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
            mode_t m = umask(0);
            m_h = open( buf, flags, mode );
            umask(m);
            
            unlink(buf);
      }

      void Release()
      {
            close(m_h);
      }

};

However, as soon as I unlink() the file, the file disappeared from the file system. Is there any way I can make sure the file gets deleted should the process terminates but visible during the life time of the process?

Avatar of NovaDenizen
NovaDenizen

Check man atexit.

int atexit(void (*func)(void));

In your program:
char file_to_delete[MAX_PATH];
void delete_the_file() {
    if (file_to_delete[0]) { // safety check
        unlink(file_to_delete);
    }
    file_to_delete[0] = '\0';
}

class ResourceCount
{
private:
     int m_h;
     
public:
     void Init(int id)
     {
          sprintf(file_to_delete, "/tmp/process_%d.cnt", getpid());
         
          int flags = O_CREAT|O_WRONLY;
          int mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
          mode_t m = umask(0);
          m_h = open(file_to_delete, flags, mode );
          umask(m);
          atexit(delete_the_file);
      }

     void Release()
     {
          close(m_h);
     }

};
Avatar of luoys

ASKER

Nova, thx. However this does not fit my requirement. I need the file to be deleted should the application crashes, which won't execute atexit().
It depends on how you crash.  You can set up signal handlers for segmentation faults, broken pipes, bus errors, all the usual suspects.  Check man signal, and look at the list of signals in /usr/include/signal.h (SIGSEGV, SIGBUS, etc).  You can create a clean-up function and install it as the signal hander for all of the signals that might be used when your program crashes.

The table in this article lists the default actions for signals when you have not installed a signal handler.
http://www.cs.uregina.ca/Links/class-info/330/Signals/signals.html

You basically need to install your clean-up function as the signal handler for all of the signals whose default action includes "Exit".
Avatar of sunnycoder
man 3 tmpfile ... I am not sure if it would delete the file if you exit abnormally, but since it is the system which deletes the file, you can give it a try.
as sunnycoder said: tmpfile() is the solution, see
  man tmpfile
  man tmpnam


 there is a better way ,

 from main , u do all operation . Just fork() , make child to sleep for a while , or make interruptible sleep .
Allow main to die ,  Before that wake up the child .The zombie process can  ,using system call can
 delete the specified file and  exit() .


1. How does the child decide when to delete the file
2. You are using more system resources and creating zombies, how is this a "better" way?
> there is a better way ,
why should this suggestion be better than that what libc already provides: tmpfile?
Because other programs are learning the status of the system by looking in a directory and looking at the files there, each file corresponding to a running process.  The contents of the files are irrelevant; only the filename and the existence of the file matter.
>  Because other programs are learning the status of the system by looking in a directory ..
.. and if the system reboots after a crash or whatever these files deliver a wrong status :-(
so you have to take care for additional cleanup of such files (like the ugly pid files on some systems)
You end up in to seperate programs: one createing the "status files" and another to keep house-cleaning.
Use tmpfile() which does all for you without thinking about

KISS - keep it simple stupid
> KISS - keep it simple stupid
Deleting leftover process files on reboot is pretty simple. :)

No matter how many times you recommend it, tmpfile still doesn't create a visible file in the filesystem.  In the original question:
"Is there any way I can make sure the file gets deleted should the process terminates but visible during the life time of the process?"
How does tmpfile fulfill this desire?
> How does tmpfile fulfill this desire?
1. read man tmpfile
2. if you mean "visability", simply do a: ls -la /var/tmp
   (well, this solution probably does not fit the questioners requirements, but it answers the requirement expressed in the question itself:-)
ASKER CERTIFIED SOLUTION
Avatar of NovaDenizen
NovaDenizen

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
agreed for 2., seems that my libc knowledge is a bit rusty ...
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
My interpretation of the question is that the end goal is to count running instances of an application on a single machine, and that file creation and deletion was merely the questioner's attempt to achieve this. The example filename, "/tmp/process_%d.cnt", is certainly a local file (with PID as the variable part, only locally unique), and the file name confirms the purpose of the file as simply a counting method.

I believe a Sys V semaphore would achieve this goal without mucking around with creating files at all.

But this all seems moot as the questioner hasn't said anything after the first hour of the question.