Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Re: File::Copy dying on Win2k when target file already there

by scain (Curate)
on Jan 16, 2003 at 21:24 UTC ( #227507=note: print w/replies, xml ) Need Help??


in reply to Re: File::Copy dying on Win2k when target file already there
in thread File::Copy dying on Win2k when target file already there

Very sorry about the confusion. I had a little bit of a versioning problem. I modified the error message line after I pasted in the code for the script to get a more informative error message, and forgot to fix the code. The modified line looks like this:
copy($localfile, $installfile) or die "$localfile unable to copy to $installfile : $!\n";

That said, demerphq helped me track down the problem. The problematic files where read-only, and apparently File::Copy won't let you copy over read-only files (even if you are the Administrator). I modified the code to add lines like this:

fixreadonly($plugindir) if $^O =~ /win32/i; sub fixreadonly { my $dir = shift; my $unsetreadonly = Bio::Root::IO->catfile( $dir, "*.*"); system("attrib -r /s $unsetreadonly"); }

Scott
Project coordinator of the Generic Model Organism Database Project

Replies are listed 'Best First'.
Re: Re: Re: File::Copy dying on Win2k when target file already there
by John M. Dlugosz (Monsignor) on Jan 17, 2003 at 02:30 UTC
    You can change the attribute using chmod, built into Perl, instead of calling out to system. I tried it using the UNIX bits meanings, and it did indeed turn off the R flag on Windows NT.

    That works the same on both platforms, so you don't even have to make it conditional.

      John,

      I did as you suggested and it works well. The readdir/while loop in the code above now looks like this:

      opendir PLUGINS, "conf/plugins" or die "unable to opendir ./conf/plugi +ns\n"; while (my $pluginfile = readdir(PLUGINS) ) { my $localfile = Bio::Root::IO->catfile('conf/plugins',$pluginfile) +; if (-f $localfile) { my $installfile = Bio::Root::IO->catfile($plugindir, $pluginfi +le); chmod (0666, $installfile); copy($localfile, $installfile) or die "$localfile unable to copy to $installfile : $!\n"; chmod (0444, $installfile); } } closedir PLUGINS;
      The only caveat being that I had to chmod the files to 444 (readonly by everyone, including the owner (root in this case)). It is fine for Windows, but an annoyance on unix. I would have preferred 644 (writeable by the owner), but on Windows, that is the same as world writeable (from Perl's chmod perspective).

      (I hate having to type :w and then :w! when I am reminded once again that the file is readonly.)

      Thanks,

      Scott
      Project coordinator of the Generic Model Organism Database Project

        I guess the chmod on Windows is using the "word" write bit as the single read-only flag.

        You could conditionally note the value to use, once:

        use constant ROFLAG => $^O eq 'MSWin32' ? 0444 : 0644;
        and then use that constant in your code.

        I don't know what you mean about typing :w.

        —John

        First of all, in reply to John M. Dlugosz, please don't use eq: use constant ROFLAG => $^O =~ /win32/i ? 0444 : 0644;

        There is too much legacy code that does so already. If everyone used a regex $^O could be changed to contain more details about the exact version of Windows.

        However, this solution strikes me as an ugly hack anyway. How about this?

        chmod +(stat)[2] | 0444, $_ for $installfile;

        Makeshifts last the longest.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://227507]
help
Chatterbox?
[ambrus]: Corion: yes, you need to implement the io watcher, which should be simple because Prima::File is basically that, and the timer watcher form Prima::Timer
[Corion]: ... or so I think. As I said, I'm somewhat vague on how to make AnyEvent cooperate with a callback-driven IO event loop that gives me callbacks when data is available or can be written
[ambrus]: what push_write thing? I don't think you need that. that's implemented generically by AnyEvent::Handle
[Corion]: ambrus: Yeah, that's what I think as well. But you give me an idea, maybe I should start with implementing the timer, as that should be far simpler and with fewer edge-cases/nasty interaction than the file watcher
[ambrus]: You only provide the watcher part that tells when the handle is readable or writable, not the actual writing and reading.
[Corion]: ambrus: Hmmm. It makes sense that AnyEvent would implement the push_write itself, but I think I don't have a good idea of where the boundary between AnyEvent and the underlying event system lies... Implementing the timer should give me a better idea
[ambrus]: Corion: push_write is in the higher level abstraction of AnyEvent::Handle, not in the watcher
[Corion]: ambrus: Hmm - rereading Prima::File, that merrily coincides with what Prima does - it tells you "you can read", and you're supposed to read from the fh yourself. I thought it called you with the data already read, which would've been harder to integrate
[ambrus]: you just need an io watcher, created by &AnyEvent::Impl:: Whatever::io(...)
[Corion]: So after talking it through with you even while I'm still not entirely clear on where AE ends and my implementation begins, I think I understand that I only need to implement some smaller parts for each functionality I want to support.

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (8)
As of 2016-12-08 12:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    On a regular basis, I'm most likely to spy upon:













    Results (141 votes). Check out past polls.