1 package Fedora
::Rebuild
::Package
::StateLock
;
4 use version
0.77; our $VERSION = version
->declare("v0.1.0");
15 isa
=> 'Fedora::Rebuild::Package',
48 if (! defined $self->state || $self->state eq '') {
49 croak
"Invalid `state' attributed passed to StateLock constructor";
55 return $self->package->packagedir . '/.' . $self->state;
60 return $self->lockfile. '.log';
65 my $file = IO
::Handle
->new();
66 open ($file, '>', $self->logfile) or
67 croak
"Could not create `" . $self->logfile . "' logfile: $!";
71 # Print array into log
73 shift->logfd->print(@_);
76 # Return true if state is finshed, otherwise open log file.
80 if (-e
$self->lockfile) {
88 # Create lock file signalling the state has been finished. is_done() return
89 # true then. Return true if succeeded.
92 my $file = IO
::Handle
->new();
93 open ($file, '>', $self->lockfile) or
94 croak
"Could not open `" . $self->lockfile .
95 "' lockfile for writing: $!";
96 $file->sync && close($file) or
97 croak
"Could not sync and close `" . $self->lockfile .
102 # Close log file. Remove lock file if exist. is_done() return false then.
106 $self->logfd->sync && $self->logfd->close or
107 croak
"Could not sync and close `" . $self->logile . "' logfile: $!";
108 if (-e
$self->lockfile) { unlink $self->lockfile; }
112 # Convert ${^CHILD_ERROR_NATIVE} to string description.
113 # XXX: This is not a method.
114 sub child_error_as_string
{
115 my $reason = ${^CHILD_ERROR_NATIVE
};
116 if (WIFEXITED
($reason)) {
117 $reason = "exit code " . WEXITSTATUS
($reason);
118 } elsif (WIFSIGNALED
($reason)) {
119 $reason = "signal " . WTERMSIG
($reason);
124 # Run command while appending output to log. Blocks. If workdir is nonempty
125 # string, switch into it befere execution (and opening the log).
126 # Return true if command succeeds.
128 my ($self, $workdir, @command) = @_;
131 open(STDOUT
, '>&', $self->logfd->fileno) and
132 open(STDERR
, '>&STDOUT');
133 print STDERR
"Executing: " . join(' ', @command) . "\n";
134 if (defined $workdir && $workdir ne '' && !chdir $workdir) {
135 print STDERR
"Could not change directory to $workdir: $!\n";
140 my $pid = Proc
::SyncExec
::sync_exec
($redirect, @command);
142 $self->log("Could not execute `" . join(' ', @command) . "': $!\n");
145 if ($pid != waitpid($pid, 0) || $?
) {
146 $self->log("Command `" . join(' ', @command) . "' failed: " .
147 child_error_as_string
. "\n");
150 $self->log("Command `" . join(' ', @command) .
151 "' returned successfully.\n");
155 # Run command while appending stderr and stdout to log and stdout to refered
156 # output argument. In case of empty command output fill empty string;
157 # Blocks. If workdir is nonempty string, switch into it befere execution
158 # (and opening the log).
159 # Return true if command succeeds.
161 my ($self, $workdir, $output, @command) = @_;
163 my ($parent, $child);
164 if (!pipe $child, $parent) {
165 $self->log("Could not get connected pipes for command `" .
166 join(' ', @command) . "': $!\n");
172 open(STDOUT
, '>&', fileno $parent) and
175 open(STDERR
, '>&', $self->logfd->fileno) and
176 print STDERR
"Executing: " . join(' ', @command) . "\n";
177 if (defined $workdir && $workdir ne '' && !chdir $workdir) {
178 print STDERR
"Could not change directory to $workdir: $!\n";
183 my $pid = Proc
::SyncExec
::sync_exec
($redirect, @command);
190 $self->log("Could not execute `" . join(' ', @command) . "': $!\n");
194 for ($$output = ''; local $_ = <$child>;) {
199 if ($pid != waitpid($pid, 0) || $?
) {
200 $self->log("Command `" . join(' ', @command) . "' failed: " .
201 child_error_as_string
. "\n");
205 $self->log("Command `" . join(' ', @command) .
206 "' returned successfully.\n");