Prev: Problems with "show tech" using the Net::Telnet Module
Next: getting full URL from relative links
From: Ben Morrow on 20 Apr 2010 18:52 Quoth Vilmos Soti <vilmos(a)soti.ca>: > PerlFAQ Server <brian(a)theperlreview.com> writes: > > > 5.35: How do I close a file descriptor by number? > > > > If, for some reason, you have a file descriptor instead of a filehandle > > (perhaps you used "POSIX::open"), you can use the "close()" function > > from the "POSIX" module: > > I have a related question: > > How do I find all the open file descriptors so I can close them? There is no way to do this in general, short of calling _exit(2) (or something else that calls _exit, like Perl's exit). One crude way is something like POSIX::close $_ for 3..1024; for some suitably large value of '1024'; most systems have some sort of limit on the maximum possible fd, so check your system documentation. Ben
From: C.DeRykus on 22 Apr 2010 01:05 On Apr 21, 11:09 am, Vilmos Soti <vil...(a)soti.ca> wrote: > "Peter J. Holzer" <hjp-usen...(a)hjp.at> writes: > > > But it looks like you care about Perl handles anyway, not about file > > descriptors. > > Well, yes. > > > and then wrap the copy operations into an eval block: > > I guess the solution in this case is to use eval, and there no > sane way to have a list of file descriptors. Another possibility, although not particularly efficient, is just redefine the handler to not interrupt the copy and run bye() in an END{}: #!/usr/bin/perl my $INT = 0; ... my $find_code = sub { local $SIG{INT} = sub { $INT = 1; }; copy ...; exit if $INT }; ... END { bye; } -- Charles DeRykus
From: Peter J. Holzer on 21 Apr 2010 04:09 On 2010-04-20 20:41, Vilmos Soti <vilmos(a)soti.ca> wrote: > J�rgen Exner <jurgenex(a)hotmail.com> writes: > >>> How do I find all the open file descriptors so I can close them? >>> >>> I have a program which basically does this (runs on Unix): [...] >>> The problem is that if the user hits Ctrl-C in the middle of the copy, >>> the open file descriptors on /mnt/cdrom will prevent umounting and >>> ejecting. >> >> AFAIR file descriptors are closed automatically when they go out of >> scope. File descriptors are handled by the OS. They don't go out of scope until the process exits (or execs, if they are marked "close on exec"). But it looks like you care about Perl handles anyway, not about file descriptors. >> So scope them correctly and you shouldn't have any problems. > > How do I do this? > > Here is an actual (and running) perl program which demonstrates this problem: > > ---------------------- code starts --------------------- > #!/usr/bin/perl > > use File::Copy; > use File::Find; > > my $find_code = sub { > copy ($File::Find::name, "/dev/null") if -f $File::Find::name; > }; > > sub bye () { > system ("/bin/umount /mnt/cdrom"); > system ("/usr/bin/eject /mnt/cdrom"); > exit; > } > > $SIG{INT} = \&bye; Here is the problem. You are calling bye() as a signal handler, so it is called while the process is still busy copying files. Instead you could just die in the signal handler: $SIG{INT} = sub { die "interrupted" } and then wrap the copy operations into an eval block: > system ("/usr/bin/eject -t /mnt/cdrom"); # close the cd tray > system ("/bin/mount /mnt/cdrom"); > print "copy starts\n"; > find ( { wanted => $find_code, follow => 0, no_chdir => 1 }, "/mnt/cdrom"); > print "copy ends\n"; eval { print "copy starts\n"; find ( { wanted => $find_code, follow => 0, no_chdir => 1 }, "/mnt/cdrom"); print "copy ends\n"; }; if ($@) { print "caught exception: $@\n"; } > bye; Then, when you press Ctrl-C, perl will cleanly abort whatever it is doing (freeing any container[1] which goes out of scope) and jump to the end of eval block. Finally, bye is called, just as if the block had been processed normally. The problem with this approach is that it will only close lexical file handles. Bareword filehandles never go out of scope, so they won't be closed. And I haven't checked now, but I'm almost sure that File::Copy uses bareword filehandles, simply because it is older than lexical filehandles. > Basically I would like something like this in the bye function: > > foreach (@OPEN_FILE_DESCRIPTORS) { > next if stdin or stdout or stderr; > close $_; > } > > The question is ... how can I get a list of open file descriptors. I don't think you can get them. You could uswe the same approach as in C: Simply calling POSIX::close on all filedescriptors between 3 and some maximum. hp
From: Ben Morrow on 21 Apr 2010 11:42 Quoth "Peter J. Holzer" <hjp-usenet2(a)hjp.at>: > > The problem with this approach is that it will only close lexical file > handles. Bareword filehandles never go out of scope, so they won't be > closed. And I haven't checked now, but I'm almost sure that File::Copy > uses bareword filehandles, simply because it is older than lexical > filehandles. File::Copy (at least, v2.14, which comes with 5.10.1) uses my $fh = \do { local *FH }; which is how you created a scoped filehandle before 5.6. At least in modern perls, these handles will also auto-close on scope exit. Ben
From: Vilmos Soti on 21 Apr 2010 14:09 "Peter J. Holzer" <hjp-usenet2(a)hjp.at> writes: > But it looks like you care about Perl handles anyway, not about file > descriptors. Well, yes. > and then wrap the copy operations into an eval block: I guess the solution in this case is to use eval, and there no sane way to have a list of file descriptors. Thanks for everybody, Vilmos
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Problems with "show tech" using the Net::Telnet Module Next: getting full URL from relative links |