Link to home
Start Free TrialLog in
Avatar of braveheart
braveheart

asked on

How to handle "Disk Full" errors cleanly

I am writing an application to run on a number of different
flavours of UNIX (Solaris, SunOS, HPUX, DEC Ultrix & OSF/1,
IRIX) which writes to disk. I would like to be able to trap
disk full errors, prompt the user to make more space and
then resume operation as if nothing had happened.

I am envisaging a solution at the fwrite/fclose/fputc level
to work with both buffered and unbuffered I/O, over NFS.
Although far from trivial, it is the mechanics of the disk
writing that I am interested in and not the prompting. Any
solution which also works with NT would be a real bonus.
Avatar of AndrewW
AndrewW

It's been a while since I've done any C programming, but this
might work

meta code. . .

if(!fwrite)
{
      string = strerror(errno);
      if(strcmp(string, "No space left on device"))
      {
            print warning
      }
}

I don't know what the string that perror will return exactly
but under IRIX the err number for ENOSPC is 28.  You can
also check the value of errno.  Pull a manpage on
strerror and errno for more details, that should get you started.


basically errno is set anytime a syscall fails, such as writing
to disk.  you can look in /usr/include/sys/errno.h to see what
kind of errors are set.
Avatar of braveheart

ASKER

The problem is rather more difficult than that. Unfortunately the method usggested by AndrewW is far from foolproof.

For a start it would obviously be easier to test errno itself than to convert it to a string and then compare the string.

Worse still, errno is defined by ANSI to only include EDOM and ERANGE - the rest are POSIX definitions. However, POSIX seems to define ENOSPC as used by link, mkdir, mkfifo, open, rename and write but not fwrite. I have myself observed that under certain circumstances errno is set and under others it is not. The precise behaviour changes from machine to machine.

The only sure way appears to be checking the number of bytes written by the call but that only tells you that there was a failure and not why it failed.

Then there is the problem of writes being buffered up until the close, but it is not possible to recover from a close so we must flush first. Then there are the effects of NFS buffering to take into account...

The code we have developed is already quite complex and, so far, only partially works on HPUX. Ideally I would like someone to either post some tried and tested code or point me to some.
ASKER CERTIFIED SOLUTION
Avatar of wex
wex

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
Come on guys. I am increasing the value to try and get an answer
(if I can work out how).

Perhaps an alternative approach such as checking the amount of
available disk space would be more appropriate. This could be
performed occasionally when there is plenty of space but, as the
disk fills up, could be performed more and more frequently until
a check is performed for every write.

Does anyone have any portable code that can check for available
disk space?