Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / Perl / June 2006



Tip: Looking for answers? Try searching our database.

Waiting until Acrobat closes file

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Tommy Nordgren - 27 May 2006 23:27 GMT
My perl script generates pdf files, and opens them with Acrobat.
How can I wait until Acrobat closes the file, so I can delete it?
------------------------------------------------------
"Home is not where you are born, but where your heart finds peace" -
Tommy Nordgren, "The dying old crone"
tommy.nordgren@chello.se
David Cantrell - 28 May 2006 00:34 GMT
> My perl script generates pdf files, and opens them with Acrobat.
> How can I wait until Acrobat closes the file, so I can delete it?

   system('acroread', 'myfile.pdf');
   unlink('myfile.pdf');

if instead you're doing something like ...

   system('open', '/Applications/Acrobat.app');

then you'll need to:

wait around until Acrobat appears in the process table;
wait around until that PID disappears;

Check out Mac::Processes on the CPAN.

Signature

David Cantrell | random organic glop and a metric fuckton of electricity

   Wow, my first sigquoting! I feel so special now!
       -- Dan Sugalski

Chris Devers - 28 May 2006 01:47 GMT
> if instead you're doing something like ...
>
[quoted text clipped - 4 lines]
> wait around until Acrobat appears in the process table;
> wait around until that PID disappears;

Really??

In my experience, the `open` command immediately returns control to the
controlling process (the shell, or whatever else invoked it (pine etc))
without waiting for the `open`ed application to finish, or for that
matter even to finish launching.

If you're going to use acroread, then [a] you have to install it, and
[b] you have to view the document in X11. Yuck. Surely that isn't really
the best way to approach this, is it? I'd have thought that the `open`
command was the perfect answer to this question...

   system('open', '/Applications/Preview.app');

etc.

Signature

Chris Devers
DO NOT LEAVE IT IS NOT REAL

Joel Rees - 28 May 2006 06:53 GMT
>> if instead you're doing something like ...
>>
[quoted text clipped - 19 lines]
>
>     system('open', '/Applications/Preview.app');

Well, I think the orginal problem was waiting until the viewer closed
the document to delete the file. So, whichever viewer you use (X11
acrobat reader, Mac OS X acrobat reader, preview app, something else)
you're still stuck with the problem of how to avoid deleting a file out
from under the viewer.

Except, of course, this is Unix, and we have i-nodes, and the system
knows how to hold onto a file until all links are gone, as I recall.

Ergo, just delete it once you know the viewer has it open, IIRC.
David Cantrell - 28 May 2006 18:44 GMT
> Except, of course, this is Unix, and we have i-nodes, and the system
> knows how to hold onto a file until all links are gone, as I recall.
>
> Ergo, just delete it once you know the viewer has it open, IIRC.

Which is fine, but if you use 'open' to fork off and run Acrobat in
parallel with your program, then at the moment system() returns you do
*not* know that it has safely grabbed hold of the file.  You don't even
know that it has when you see Acrobat appear in the process table.

Signature

David Cantrell | http://www.cantrell.org.uk/david

Eye have a spelling chequer / It came with my pea sea
It planely marques four my revue / Miss Steaks eye kin knot sea.
Eye strike a quay and type a word / And weight for it to say
Weather eye am wrong oar write / It shows me strait a weigh.

Joel Rees - 28 May 2006 21:26 GMT
>> Except, of course, this is Unix, and we have i-nodes, and the system
>> knows how to hold onto a file until all links are gone, as I recall.
>> Ergo, just delete it once you know the viewer has it open, IIRC.

There is only one way to be sure it is _your_ child process that has
opened it. I'm pretty sure it involves looking at the table of open
files. However, ...

> Which is fine, but if you use 'open' to fork off and run Acrobat in
> parallel with your program, then at the moment system() returns you do
> *not* know that it has safely grabbed hold of the file.  You don't
> even know that it has when you see Acrobat appear in the process > table.

since you do need to take the steps to be sure it is your child process
that has it open, once you have taken those steps, there is no need to
wait around for it to close. IIRC.
Christian Huldt - 28 May 2006 08:15 GMT
28 maj 2006 kl. 02.47 skrev Chris Devers:

>> if instead you're doing something like ...
>>
[quoted text clipped - 13 lines]
> without waiting for the `open`ed application to finish, or for that
> matter even to finish launching.

which is why processes have to be monitored manually...

