#include <sys/types.h>
#include <unistd.h>
+#ifdef __GLIBC__
+/* glibc's way of closing the file without freeing the file pointer */
+extern int _IO_file_close_it(FILE *);
+#else
+#define _IO_file_close_it(fp) 0
+#endif
+
/* argh, swig undefs bool for perl */
#ifndef bool
typedef int bool;
} Chksum;
%rename(xfopen) solv_xfopen;
-%rename(xfopen_fd) solv_xfopen_fd;
-%rename(xfopen_dup) solv_xfopen_dup;
-%rename(xfclose) solv_xfclose;
-%rename(xfileno) solv_xfileno;
+%rename(xfopen_fd) solv_xfopen_dup;
+
+%nodefaultctor FILE;
+typedef struct {
+} FILE;
+
+%newobject solv_xfopen;
+%newobject solv_xfopen_dup;
FILE *solv_xfopen(const char *fn, const char *mode = 0);
-FILE *solv_xfopen_fd(const char *fn, int fd, const char *mode = 0);
FILE *solv_xfopen_dup(const char *fn, int fd, const char *mode = 0);
-int solv_xfclose(FILE *fp);
-int solv_xfileno(FILE *fp);
%{
- SWIGINTERN int solv_xfclose(FILE *fp) {
- return fclose(fp);
- }
- SWIGINTERN int solv_xfileno(FILE *fp) {
- return fileno(fp);
- }
SWIGINTERN FILE *solv_xfopen_dup(const char *fn, int fd, const char *mode) {
fd = dup(fd);
return fd == -1 ? 0 : solv_xfopen_fd(fn, fd, mode);
int const count;
} TransactionClass;
+%extend FILE {
+ ~FILE() {
+ fclose($self);
+ }
+ int fileno() {
+ return fileno($self);
+ }
+ int dup() {
+ return dup(fileno($self));
+ }
+ bool flush() {
+ return fflush($self) == 0;
+ }
+ bool close() {
+ bool ret;
+ ret = fflush($self) == 0;
+ _IO_file_close_it($self);
+ return ret;
+ }
+}
%extend Job {
static const Id SOLVER_SOLVABLE = SOLVER_SOLVABLE;
}
}
if ($uncompress) {
- return solv::xfopen_dup($file, fileno($f));
+ return solv::xfopen_fd($file, fileno($f));
} else {
- return solv::xfopen_dup(undef, fileno($f));
+ return solv::xfopen_fd(undef, fileno($f));
}
}
return undef if sysread($f, $fextcookie, 32) != 32;
}
sysseek($f, 0, Fcntl::SEEK_SET);
- my $fd = solv::xfopen_dup(undef, fileno($f));
+ my $fd = solv::xfopen_fd(undef, fileno($f));
my $flags = $ext ? $solv::Repo::REPO_USE_LOADING|$solv::Repo::REPO_EXTEND_SOLVABLES : 0;
$flags |= $solv::Repo::REPO_LOCALPOOL if $ext && $ext ne 'DL';
if (!$self->{'handle'}->add_solv($fd, $flags)) {
- solv::xfclose($fd);
return undef;
}
- solv::xfclose($fd);
$self->{'cookie'} = $fcookie unless $ext;
$self->{'extcookie'} = $fextcookie if $fextcookie;
utime undef, undef, $f if $mark;
};
return unless $f;
chmod 0444, $f;
- my $ff = solv::xfopen_dup(undef, fileno($f));
+ my $ff = solv::xfopen_fd(undef, fileno($f));
if (!$info) {
$self->{'handle'}->write($ff);
} elsif ($ext) {
} else {
$self->{'handle'}->write_first_repodata($ff);
}
- solv::xfclose($ff);
+ undef $ff; # also flushes
if ($self->{'type'} ne 'system' && !$ext) {
$self->{'extcookie'} ||= $self->calc_cookie_ext($f, $self->{'cookie'});
syswrite($f, $self->{'extcookie'});
$info->extend_to_repo();
$info->add_solv($f, $solv::Repo::REPO_EXTEND_SOLVABLES);
}
- solv::xfclose($f);
}
}
rename($tmpname, $self->cachepath($ext));
} elsif ($ext eq 'FL') {
$self->{'handle'}->add_deltainfoxml($f, $solv::Repo::REPO_USE_LOADING);
}
- solv::xfclose($f);
$self->writecachedrepo($ext, $repodata);
return 1;
}
$self->{'cookie'} = $self->calc_cookie_fp($f);
if ($self->usecachedrepo(undef, 1)) {
print "cached\n";
- solv::xfclose($f);
return 1;
}
$self->{'handle'}->add_repomdxml($f, 0);
- solv::xfclose($f);
print "fetching\n";
my ($filename, $filechksum) = $self->find('primary');
if ($filename) {
$f = $self->download($filename, 1, $filechksum, 1);
if ($f) {
$self->{'handle'}->add_rpmmd($f, undef, 0);
- solv::xfclose($f);
}
return undef if $self->{'incomplete'};
}
$f = $self->download($filename, 1, $filechksum, 1);
if ($f) {
$self->{'handle'}->add_updateinfoxml($f, 0);
- solv::xfclose($f);
}
}
$self->add_exts();
my $f = $self->download("$descrdir/$filename", 1, $filechksum);
return 0 unless $f;
$self->{'handle'}->add_susetags($f, $defvendorid, $ext, $solv::Repo::REPO_USE_LOADING|$solv::Repo::REPO_EXTEND_SOLVABLES);
- solv::xfclose($f);
$self->writecachedrepo($ext, $repodata);
return 1;
}
$self->{'cookie'} = $self->calc_cookie_fp($f);
if ($self->usecachedrepo(undef, 1)) {
print "cached\n";
- solv::xfclose($f);
return 1;
}
$self->{'handle'}->add_content($f, 0);
- solv::xfclose($f);
print "fetching\n";
my $defvendorid = $self->{'handle'}->lookup_id($solv::SOLVID_META, $solv::SUSETAGS_DEFAULTVENDOR);
my $descrdir = $self->{'handle'}->lookup_str($solv::SOLVID_META, $solv::SUSETAGS_DESCRDIR) || 'suse/setup/descr';
$f = $self->download("$descrdir/$filename", 1, $filechksum, 1);
if ($f) {
$self->{'handle'}->add_susetags($f, $defvendorid, undef, $solv::Repo::REPO_NO_INTERNALIZE|$solv::Repo::SUSETAGS_RECORD_SHARES);
- solv::xfclose($f);
($filename, $filechksum) = $self->find('packages.en.gz');
($filename, $filechksum) = $self->find('packages.en') unless $filename;
if ($filename) {
$f = $self->download("$descrdir/$filename", 1, $filechksum, 1);
if ($f) {
$self->{'handle'}->add_susetags($f, $defvendorid, undef, $solv::Repo::REPO_NO_INTERNALIZE|$solv::Repo::REPO_REUSE_REPODATA|$solv::Repo::REPO_EXTEND_SOLVABLES);
- solv::xfclose($f);
}
}
$self->{'handle'}->internalize();
print "install ".$p->str()."\n";
my $f = $newpkgsfps{$p->{'id'}};
my $mode = $steptype == $solv::Transaction::SOLVER_TRANSACTION_INSTALL ? '-U' : '-i';
- system('rpm', $mode, '--force', '--nodeps', '--nodigest', '--nosignature', "/dev/fd/".solv::xfileno($f)) && die("rpm failed: $?\n");
- solv::xfclose($f);
+ system('rpm', $mode, '--force', '--nodeps', '--nodigest', '--nosignature', "/dev/fd/".$f->fileno()) && die("rpm failed: $?\n");
delete $newpkgsfps{$p->{'id'}};
}
}
self['baseurl'] = url
def setfrommetalink(self, metalink):
- nf = self.download(metalink, False, None)
- if not nf:
+ f = self.download(metalink, False, None)
+ if not f:
return None
- f = os.fdopen(os.dup(solv.xfileno(nf)), 'r')
- solv.xfclose(nf)
+ f = os.fdopen(f.dup(), 'r')
urls = []
chksum = None
for l in f.readlines():
return chksum
def setfrommirrorlist(self, mirrorlist):
- nf = self.download(mirrorlist, False, None)
- if not nf:
+ f = self.download(mirrorlist, False, None)
+ if not f:
return
- f = os.fdopen(os.dup(solv.xfileno(nf)), 'r')
- solv.xfclose(nf)
+ f = os.fdopen(f.dup(), 'r')
urls = []
for l in f.readline():
l = l.strip()
self['incomplete'] = True
return None
if uncompress:
- return solv.xfopen_fd(file, os.dup(f.fileno()))
- return solv.xfopen_fd(None, os.dup(f.fileno()))
+ return solv.xfopen_fd(file, f.fileno())
+ return solv.xfopen_fd(None, f.fileno())
def usecachedrepo(self, ext, mark=False):
try:
info.extend_to_repo()
# LOCALPOOL does not help as pool already contains all ids
info.add_solv(nf, Repo.REPO_EXTEND_SOLVABLES)
- solv.xfclose(nf)
os.rename(tmpname, self.cachepath(ext))
except IOError, e:
if tmpname:
self['cookie'] = self.calc_cookie_fp(f)
if self.usecachedrepo(None, True):
print "cached"
- solv.xfclose(f)
return True
self.handle.add_repomdxml(f, 0)
- solv.xfclose(f)
print "fetching"
(filename, filechksum) = self.find('primary')
if filename:
f = self.download(filename, True, filechksum, True)
if f:
self.handle.add_rpmmd(f, None, 0)
- solv.xfclose(f)
if 'incomplete' in self:
return False # hopeless, need good primary
(filename, filechksum) = self.find('updateinfo')
f = self.download(filename, True, filechksum, True)
if f:
self.handle.add_updateinfoxml(f, 0)
- solv.xfclose(f)
self.add_exts()
self.writecachedrepo(None)
# must be called after writing the repo
self.handle.add_rpmmd(f, 'FL', Repo.REPO_USE_LOADING|Repo.REPO_EXTEND_SOLVABLES)
elif ext == 'DL':
self.handle.add_deltainfoxml(f, Repo.REPO_USE_LOADING)
- solv.xfclose(f)
self.writecachedrepo(ext, repodata)
return True
self['cookie'] = self.calc_cookie_fp(f)
if self.usecachedrepo(None, True):
print "cached"
- solv.xfclose(f)
return True
self.handle.add_content(f, 0)
- solv.xfclose(f)
print "fetching"
defvendorid = self.handle.lookup_id(solv.SOLVID_META, solv.SUSETAGS_DEFAULTVENDOR)
descrdir = self.handle.lookup_str(solv.SOLVID_META, solv.SUSETAGS_DESCRDIR)
f = self.download(descrdir + '/' + filename, True, filechksum, True)
if f:
self.handle.add_susetags(f, defvendorid, None, Repo.REPO_NO_INTERNALIZE|Repo.SUSETAGS_RECORD_SHARES)
- solv.xfclose(f)
(filename, filechksum) = self.find('packages.en.gz')
if not filename:
(filename, filechksum) = self.find('packages.en')
f = self.download(descrdir + '/' + filename, True, filechksum, True)
if f:
self.handle.add_susetags(f, defvendorid, None, Repo.REPO_NO_INTERNALIZE|Repo.REPO_REUSE_REPODATA|Repo.REPO_EXTEND_SOLVABLES)
- solv.xfclose(f)
self.handle.internalize()
self.add_exts()
self.writecachedrepo(None)
if not f:
return False
self.handle.add_susetags(f, defvendorid, ext, Repo.REPO_USE_LOADING|Repo.REPO_EXTEND_SOLVABLES)
- solv.xfclose(f)
self.writecachedrepo(ext, repodata)
return True
if not f:
continue
nf = tempfile.TemporaryFile()
- nf = os.dup(nf.fileno())
- st = subprocess.call(['/usr/bin/applydeltarpm', '-a', p.arch, "/dev/fd/%d" % solv.xfileno(f), "/dev/fd/%d" % nf])
- solv.xfclose(f)
+ nf = os.dup(nf.fileno()) # get rid of CLOEXEC
+ st = subprocess.call(['/usr/bin/applydeltarpm', '-a', p.arch, "/dev/fd/%d" % f.fileno(), "/dev/fd/%d" % nf])
os.lseek(nf, 0, os.SEEK_SET)
newpkgsfp[p.id] = solv.xfopen_fd("", nf)
+ os.close(nf)
break
if p.id in newpkgsfp:
sys.stdout.write("d")
return nil
end
end
+ rf = nil
if uncompress
- return Solv::xfopen_dup(file, f.fileno)
+ rf = Solv::xfopen_fd(file, f.fileno)
else
- return Solv::xfopen_dup('', f.fileno)
+ rf = Solv::xfopen_fd('', f.fileno)
end
+ f.close
+ return rf
end
def usecachedrepo(ext, mark = false)
return false if fextcookie.length != 32
end
f.sysseek(0, IO::SEEK_SET)
- f = Solv::xfopen_dup('', f.fileno)
+ nf = Solv::xfopen_fd('', f.fileno)
+ f.close
flags = ext ? Solv::Repo::REPO_USE_LOADING|Solv::Repo::REPO_EXTEND_SOLVABLES : 0
flags |= Solv::Repo::REPO_LOCALPOOL if ext && ext != 'DL'
- if ! @handle.add_solv(f, flags)
- Solv::xfclose(f)
+ if ! @handle.add_solv(nf, flags)
+ nf.close
return false
end
- Solv::xfclose(f)
+ nf.close()
@cookie = fcookie unless ext
@extcookie = fextcookie if !ext && @type != 'system'
now = Time.now
Dir::mkdir("/var/cache/solv", 0755) unless FileTest.directory?("/var/cache/solv")
f = Tempfile.new('.newsolv-', '/var/cache/solv')
f.chmod(0444)
- sf = Solv::xfopen_dup('', f.fileno)
+ sf = Solv::xfopen_fd('', f.fileno)
if !info
@handle.write(sf)
elsif ext
else
@handle.write_first_repodata(sf)
end
- Solv::xfclose(sf)
+ sf.close
f.sysseek(0, IO::SEEK_END)
if @type != 'system' && !ext
@extcookie = calc_cookie_ext(f, @cookie) unless @extcookie
f.syswrite(@extcookie)
end
f.syswrite(ext ? @extcookie : @cookie)
- f.close(false)
+ f.close
if @handle.iscontiguous?
sf = Solv::xfopen(f.path)
if sf
info.extend_to_repo()
info.add_solv(sf, Solv::Repo::REPO_EXTEND_SOLVABLES)
end
- Solv::xfclose(sf)
+ sf.close
end
end
File.rename(f.path, cachepath(ext))
@cookie = calc_cookie_fp(f)
if usecachedrepo(nil, true)
puts "cached"
- Solv.xfclose(f)
+ f.close
return true
end
@handle.add_repomdxml(f, 0)
- Solv::xfclose(f)
+ f.close
puts "fetching"
filename, filechksum = find('primary')
if filename
f = download(filename, true, filechksum, true)
if f
@handle.add_rpmmd(f, nil, 0)
- Solv::xfclose(f)
+ f.close
end
return false if @incomplete
end
f = download(filename, true, filechksum, true)
if f
@handle.add_updateinfoxml(f, 0)
- Solv::xfclose(f)
+ f.close
end
end
add_exts()
elsif ext == 'DL'
@handle.add_deltainfoxml(f, Solv::Repo::REPO_USE_LOADING)
end
- Solv::xfclose(f)
+ f.close
writecachedrepo(ext, repodata)
return true
end
@cookie = calc_cookie_fp(f)
if usecachedrepo(nil, true)
puts "cached"
- Solv.xfclose(f)
+ f.close
return true
end
@handle.add_content(f, 0)
- Solv::xfclose(f)
+ f.close
puts "fetching"
defvendorid = @handle.lookup_id(Solv::SOLVID_META, Solv::SUSETAGS_DEFAULTVENDOR)
descrdir = @handle.lookup_str(Solv::SOLVID_META, Solv::SUSETAGS_DESCRDIR)
f = download("#{descrdir}/#{filename}", true, filechksum, true)
if f
@handle.add_susetags(f, defvendorid, nil, Solv::Repo::REPO_NO_INTERNALIZE|Solv::Repo::SUSETAGS_RECORD_SHARES)
- Solv::xfclose(f)
+ f.close
(filename, filechksum) = find('packages.en.gz')
(filename, filechksum) = find('packages.en') unless filename
if filename
f = download("#{descrdir}/#{filename}", true, filechksum, true)
if f
@handle.add_susetags(f, defvendorid, nil, Solv::Repo::REPO_NO_INTERNALIZE|Solv::Repo::REPO_REUSE_REPODATA|Solv::Repo::REPO_EXTEND_SOLVABLES)
- Solv::xfclose(f)
+ f.close
end
end
@handle.internalize()
f = download("#{descrdir}/#{filename}", true, filechksum)
return false unless f
@handle.add_susetags(f, defvendorid, ext, Solv::Repo::REPO_USE_LOADING|Solv::Repo::REPO_EXTEND_SOLVABLES)
- Solv::xfclose(f)
+ f.close
writecachedrepo(ext, repodata)
return true
end
f = newpkgsfp.delete(p.id)
next unless f
mode = steptype == Solv::Transaction::SOLVER_TRANSACTION_INSTALL ? '-U' : '-i'
- system('rpm', mode, '--force', '--nodeps', '--nodigest', '--nosignature', "/dev/fd/#{Solv::xfileno(f).to_s}") || abort("rpm failed: #{$? >> 8}")
- solv::xfclose(f)
+ system('rpm', mode, '--force', '--nodeps', '--nodigest', '--nosignature', "/dev/fd/#{f.fileno().to_s}") || abort("rpm failed: #{$? >> 8}")
+ f.close
end
end
end