On Sat, Jun 11, 2011 at 3:47 PM, Benny Lofgren <[email protected]> wrote:
> On 2011-06-11 10.08, T wrote:
>> I'm writing a small program which changes working dir to a
>> specific directory (using chdir()), and then opens, reads, and
>> closes files in that directory, depending on user actions.
>> Sometimes this directory is located on a mounted USB stick.
>>
>> I'm looking for a simple way to detect, from within my program,
>> if a user have removed the USB stick without first unmounting it.
>>
>> The simplest way, I thought, was to check errno for EIO or ENXIO
>> (depending on whether an error occurs in fread() or fopen()).
>> However, that does not seem to work, because if I call fopen()
>> after the USB stick has been removed, the return value is NULL,
>> and the errno code is ENOENT instead of ENXIO, which sort of
>> makes sense (the file certainly is not there any more), but the
>> cause of the error cannot be differentiated from a regular
>> mis-spelling of the file name.
>>
>> So is there some reliable way of detecting whether the underlying
>> storage device has gone away when a library/system call fails,
>> even if the OS still regards the filesystem as being mounted? Can
>> I, upon detecting errno==ENOENT after fopen(), use some other
>> calls (for example ioctl(), getfsstat(), or statfs()) to
>> determine whether the cause is a mis-spelled filename or removed
>> USB stick? What is the recommended/preferred way? Can/should I
>> perhaps do something before attempting the fopen(), to find out
>> whether the USB stick is still attached?
>>
>> I prefer simple solutions using standard library/system calls,
>> and would like to avoid attaching to some notification mechanism,
>> and tailing the kernel log looking for USB detach messages is a
>> clumsy last chance solution.
>
> Try to do an open(".", O_RDONLY) if your fopen()/fread() fails.
>
> If you get -1 and ENOENT then the file system where you've parked
> your cwd is no longer mounted (statfs() should also work equally
> well, but then you'd need to declare a statfs struct you'd have
> no further use for).
>
> It's not wise to check before your fopen():s, because they may
> still fail if the user pulls the USB stick in the right moment,
> only use it as a verification of *what* actually went wrong.

Thanks for the replies, on- and off-list. I ended up going with
Benny's open(".", O_RDONLY); suggestion, which felt cleanest,
easiest, and had the highest probability of being portable,
should the need arise. Works like a charm.

Dave

Reply via email to