remote_refs prompt
get_tz_offset
credential credential_read credential_write
- temp_acquire temp_release temp_reset temp_path);
+ temp_acquire temp_is_locked temp_release temp_reset temp_path);
=head1 DESCRIPTION
};
if ($dir) {
- $dir =~ m#^/# or $dir = $opts{Directory} . '/' . $dir;
+ _verify_require();
+ File::Spec->file_name_is_absolute($dir) or $dir = $opts{Directory} . '/' . $dir;
$opts{Repository} = abs_path($dir);
# If --git-dir went ok, this shouldn't die either.
Execute the given C<COMMAND> in the same way as command_output_pipe()
does but return both an input pipe filehandle and an output pipe filehandle.
-The function will return return C<($pid, $pipe_in, $pipe_out, $ctx)>.
+The function will return C<($pid, $pipe_in, $pipe_out, $ctx)>.
See C<command_close_bidi_pipe()> for details.
=cut
is simple decimal number. An optional value suffix of 'k', 'm',
or 'g' in the config file will cause the value to be multiplied
by 1024, 1048576 (1024^2), or 1073741824 (1024^3) prior to output.
-It would return C<undef> if configuration variable is not defined,
+It would return C<undef> if configuration variable is not defined.
=cut
}
# Common subroutine to implement bulk of what the config* family of methods
-# do. This curently wraps command('config') so it is not so fast.
+# do. This currently wraps command('config') so it is not so fast.
sub _config_common {
my ($opts) = shift @_;
my ($self, $var) = _maybe_self(@_);
return "$ident[0] <$ident[1]>";
}
+=item parse_mailboxes
+
+Return an array of mailboxes extracted from a string.
+
+=cut
+
+sub parse_mailboxes {
+ my $re_comment = qr/\((?:[^)]*)\)/;
+ my $re_quote = qr/"(?:[^\"\\]|\\.)*"/;
+ my $re_word = qr/(?:[^]["\s()<>:;@\\,.]|\\.)+/;
+
+ # divide the string in tokens of the above form
+ my $re_token = qr/(?:$re_quote|$re_word|$re_comment|\S)/;
+ my @tokens = map { $_ =~ /\s*($re_token)\s*/g } @_;
+
+ # add a delimiter to simplify treatment for the last mailbox
+ push @tokens, ",";
+
+ my (@addr_list, @phrase, @address, @comment, @buffer) = ();
+ foreach my $token (@tokens) {
+ if ($token =~ /^[,;]$/) {
+ # if buffer still contains undeterminated strings
+ # append it at the end of @address or @phrase
+ if (@address) {
+ push @address, @buffer;
+ } else {
+ push @phrase, @buffer;
+ }
+
+ my $str_phrase = join ' ', @phrase;
+ my $str_address = join '', @address;
+ my $str_comment = join ' ', @comment;
+
+ # quote are necessary if phrase contains
+ # special characters
+ if ($str_phrase =~ /[][()<>:;@\\,.\000-\037\177]/) {
+ $str_phrase =~ s/(^|[^\\])"/$1/g;
+ $str_phrase = qq["$str_phrase"];
+ }
+
+ # add "<>" around the address if necessary
+ if ($str_address ne "" && $str_phrase ne "") {
+ $str_address = qq[<$str_address>];
+ }
+
+ my $str_mailbox = "$str_phrase $str_address $str_comment";
+ $str_mailbox =~ s/^\s*|\s*$//g;
+ push @addr_list, $str_mailbox if ($str_mailbox);
+
+ @phrase = @address = @comment = @buffer = ();
+ } elsif ($token =~ /^\(/) {
+ push @comment, $token;
+ } elsif ($token eq "<") {
+ push @phrase, (splice @address), (splice @buffer);
+ } elsif ($token eq ">") {
+ push @address, (splice @buffer);
+ } elsif ($token eq "@") {
+ push @address, (splice @buffer), "@";
+ } elsif ($token eq ".") {
+ push @address, (splice @buffer), ".";
+ } else {
+ push @buffer, $token;
+ }
+ }
+
+ return @addr_list;
+}
=item hash_object ( TYPE, FILENAME )
=item temp_acquire ( NAME )
-Attempts to retreive the temporary file mapped to the string C<NAME>. If an
+Attempts to retrieve the temporary file mapped to the string C<NAME>. If an
associated temp file has not been created this session or was closed, it is
created, cached, and set for autoflush and binmode.
$temp_fd;
}
+=item temp_is_locked ( NAME )
+
+Returns true if the internal lock created by a previous C<temp_acquire()>
+call with C<NAME> is still in effect.
+
+When temp_acquire is called on a C<NAME>, it internally locks the temporary
+file mapped to C<NAME>. That lock will not be released until C<temp_release()>
+is called with either the original C<NAME> or the L<File::Handle> that was
+returned from the original call to temp_acquire.
+
+Subsequent attempts to call C<temp_acquire()> with the same C<NAME> will fail
+unless there has been an intervening C<temp_release()> call for that C<NAME>
+(or its corresponding L<File::Handle> that was returned by the original
+C<temp_acquire()> call).
+
+If true is returned by C<temp_is_locked()> for a C<NAME>, an attempt to
+C<temp_acquire()> the same C<NAME> will cause an error unless
+C<temp_release> is first called on that C<NAME> (or its corresponding
+L<File::Handle> that was returned by the original C<temp_acquire()> call).
+
+=cut
+
+sub temp_is_locked {
+ my ($self, $name) = _maybe_self(@_);
+ my $temp_fd = \$TEMP_FILEMAP{$name};
+
+ defined $$temp_fd && $$temp_fd->opened && $TEMP_FILES{$$temp_fd}{locked};
+}
+
=item temp_release ( NAME )
=item temp_release ( FILEHANDLE )
$tmpdir = $self->repo_path();
}
- ($$temp_fd, $fname) = File::Temp->tempfile(
- 'Git_XXXXXX', UNLINK => 1, DIR => $tmpdir,
+ my $n = $name;
+ $n =~ s/\W/_/g; # no strange chars
+
+ ($$temp_fd, $fname) = File::Temp::tempfile(
+ "Git_${n}_XXXXXX", UNLINK => 1, DIR => $tmpdir,
) or throw Error::Simple("couldn't open new temp file");
$$temp_fd->autoflush;
if (not defined $pid) {
throw Error::Simple("open failed: $!");
} elsif ($pid == 0) {
- if (defined $opts{STDERR}) {
- close STDERR;
- }
if ($opts{STDERR}) {
open (STDERR, '>&', $opts{STDERR})
or die "dup failed: $!";
+ } elsif (defined $opts{STDERR}) {
+ open (STDERR, '>', '/dev/null')
+ or die "opening /dev/null failed: $!";
}
_cmd_exec($self, $cmd, @args);
}