Re: How do I tell if a handle is open for writing?
by Zaxo (Archbishop) on Nov 07, 2005 at 16:31 UTC
|
stat or, more conveniently, the -w file test operator. Both work fine on open handles, though we're mostly used to feeding them file names.
Update: Oops, got the wrong end of the stick. Here's how to check the open flags to see if the handle is currently writable:
use Fcntl;
sub writable {
my $fh = shift;
(O_WRONLY | O_RDWR) & fcntl( $fh, F_GETFL, my $slush);
}
for (qw/ > < >> +< +> /) {
open my $fh, $_, 'foo' or warn $! and next;
print
"$_\t",
writable($fh)? 'writable.': 'not writable.',
$/;
}
__END__
> writable.
< not writable.
>> writable.
+< writable.
+> writable.
| [reply] [Watch: Dir/Any] [d/l] |
|
Correct me if I'm wrong here, but doesn't -w myfilehandle tell you whether the file that myfilehandle is pointing to has its writable bits set? That's not what I want to know. I want to know if the filehandle is open for writing. You could open a writable file for reading. Then you couldn't write to it with that handle even though passing that handle to -w would still return true. Or have I been smoking the curtains again?
--DrWhy
"If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
|
$ touch x; perl -le 'open X,"x"; print -w X; print X "x" or die $!'
1
Bad file descriptor at -e line 1.
-sauoq
"My two cents aren't worth a dime.";
| [reply] [Watch: Dir/Any] [d/l] |
|
I'm trying to extend this to a comparable readable() function.
sub readable {
my $fh = shift;
(O_RDONLY | O_RDWR) & fcntl( $fh, F_GETFL, my $slush);
}
for (qw/ > < >> +< +> /) {
open my $fh, $_, 'foo' or warn $! and next;
print
"$_\t",
readable($fh)? 'readable.': 'not readable.',
$/;
}
__END__
> not readable.
< not readable.
>> not readable.
+< readable.
+> readable.
Huh??!
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] [Watch: Dir/Any] [d/l] |
Re: How do I tell if a handle is open for writing?
by sgifford (Prior) on Nov 07, 2005 at 17:00 UTC
|
Try writing nothing at all to the file, and see if it fails:
sub is_writable_fh
{
my($fh)=@_;
local $\='';
return print $fh '';
}
open(F1,"< $0")
or die "Couldn't open '$0' for read: $!\n";
print "F1 is".(is_writable_fh(\*F1)?"":"n't")." writable.\n";
open(F2,">> $0")
or die "Couldn't open '$0' for append: $!\n";
print "F2 is".(is_writable_fh(\*F2)?"":"n't")." writable.\n";
Zaxo's solution will tell you whether you have write permissions to the file, but not whether you have write permissions to the filehandle.
| [reply] [Watch: Dir/Any] [d/l] |
|
Excellent! I had thought about just trying to write something to the file but didn't want to modify the file. It didn't occur to me to write *nothing* to the file :)
I was worried that even this solution might have unintended side effects, e.g., changing the modified time on the file or (less likely in my mind) writing a null character to the file. I tried it on my WinXP system and it doesn't appear to modify the file in any way -- modified date remains unchanged.
Thanks!
--DrWhy
"If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."
| [reply] [Watch: Dir/Any] |
|
It should write an EOF at the position (on Win that is, or was it FAT-filesystem only?) and everything after it would be lost. Of course perl could intervene and take it to mean a check for writability, and then use other means to check and get you the result. But I would first seek to EOF.
| [reply] [Watch: Dir/Any] |
Re: How do I tell if a handle is open for writing?
by jZed (Prior) on Nov 07, 2005 at 16:40 UTC
|
Well I may be a member of the idiots' club along with you, and this certainly isn't pretty, but is there a reason this wouldn't work?:
eval {
my $pos = $fh->tell;
$fh->print('1');
$fh->seek($pos);
};
my $ready_for_writing = ($@) ? 0 : 1;
update please ignore this and listen to Zaxo :-) | [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] |
|
If this was worth salvaging, I could add in a seek() before the original tell to avoid that problem. But since it's crap anyway, I won't bother :-).
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
I did that once. I wouldn't recommend it to anyone -- it tends to make your mother a little crazy...
--DrWhy
"If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."
| [reply] [Watch: Dir/Any] |