Skip Menu |

This queue is for tickets about the MP3-Tag CPAN distribution.

Report information
The Basics
Id: 87914
Status: open
Priority: 0/
Queue: MP3-Tag

People
Owner: Nobody in particular
Requestors: caleb [...] infinityosd.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Fix for cross-platform bug
Date: Sat, 17 Aug 2013 08:17:46 -0600
To: <bug-MP3-Tag [...] rt.cpan.org>
From: "Caleb Jardine" <caleb [...] infinityosd.com>
MP3: Tag will sometimes throw an error. I found the same problem here: https://rt.cpan.org/Public/Bug/Display.html?id=37950 The problem seems to be in the system call to ‘mv’ which is not available on all systems. I was able to fix the issue by adding File::Copy to the ID3v2.pm file and using it as first move attempt. I am not a great programmer but I wanted to pass my findings along. I hope this helps. Cheers, Caleb Jardine ID3v2.pm changes: added to top of script: use File::Copy; line 674: unless (( rename $tempfile, $mp3obj->{filename})|| (system("mv",$tempfile,$mp3obj->{filename})==0)) { changed to: unless (( move $tempfile, $mp3obj->{filename}) || ( rename $tempfile, $mp3obj->{filename})|| (system("mv",$tempfile,$mp3obj->{filename})==0)) { line 917: unless (( rename $tempfile, $mp3obj->{filename})|| (system("mv",$tempfile,$mp3obj->{filename})==0)) { changed to: unless (( move $tempfile, $mp3obj->{filename}) || ( rename $tempfile, $mp3obj->{filename})|| (system("mv",$tempfile,$mp3obj->{filename})==0)) {
Subject: Re: [rt.cpan.org #87914] AutoReply: Fix for cross-platform bug
Date: Wed, 21 Aug 2013 06:33:11 -0600
To: <bug-MP3-Tag [...] rt.cpan.org>
From: "Caleb Jardine" <caleb [...] infinityosd.com>
This addition to thread is for search engine results. The fix is for errors that appear so: 'mv' is not recognized as an internal or external command, operable program or batch file. Couldn't rename temporary file C:/dir/TMPxx0.tmp to C:/dir/filename.mp3
Please find attached a patch that solves this problem, too. I actually removed the system('mv'...) entirely, since that is generally not portable. Furthermore I changed the temp file generation to use File::Temp. The resulting new code works now fine on Windows with Strawberry Perl. I think the original proposal is correct in using File::Copy::move _before_ rename, so that there are less dummy warnings printed. When updating, please mind adding File::Temp and File::Copy to the prerequisites of this distro. Many thanks and happy new year, Marek
Subject: ID3v2.pm.diff
--- C:\Strawberry\perl\site\lib\MP3\Tag\ID3v2.pm Sat Jan 2 18:12:40 2010 +++ lib\MP3\Tag\ID3v2.pm Thu Dec 3 23:34:48 2015 @@ -9,6 +9,8 @@ use strict; use File::Basename; # use Compress::Zlib; +use File::Temp qw(); +use File::Copy qw(move); use vars qw /%format %long_names %res_inp @supported_majors %v2names_to_v3 $VERSION @ISA %field_map %field_map_back %is_small_int @@ -627,21 +629,15 @@ my ($self, $insert) = @_; my $mp3obj = $self->{mp3}; # !! use a specific tmp-dir here - my $tempfile = dirname($mp3obj->{filename}) . "/TMPxx"; + my $tmpfh = File::Temp->new(TMPDIR => 1); + unless($tmpfh) { + warn "Problems with tempfile: $!\n"; + return -1; + } + my $tempfile = $tmpfh->filename; my $count = 0; - while (-e $tempfile . $count . ".tmp") { - if ($count++ > 999) { - warn "Problems with tempfile\n"; - return undef; - } - } - $tempfile .= $count . ".tmp"; - unless (open (NEW, ">$tempfile")) { - warn "Can't open '$tempfile' to insert tag\n"; - return -1; - } my ($buf, $pos_old); - binmode NEW; + binmode $tmpfh; $pos_old=0; $mp3obj->seek(0,0); local $\ = ''; @@ -650,12 +646,12 @@ if ($pos_old < $ins->[0]) { $pos_old += $ins->[0]; while ($mp3obj->read(\$buf,$ins->[0]<16384?$ins->[0]:16384)) { - print NEW $buf; + print $tmpfh $buf; $ins->[0] = $ins->[0]<16384?0:$ins->[0]-16384; } } for (my $i = 0; $i<$ins->[2]; $i++) { - print NEW chr(0); + print $tmpfh chr(0); } if ($ins->[1]) { $pos_old += $ins->[1]; @@ -664,18 +660,23 @@ } while ($mp3obj->read(\$buf,16384)) { - print NEW $buf; + print $tmpfh $buf; } - close NEW; + close $tmpfh; $mp3obj->close; # rename tmp-file to orig file - unless (( rename $tempfile, $mp3obj->{filename})|| - (system("mv",$tempfile,$mp3obj->{filename})==0)) { - unlink($tempfile); - warn "Couldn't rename temporary file $tempfile to $mp3obj->{filename}\n"; - return -1; - } + my $fname = $mp3obj->{filename}; + unless(unlink $fname) { + warn "Cannot unlink $fname: $!\n"; + } + if(!rename($tempfile, $fname)) { + warn "Cannot rename $tempfile to $fname: $!\n"; + if(!move($tempfile, $fname)) { + warn "Cannot move $tempfile to $fname: $!\n"; + return -1; + } + } return 0; } @@ -772,7 +773,6 @@ sub as_bin ($;$$$) { my ($self, $ignore_error, $update_file, $raw_ok) = @_; - return $self->{raw_data} if $raw_ok and $self->{raw_data} and not $self->{modified} and not $update_file; @@ -848,7 +848,6 @@ my ($self,$ignore_error) = @_; $self->fix_frames_encoding() if $self->get_config1('id3v2_fix_encoding_on_write'); - $self->get_frame_ids; # Ensure all the reading is done... # Need to do early, otherwise file size for calculation of "best" padding # may not take into account the added ID3v1 tag @@ -893,33 +892,33 @@ sub remove_tag { my $self = shift; - my $mp3obj = $self->{mp3}; - my $tempfile = dirname($mp3obj->{filename}) . "/TMPxx"; + my $mp3obj = $self->{mp3}; + + my $tmpfh = File::Temp->new(TMPDIR => 1); + unless($tmpfh) { + warn "Problems with tempfile: $!\n"; + return undef; + } + my $tempfile = $tmpfh->filename; my $count = 0; local $\ = ''; - while (-e $tempfile . $count . ".tmp") { - if ($count++ > 999) { - warn "Problems with tempfile\n"; - return undef; - } + my $buf; + binmode $tmpfh; + $mp3obj->seek($self->{tagsize}+10,0); + while ($mp3obj->read(\$buf,16384)) { + print $tmpfh $buf; } - $tempfile .= $count . ".tmp"; - if (open (NEW, ">$tempfile")) { - my $buf; - binmode NEW; - $mp3obj->seek($self->{tagsize}+10,0); - while ($mp3obj->read(\$buf,16384)) { - print NEW $buf; - } - close NEW; - $mp3obj->close; - unless (( rename $tempfile, $mp3obj->{filename})|| - (system("mv",$tempfile,$mp3obj->{filename})==0)) { - warn "Couldn't rename temporary file $tempfile\n"; - } - } else { - warn "Couldn't write temp file\n"; - return undef; + close $tmpfh || die $!; + $mp3obj->close; + my $fname = $mp3obj->{filename}; + unless(unlink $fname) { + warn "Cannot unlink $fname: $!\n"; + } + if(!rename($tempfile, $fname)) { + warn "Cannot rename $tempfile to $fname: $!\n"; + if(!move($tempfile, $fname)) { + warn "Cannot move $tempfile to $fname: $!\n"; + } } return 1; }
On 2016-01-02 08:29:53, MAREKR wrote: Show quoted text
> I think the original proposal is correct in using > File::Copy::move _before_ rename, so that there are less dummy > warnings printed.
Probably the rename() does not have to be done at all, as File::Copy::move() internally already uses rename().