Re: Programmatically detect removed usb stick?

2011-07-10 Thread T
On Sat, Jun 11, 2011 at 3:47 PM, Benny Lofgren bl-li...@lofgren.biz 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



Programmatically detect removed usb stick?

2011-06-11 Thread T
Hello,

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.

Dave



Re: Programmatically detect removed usb stick?

2011-06-11 Thread Benny Lofgren
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.


Regards,
/Benny


-- 
internetlabbet.se / work:   +46 8 551 124 80  / Words must
Benny Lvfgren/  mobile: +46 70 718 11 90 /   be weighed,
/   fax:+46 8 551 124 89/not counted.
   /email:  benny -at- internetlabbet.se



Re: Programmatically detect removed usb stick?

2011-06-11 Thread Martin Schröder
2011/6/11 Benny Lofgren bl-li...@lofgren.biz:
 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

What if the cwd has been removed by another process instead?

Best
   Martin



Re: Programmatically detect removed usb stick?

2011-06-11 Thread Ted Unangst
On Sat, Jun 11, 2011 at 4:08 AM, T jatd...@gmail.com wrote:
 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?

There are no filesystems without storage, they are force unmounted
when the device is removed.  You should look into hotplugd if you want
notification of device removal.