I'm quite confident that David meant
system('/Applications/Adobe Reader 7.0.7/Adobe Reader 7.0.7.app/
Contents/MacOS/Adobe Reader', 'myfile.pdf');
using acroread as shorthand

This will block as long as the process is running, to just wait while  
the document is open, I'd probably try monitoring
`lsof | grep myfile.pdf`;
after system ('open',...

unless you can arrange for Acrobat to quit, which however would cause  
a lot of time wasted for launching if you will process more than one  
document...

(I assume the the full Acrobat can be controlled using Mac::Glue, but  
this does not seem possible for the Reader)
David Cantrell - 28 May 2006 18:41 GMT
>> if instead you're doing something like ...
>>    system('open', '/Applications/Acrobat.app');
[quoted text clipped - 7 lines]
> without waiting for the `open`ed application to finish, or for that
> matter even to finish launching.

Yes, and that is why I said you need to:

  wait around until Acrobat appears in the process table

because you can't guarantee that it'll be there when 'open' returns
control to your perl program - 'open' will have fork()ed and exited but
won't necessarily have exec()ed by then.  And that you need to then

  wait around until that PID disappears

because, erm, it's running in parallel to your program.  Do try to keep
up old chap :-)

Signature

David Cantrell | Benevolent Dictator Of The World

  When one has bathed in Christ there is no need to bathe a second time
      -- St. Jerome, on why washing is a vile pagan practice

Wren Ng Thornton - 28 May 2006 23:34 GMT
> Really??
>
> In my experience, the `open` command immediately
> returns control to the controlling process (the
shell,
> or whatever else invoked it (pine etc)) without
> waiting for the `open`ed application to finish, or for
> that matter even to finish launching.

Others have gone over briefly why your observations
about `open` returning are correct, but why that's
actually the root of the problem. The problem isn't
that it takes too long to return, it's that it returns
too quickly. The issue in general is race conditions.

Because `open` returns so soon you have no idea when
the other app will open the file let alone close it.
If you delete the file right away it may be missing by
the time the app is up and running; if you delete it
after it's been opened but before it's been closed,
the app may choose to "undelete" it for you by saving
it or whatnot.

The only real way around this problem is to wait for
the app to close and only then delete the file, and
the only way to get that information without race
conditions itself is from the OS itself. You'll want
the new process to be a child process so you can know
definitively that it has completed (and without
constantly polling the process table). system() does
this, though you'll want to launch the app directly
rather than using something like `open` to open it
indirectly.

Since terminated processes can't have open files you
can be sure that once the child finishes, the file is
closed (or at least closed as far as your program is
concerned, other processes out there in the universe
may muck with your plans to delete it, but you have no
control over that).

In short, `open` is an awesome utility that I wish all
*nices had, but it's not the right tool for this job.

Live well,
~wren

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Joseph Alotta - 29 May 2006 06:19 GMT
This may not be what you are looking for, but if you were
to name the files in a way that uses the date, then
you can just delete the old ones the next day.

Joe.

On May 28, 2006, at 5:34 PM, wren ng thornton wrote:

>> Really??
>>
[quoted text clipped - 48 lines]
> Tired of spam?  Yahoo! Mail has the best spam protection around
> http://mail.yahoo.com
Tommy Nordgren - 10 Jun 2006 23:49 GMT
>> My perl script generates pdf files, and opens them with Acrobat.
>> How can I wait until Acrobat closes the file, so I can delete it?
>
>     system('acroread', 'myfile.pdf');
>     unlink('myfile.pdf');

    There is no 'acroread' , at least not with only the reader installed
> if instead you're doing something like ...
>
[quoted text clipped - 4 lines]
> wait around until Acrobat appears in the process table;
> wait around until that PID disappears;

    1. Acrobat may already be running when told to open a document.
    2. I would prefer being able to remove the file as soon as it is  
closed, keeping the reader
running is preferable, since it has long start up time.
   
Will it work to:
a) Wait until Acrobat Reader is running
b) Sleep long enough to make sure acrobat has opened the file
c) Open the file in read/write mode, and wait until a write lock can  
be aquired
d) Then , close and remove the file
> Check out Mac::Processes on the CPAN.

------------------------------------------------------
"Home is not where you are born, but where your heart finds peace" -
Tommy Nordgren, "The dying old crone"
tommy.nordgren@chello.se
Joel Rees - 11 Jun 2006 00:24 GMT
> Will it work to:
> a) Wait until Acrobat Reader is running
> b) Sleep long enough ...

Instead of depending on timing, which will always get messed up when
you can least afford it, get a list of the open files from the system.

man lsof

There should be better ways to get the file handle, but you should at
least be able to look through the list of open files given by lsof for
an instance of your file opened by the process whose id is the acrobat
reader you asked to open it.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.