[comp.unix.questions] how do you watch for an incoming file

quan@hplabsb.HP.COM (Suu Quan) (11/29/89)

	How do I write a C-program or shell script that will watch for
the presence of a new file in a certain directory.

Scenario : I expect a file to be sent to me -name possibly unknown- to a
directory (callit /application/inputfile/). Since I do not know when it
will arrive (ftp, rcp ... does not matter), I want to be notified of its
presence as soon as possible but not burn any cpu in the mean time.

I know how to write a shell script will a loop and a sleep a la :
cd /application/inputfile/
while (1)
do
  sleep($some)
  if [ $(/bin/ls) ]    # assume ksh
  then
       echo there is something in here
  else
	;
  fi
done.

	But I would prefer a C-program or a script using a blocking command
	Any help is appreciated
-- 
Suu Quan  (TELNET/415) 857-3594			quan@hpcmfs.corp.HP.COM
HEWLETT-PACKARD, Corp Manuf Factory Systems	quan@hpcmfs
Palo Alto, CA 94304				suu quan /HP0080/04

cpcahil@virtech.uucp (Conor P. Cahill) (11/29/89)

In article <5506@hplabsb.HP.COM>, quan@hplabsb.HP.COM (Suu Quan) writes:
> 	How do I write a C-program or shell script that will watch for
> the presence of a new file in a certain directory.

   [example shell deleted]
> 	But I would prefer a C-program or a script using a blocking command

There is no way to sleep on a file being added to a directory.  If you can't
modify the software that is sending the file (to use some kind of IPC to 
tell your daemon that the file is there), the next best thing you could
do is:

	set dir mtime var to non zero;
	set old mtime var to zero;
	forever loop
	{
		if( dir mtime var != old mtime var)
		{
			/* The dir has been modified, so look for new stuff...*/
			old mtime var = dir mtime var
		}
		else
		{
			sleep(however long is ok);
		}
		stat(dir,to get current dir mtime var)
	}

NOTE-> the code above was just off the top of my head, so there may be a typo,
       bug, mistake, or other such stuff.

This way you are only stating the directory every x seconds (unless there
is a file to process) and this shouldn't use up any measurable CPU as long
as long as the sleep is > 1 second.

-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

les@chinet.chi.il.us (Leslie Mikesell) (11/30/89)

In article <5506@hplabsb.HP.COM> quan@hplabsb.HP.COM (Suu Quan) writes:
>
>	How do I write a C-program or shell script that will watch for
>the presence of a new file in a certain directory.
>
>Scenario : I expect a file to be sent to me -name possibly unknown- to a
>directory (callit /application/inputfile/). Since I do not know when it
>will arrive (ftp, rcp ... does not matter), I want to be notified of its
>presence as soon as possible but not burn any cpu in the mean time.

The cheapest operation would probably be to stat(2) the directory at
some interval, then use opendir(), readdir(), etc. to find the
filename when the st_mtime field changes.
For a shell approach you will have to read the directory but the
(generally) built-in echo command will do it.
#
cd dir
while :
do
FILES=`echo *`
if [ $FILES != "*" ]
then
# put your notify command here...
exit
fi
sleep 30
done

>	But I would prefer a C-program or a script using a blocking command
>	Any help is appreciated

That would require some help from the delivery program - for example writing
to a FIFO when the delivery is complete.  In any case you might need to
guard against processing a partial file (i.e. the name has appeared but
the writer has not completed its output).

Les Mikesell
  les@chinet.chi.il.us

chris@mimsy.umd.edu (Chris Torek) (11/30/89)

In article <1989Nov29.042955.8217@virtech.uucp> cpcahil@virtech.uucp
(Conor P. Cahill) writes:
>	forever loop
		...
>		stat(dir,to get current dir mtime var)

If you open the directory, and use fstat on the resulting descriptor,
you will accumulate less system time.  Unfortunately, it seems that some
Unix systems refuse to let you open a directory these days, so you
would need something like

	fd = open(dir, 0);
	forever loop ...
		result = fd >= 0 ? fstat(fd, &st) : stat(dir, &st);
		if (result < 0)
			er ror er ror ster ril lize

(no points for remembering the source of the `er ror' line :-) )
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

ken@wsl.UUCP (Kenneth Woods on wsl) (12/08/89)

----- News saved at 7 Dec 89 23:20:43 GMT
>In article <5506@hplabsb.HP.COM>, quan@hplabsb.HP.COM (Suu Quan) writes:
>> 	How do I write a C-program or shell script that will watch for
>> the presence of a new file in a certain directory.

If you use the C-shell you could try the following command 

set mail = ( 10 /usr/mail/$LOGNAME certain_directory )

csh will then send you the message
"New mail in certain_directory"
whenever a file is added or removed from that directory.
You can use ls -t or whatever to find the actual name of the file.
Newsgroups: comp.unix.questions,hp.unix
Subject: Re: how do you watch for an incoming file
Summary:
Expires:
References: <5506@hplabsb.HP.COM> <1989Nov29.042955.8217@virtech.uucp>
Sender:
Reply-To: ken@wsl.ie (Kenneth Woods on wsl)
Followup-To:
Distribution: 
Organization: Workhorse Systems, Dublin, Ireland
Keywords: 

>In article <5506@hplabsb.HP.COM>, quan@hplabsb.HP.COM (Suu Quan) writes:
>> 	How do I write a C-program or shell script that will watch for
>> the presence of a new file in a certain directory.

If you use the C-shell you could try the following command 

set mail = ( 10 /usr/mail/$LOGNAME certain_directory )

csh will then send you the message
"New mail in certain_directory"
whenever a file is added or removed from that directory.
You can use ls -t or whatever to find the actual name of the file.