Re: Why doesn't chmod work on this lexical filehandle?
by JavaFan (Canon) on Feb 14, 2011 at 20:55 UTC
|
1) your system must support fchmod for it to work. 2) you should be using globs or glob references. 3) I don't think it works with closed file handles. 4) Did you check the return value of chmod, and $! if it's false? | [reply] [Watch: Dir/Any] [d/l] [select] |
|
Thanks for great suggestions. Moved close after chmod but it did not help.
Working on Linux box, uname -a says:
Linux ... 2.6.9-89.0.16.ELxenU #1 SMP Tue Oct 27 04:12:25 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
chmod returns 0 and $! returns "No such file or directory" even after moving close after chmod.
will investigate globs, glob refs. I think those are used in main, but a scalar ref was used with this sub.
| [reply] [Watch: Dir/Any] |
|
Then it sounds like $OUT is being interpreted as a string and that that string is being interpreted as a file name: If chmod had thought that you had passed a file handle to it on a system where Perl doesn't think fchmod() is supported, then it would have died rather than returning 0. If you passed a file handle to chmod() on a system with fchmod, "No such file or directory" could not have been the failure reason.
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Re: Why doesn't chmod work on this lexical filehandle?
by ELISHEVA (Prior) on Feb 14, 2011 at 23:01 UTC
|
chmod 0444 on a file handle open for writing works for me. I'm running Linux Debian 2.6.22 (lenny) and Perl 5.10. However, I seem to recall that when I was running code on Debian Etch + 5.8.8 chmod on a file open for writing would fail. That older version of Perl (or of the operating system) didn't let you mark a file as read only when it was open for writing.
As mentioned earlier, chmod on a file handle in Perl only works if your system supports chmod on file handles in general (i.e. it supports fchmod). I'm guessing your system does not support it or else you are using an older perl/os combination. Can you set any permissions on a file handle? Or is the problem limited to making files open for writing read only?
In any case, your best bet is to simply call chmod on the file name rather than the file handle. I can see from your code that you have access to both so this shouldn't be a problem. Your only risk is a small chance that someone could intercept the file and modify it between the time that you close the handle and the time that you set the permissions.
Also, as a side note, I notice you are using the two parameter open. Don't. Use the three parameter open instead. With the two parameter open there is a small chance that Perl with confuse the file name and the open instructions. With the three parameter open, this risk goes away. You may not be able to avoid the security/timing risk, but the risk of a misinterpreted is something you can eliminate entirely.
Update: - struck out words -my recollection was faulty - looking back on my testing notes from a ways back it wasn't chmod on a file handle that failed in Etch+5.8.8 but rather 0444 passed to sysopen - system open would turn 0444 into 0644. I just brought up the Debian Etch system and chmod 0444 on a file handle does work on Etch+5.8.8. Thank-you anonymous monk below for making me double check this.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
...only works if your system supports chmod on file handles in general (i.e. it supports fchmod).
While this is technically correct, it's almost certainly irrelevant, as the OP is using Linux, and fchmod was introduced with kernel 0.96a almost two decades ago (when the entire kernel source tarball was just 200k).
Rather, the problem is with older versions of Perl. For example, when I strace a test script running under 5.8.4, I'm getting
chmod("*main::OUT", 0444) = -1 ENOENT (No such file or d
+irectory)
for "chmod 0444, *OUT", and something like
chmod("GLOB(0x602210)", 0444) = -1 ENOENT (No such file or d
+irectory)
for "chmod 0444, $OUT", while newer versions of Perl in both cases correctly do
fchmod(4, 0444) = 0
In other words, older versions simply passed the stringified handle to the chmod system call...
The OP's case definitely works with 5.8.8 (and newer), though. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
Re: Why doesn't chmod work on this lexical filehandle?
by Anonyrnous Monk (Hermit) on Feb 14, 2011 at 20:59 UTC
|
You're calling chmod on a closed file handle. This doesn't work (it doesn't work with non-lexical file handles either). Put the close after the chmod.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
thank you, and as promising as it seemed, it did not alter the chmod response.
| [reply] [Watch: Dir/Any] |
Re: Why doesn't chmod work on this lexical filehandle?
by pavunkumar (Scribe) on Feb 15, 2011 at 07:23 UTC
|
You can try this......
open ($OUT,">$$outScalarRef")
or open ($OUT,">$$outScalarRef-$date")
or die "Cannot open file $$outScalarRef : $!\n";
print $OUT @stuff;
# chmod 0444, $OUT;
my ($inode) = ((stat($OUT))[1]);
my ($filename) = ` find . -inum $inode ` ;
chomp $filename ;
chmod 0444, $filename ;
close $OUT;
| [reply] [Watch: Dir/Any] [d/l] |