Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 239
  • Last Modified:

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?

0
luoys
Asked:
luoys
  • 5
  • 5
  • 2
  • +4
3 Solutions
 
NovaDenizenCommented:
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);
     }

};
0
 
luoysAuthor Commented:
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().
0
 
NovaDenizenCommented:
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".
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
sunnycoderCommented:
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.
0
 
ahoffmannCommented:
as sunnycoder said: tmpfile() is the solution, see
  man tmpfile
  man tmpnam
0
 
karanaCommented:


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


0
 
sunnycoderCommented:
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?
0
 
ahoffmannCommented:
> there is a better way ,
why should this suggestion be better than that what libc already provides: tmpfile?
0
 
NovaDenizenCommented:
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.
0
 
ahoffmannCommented:
>  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
0
 
NovaDenizenCommented:
> 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?
0
 
ahoffmannCommented:
> 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:-)
0
 
NovaDenizenCommented:
>2. if you mean "visability", simply do a: ls -la /var/tmp

First, nowhere in man tmpfile does it say there is any guarantee that the file will be created in /var/tmp.
Second, when you use tmpfile, the file is only present in any directory for an instant.  tmpfile() generates a unique filename, creates the file, then immediately unlinks the file.

Here is the implementation of tmpfile from glibc-2.3.3/sysdeps/generic/tmpfile.c:
FILE *
tmpfile (void)
{
  char buf[FILENAME_MAX];
  int fd;
  FILE *f;

  if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
    return NULL;
  fd = __gen_tempname (buf, GEN_THIS);
  if (fd < 0)
    return NULL;

  /* Note that this relies on the Unix semantics that
     a file is not really removed until it is closed.  */
  (void) __unlink (buf);

  if ((f = __fdopen (fd, "w+b")) == NULL)
    __close (fd);

  return f;
}
0
 
ahoffmannCommented:
agreed for 2., seems that my libc knowledge is a bit rusty ...
0
 
TimEliseoCommented:
I think what you're trying to do is much more easily and reliably achieved using System V semaphores. The kernel will properly keep a count and decrement it upon exit. It is completely reliable even in the face of program and system crashes. You could even set a max count, n, and guarantee that process n+1 will fail (or do something different). The man pages for semget(), semop(), semctl(), and ftok() provide all the details.

I could write you some sample code if you're interested. This question is kind of stale, so I don't want to bother if you've already found another solution.

Tim
0
 
jmcgOwnerCommented:
Semaphores and file locks would both be potential solutions if you don't need visibility across remote file systems.

It's fairly hard to ensure a file will be _removed_ when the app that created it crashes. If you're willing to spend an extra process, you might fork a process to do the work while the parent merely monitors for child termination and then removes the file. I think this is the approach karana had in mind, but his description left a lot to be desired.

By checking whether you can obtain a shared lock, you can probe whether some other process holds an exclusive lock. This complicates the checking, since you have to do more than merely read the directory, but should have the correct semantics as long as your process doesn't _hang_ with the lock held. The content of the file could be the process ID of the process that created it, by the way; just because you can't lock the file doesn't mean you couldn't read it.

I've never found an application where the Sys V semaphores were useful.

In a networked environment, locking files on remote filesystems is problematic. You'd then need something more along the lines of a Distributed Lock Manager, which is an essential component of most clustering systems, but not something I could easily tell you how to apply for your purpose.
0
 
TimEliseoCommented:
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.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 5
  • 5
  • 2
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now