]>
git.saurik.com Git - apt.git/blob - apt-pkg/packagemanager.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: packagemanager.cc,v 1.30 2003/04/27 03:04:15 doogie Exp $
4 /* ######################################################################
6 Package Manager - Abstacts the package manager
8 More work is needed in the area of transitioning provides, ie exim
9 replacing smail. This can cause interesing side effects.
11 Other cases involving conflicts+replaces should be tested.
13 ##################################################################### */
15 // Include Files /*{{{*/
18 #include <apt-pkg/packagemanager.h>
19 #include <apt-pkg/orderlist.h>
20 #include <apt-pkg/depcache.h>
21 #include <apt-pkg/error.h>
22 #include <apt-pkg/version.h>
23 #include <apt-pkg/acquire-item.h>
24 #include <apt-pkg/algorithms.h>
25 #include <apt-pkg/configuration.h>
26 #include <apt-pkg/sptr.h>
34 // PM::PackageManager - Constructor /*{{{*/
35 // ---------------------------------------------------------------------
37 pkgPackageManager::pkgPackageManager(pkgDepCache
*pCache
) : Cache(*pCache
)
39 FileNames
= new string
[Cache
.Head().PackageCount
];
41 Debug
= _config
->FindB("Debug::pkgPackageManager",false);
44 // PM::PackageManager - Destructor /*{{{*/
45 // ---------------------------------------------------------------------
47 pkgPackageManager::~pkgPackageManager()
53 // PM::GetArchives - Queue the archives for download /*{{{*/
54 // ---------------------------------------------------------------------
56 bool pkgPackageManager::GetArchives(pkgAcquire
*Owner
,pkgSourceList
*Sources
,
59 if (CreateOrderList() == false)
63 _config
->FindB("PackageManager::UnpackAll",true) ?
64 List
->OrderUnpack() : List
->OrderCritical();
65 if (ordering
== false)
66 return _error
->Error("Internal ordering error");
68 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); ++I
)
70 PkgIterator
Pkg(Cache
,*I
);
71 FileNames
[Pkg
->ID
] = string();
73 // Skip packages to erase
74 if (Cache
[Pkg
].Delete() == true)
77 // Skip Packages that need configure only.
78 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
79 Cache
[Pkg
].Keep() == true)
82 // Skip already processed packages
83 if (List
->IsNow(Pkg
) == false)
86 new pkgAcqArchive(Owner
,Sources
,Recs
,Cache
[Pkg
].InstVerIter(Cache
),
93 // PM::FixMissing - Keep all missing packages /*{{{*/
94 // ---------------------------------------------------------------------
95 /* This is called to correct the installation when packages could not
97 bool pkgPackageManager::FixMissing()
99 pkgDepCache::ActionGroup
group(Cache
);
100 pkgProblemResolver
Resolve(&Cache
);
101 List
->SetFileList(FileNames
);
104 for (PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
106 if (List
->IsMissing(I
) == false)
109 // Okay, this file is missing and we need it. Mark it for keep
111 Cache
.MarkKeep(I
, false, false);
114 // We have to empty the list otherwise it will not have the new changes
121 // Now downgrade everything that is broken
122 return Resolve
.ResolveByKeep() == true && Cache
.BrokenCount() == 0;
125 // PM::ImmediateAdd - Add the immediate flag recursivly /*{{{*/
126 // ---------------------------------------------------------------------
127 /* This adds the immediate flag to the pkg and recursively to the
130 void pkgPackageManager::ImmediateAdd(PkgIterator I
, bool UseInstallVer
, unsigned const int &Depth
)
136 if(Cache
[I
].InstallVer
== 0)
138 D
= Cache
[I
].InstVerIter(Cache
).DependsList();
140 if (I
->CurrentVer
== 0)
142 D
= I
.CurrentVer().DependsList();
145 for ( /* nothing */ ; D
.end() == false; ++D
)
146 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
148 if(!List
->IsFlag(D
.TargetPkg(), pkgOrderList::Immediate
))
151 clog
<< OutputInDepth(Depth
) << "ImmediateAdd(): Adding Immediate flag to " << D
.TargetPkg() << " cause of " << D
.DepType() << " " << I
.Name() << endl
;
152 List
->Flag(D
.TargetPkg(),pkgOrderList::Immediate
);
153 ImmediateAdd(D
.TargetPkg(), UseInstallVer
, Depth
+ 1);
159 // PM::CreateOrderList - Create the ordering class /*{{{*/
160 // ---------------------------------------------------------------------
161 /* This populates the ordering list with all the packages that are
163 bool pkgPackageManager::CreateOrderList()
169 List
= new pkgOrderList(&Cache
);
171 static bool const NoImmConfigure
= !_config
->FindB("APT::Immediate-Configure",true);
173 // Generate the list of affected packages and sort it
174 for (PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
176 // Ignore no-version packages
177 if (I
->VersionList
== 0)
180 // Mark the package and its dependends for immediate configuration
181 if (((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
||
182 (I
->Flags
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
) &&
183 NoImmConfigure
== false)
186 clog
<< "CreateOrderList(): Adding Immediate flag for " << I
.Name() << endl
;
187 List
->Flag(I
,pkgOrderList::Immediate
);
189 // Look for other install packages to make immediate configurea
190 ImmediateAdd(I
, true);
192 // And again with the current version.
193 ImmediateAdd(I
, false);
197 if ((Cache
[I
].Keep() == true ||
198 Cache
[I
].InstVerIter(Cache
) == I
.CurrentVer()) &&
199 I
.State() == pkgCache::PkgIterator::NeedsNothing
&&
200 (Cache
[I
].iFlags
& pkgDepCache::ReInstall
) != pkgDepCache::ReInstall
&&
201 (I
.Purge() != false || Cache
[I
].Mode
!= pkgDepCache::ModeDelete
||
202 (Cache
[I
].iFlags
& pkgDepCache::Purge
) != pkgDepCache::Purge
))
205 // Append it to the list
212 // PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/
213 // ---------------------------------------------------------------------
214 /* The restriction on provides is to eliminate the case when provides
215 are transitioning between valid states [ie exim to smail] */
216 bool pkgPackageManager::DepAlwaysTrue(DepIterator D
)
218 if (D
.TargetPkg()->ProvidesList
!= 0)
221 if ((Cache
[D
] & pkgDepCache::DepInstall
) != 0 &&
222 (Cache
[D
] & pkgDepCache::DepNow
) != 0)
227 // PM::CheckRConflicts - Look for reverse conflicts /*{{{*/
228 // ---------------------------------------------------------------------
229 /* This looks over the reverses for a conflicts line that needs early
231 bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg
,DepIterator D
,
234 for (;D
.end() == false; ++D
)
236 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
237 D
->Type
!= pkgCache::Dep::Obsoletes
)
240 // The package hasnt been changed
241 if (List
->IsNow(Pkg
) == false)
244 // Ignore self conflicts, ignore conflicts from irrelevent versions
245 if (D
.ParentPkg() == Pkg
|| D
.ParentVer() != D
.ParentPkg().CurrentVer())
248 if (Cache
.VS().CheckDep(Ver
,D
->CompareOp
,D
.TargetVer()) == false)
251 if (EarlyRemove(D
.ParentPkg()) == false)
252 return _error
->Error("Reverse conflicts early remove for package '%s' failed",
258 // PM::ConfigureAll - Run the all out configuration /*{{{*/
259 // ---------------------------------------------------------------------
260 /* This configures every package. It is assumed they are all unpacked and
261 that the final configuration is valid. */
262 bool pkgPackageManager::ConfigureAll()
264 pkgOrderList
OList(&Cache
);
266 // Populate the order list
267 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); ++I
)
268 if (List
->IsFlag(pkgCache::PkgIterator(Cache
,*I
),
269 pkgOrderList::UnPacked
) == true)
272 if (OList
.OrderConfigure() == false)
275 std::string
const conf
= _config
->Find("PackageManager::Configure","all");
276 bool const ConfigurePkgs
= (conf
== "all");
278 // Perform the configuring
279 for (pkgOrderList::iterator I
= OList
.begin(); I
!= OList
.end(); ++I
)
281 PkgIterator
Pkg(Cache
,*I
);
283 if (ConfigurePkgs
== true && Configure(Pkg
) == false)
286 List
->Flag(Pkg
,pkgOrderList::Configured
,pkgOrderList::States
);
292 // PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/
293 // ---------------------------------------------------------------------
294 /* This routine scheduals the configuration of the given package and all
295 of it's dependents. */
296 bool pkgPackageManager::SmartConfigure(PkgIterator Pkg
)
299 clog
<< "SmartConfigure " << Pkg
.Name() << endl
;
301 pkgOrderList
OList(&Cache
);
303 if (DepAdd(OList
,Pkg
) == false)
306 static std::string
const conf
= _config
->Find("PackageManager::Configure","all");
307 static bool const ConfigurePkgs
= (conf
== "all" || conf
== "smart");
309 if (ConfigurePkgs
== true)
310 if (OList
.OrderConfigure() == false)
313 // Perform the configuring
314 for (pkgOrderList::iterator I
= OList
.begin(); I
!= OList
.end(); ++I
)
316 PkgIterator
Pkg(Cache
,*I
);
318 if (ConfigurePkgs
== true && Configure(Pkg
) == false)
321 List
->Flag(Pkg
,pkgOrderList::Configured
,pkgOrderList::States
);
324 if ((Cache
[Pkg
].InstVerIter(Cache
)->MultiArch
& pkgCache::Version::Same
) == pkgCache::Version::Same
)
325 for (PkgIterator P
= Pkg
.Group().PackageList();
326 P
.end() == false; P
= Pkg
.Group().NextPkg(P
))
328 if (Pkg
== P
|| List
->IsFlag(P
,pkgOrderList::Configured
) == true ||
329 Cache
[P
].InstallVer
== 0 || (P
.CurrentVer() == Cache
[P
].InstallVer
&&
330 (Cache
[Pkg
].iFlags
& pkgDepCache::ReInstall
) != pkgDepCache::ReInstall
))
336 if (List
->IsFlag(Pkg
,pkgOrderList::Configured
) == false)
337 return _error
->Error(_("Could not perform immediate configuration on '%s'. "
338 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg
.Name(),1);
343 // PM::DepAdd - Add all dependents to the oder list /*{{{*/
344 // ---------------------------------------------------------------------
345 /* This recursively adds all dependents to the order list */
346 bool pkgPackageManager::DepAdd(pkgOrderList
&OList
,PkgIterator Pkg
,int Depth
)
348 if (OList
.IsFlag(Pkg
,pkgOrderList::Added
) == true)
350 if (List
->IsFlag(Pkg
,pkgOrderList::Configured
) == true)
352 if (List
->IsFlag(Pkg
,pkgOrderList::UnPacked
) == false)
356 std::clog
<< OutputInDepth(Depth
) << "DepAdd: " << Pkg
.Name() << std::endl
;
358 // Put the package on the list
359 OList
.push_back(Pkg
);
360 OList
.Flag(Pkg
,pkgOrderList::Added
);
363 // Check the dependencies to see if they are all satisfied.
365 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
367 if (D
->Type
!= pkgCache::Dep::Depends
&& D
->Type
!= pkgCache::Dep::PreDepends
)
375 for (bool LastOR
= true; D
.end() == false && LastOR
== true; ++D
)
377 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
382 SPtrArray
<Version
*> VList
= D
.AllTargets();
383 for (Version
**I
= VList
; *I
!= 0 && Bad
== true; ++I
)
385 VerIterator
Ver(Cache
,*I
);
386 PkgIterator Pkg
= Ver
.ParentPkg();
388 // See if the current version is ok
389 if (Pkg
.CurrentVer() == Ver
&& List
->IsNow(Pkg
) == true &&
390 Pkg
.State() == PkgIterator::NeedsNothing
)
396 // Not the install version
397 if (Cache
[Pkg
].InstallVer
!= *I
||
398 (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
))
401 if (List
->IsFlag(Pkg
,pkgOrderList::UnPacked
) == true)
402 Bad
= !DepAdd(OList
,Pkg
,Depth
);
403 if (List
->IsFlag(Pkg
,pkgOrderList::Configured
) == true)
411 std::clog
<< OutputInDepth(Depth
) << "DepAdd FAILS on: " << Pkg
.Name() << std::endl
;
412 OList
.Flag(Pkg
,0,pkgOrderList::Added
);
423 // PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
424 // ---------------------------------------------------------------------
425 /* This is called to deal with conflicts arising from unpacking */
426 bool pkgPackageManager::EarlyRemove(PkgIterator Pkg
)
428 if (List
->IsNow(Pkg
) == false)
431 // Already removed it
432 if (List
->IsFlag(Pkg
,pkgOrderList::Removed
) == true)
435 // Woops, it will not be re-installed!
436 if (List
->IsFlag(Pkg
,pkgOrderList::InList
) == false)
439 // Essential packages get special treatment
440 bool IsEssential
= false;
441 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) != 0)
444 /* Check for packages that are the dependents of essential packages and
446 if (Pkg
->CurrentVer
!= 0)
448 for (DepIterator D
= Pkg
.RevDependsList(); D
.end() == false &&
449 IsEssential
== false; ++D
)
450 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
451 if ((D
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != 0)
455 if (IsEssential
== true)
457 if (_config
->FindB("APT::Force-LoopBreak",false) == false)
458 return _error
->Error(_("This installation run will require temporarily "
459 "removing the essential package %s due to a "
460 "Conflicts/Pre-Depends loop. This is often bad, "
461 "but if you really want to do it, activate the "
462 "APT::Force-LoopBreak option."),Pkg
.Name());
465 bool Res
= SmartRemove(Pkg
);
466 if (Cache
[Pkg
].Delete() == false)
467 List
->Flag(Pkg
,pkgOrderList::Removed
,pkgOrderList::States
);
472 // PM::SmartRemove - Removal Helper /*{{{*/
473 // ---------------------------------------------------------------------
475 bool pkgPackageManager::SmartRemove(PkgIterator Pkg
)
477 if (List
->IsNow(Pkg
) == false)
480 List
->Flag(Pkg
,pkgOrderList::Configured
,pkgOrderList::States
);
482 return Remove(Pkg
,(Cache
[Pkg
].iFlags
& pkgDepCache::Purge
) == pkgDepCache::Purge
);
486 // PM::SmartUnPack - Install helper /*{{{*/
487 // ---------------------------------------------------------------------
488 /* This performs the task of handling pre-depends. */
489 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg
)
491 return SmartUnPack(Pkg
, true);
493 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg
, bool const Immediate
)
495 // Check if it is already unpacked
496 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
497 Cache
[Pkg
].Keep() == true)
499 List
->Flag(Pkg
,pkgOrderList::UnPacked
,pkgOrderList::States
);
500 if (Immediate
== true &&
501 List
->IsFlag(Pkg
,pkgOrderList::Immediate
) == true)
502 if (SmartConfigure(Pkg
) == false)
503 return _error
->Error(_("Could not perform immediate configuration on already unpacked '%s'. "
504 "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg
.Name());
508 VerIterator
const instVer
= Cache
[Pkg
].InstVerIter(Cache
);
510 /* See if this packages install version has any predependencies
511 that are not met by 'now' packages. */
512 for (DepIterator D
= instVer
.DependsList();
515 // Compute a single dependency element (glob or)
516 pkgCache::DepIterator Start
;
517 pkgCache::DepIterator End
;
520 while (End
->Type
== pkgCache::Dep::PreDepends
)
523 clog
<< "PreDepends order for " << Pkg
.Name() << std::endl
;
525 // Look for possible ok targets.
526 SPtrArray
<Version
*> VList
= Start
.AllTargets();
528 for (Version
**I
= VList
; *I
!= 0 && Bad
== true; I
++)
530 VerIterator
Ver(Cache
,*I
);
531 PkgIterator Pkg
= Ver
.ParentPkg();
533 // See if the current version is ok
534 if (Pkg
.CurrentVer() == Ver
&& List
->IsNow(Pkg
) == true &&
535 Pkg
.State() == PkgIterator::NeedsNothing
)
539 clog
<< "Found ok package " << Pkg
.Name() << endl
;
544 // Look for something that could be configured.
545 for (Version
**I
= VList
; *I
!= 0 && Bad
== true; I
++)
547 VerIterator
Ver(Cache
,*I
);
548 PkgIterator Pkg
= Ver
.ParentPkg();
550 // Not the install version
551 if (Cache
[Pkg
].InstallVer
!= *I
||
552 (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
))
556 clog
<< "Trying to SmartConfigure " << Pkg
.Name() << endl
;
557 Bad
= !SmartConfigure(Pkg
);
560 /* If this or element did not match then continue on to the
561 next or element until a matching element is found */
564 // This triggers if someone make a pre-depends/depend loop.
566 return _error
->Error("Couldn't configure pre-depend %s for %s, "
567 "probably a dependency cycle.",
568 End
.TargetPkg().Name(),Pkg
.Name());
575 if (End
->Type
== pkgCache::Dep::Conflicts
||
576 End
->Type
== pkgCache::Dep::Obsoletes
)
578 /* Look for conflicts. Two packages that are both in the install
579 state cannot conflict so we don't check.. */
580 SPtrArray
<Version
*> VList
= End
.AllTargets();
581 for (Version
**I
= VList
; *I
!= 0; I
++)
583 VerIterator
Ver(Cache
,*I
);
584 PkgIterator Pkg
= Ver
.ParentPkg();
586 // See if the current version is conflicting
587 if (Pkg
.CurrentVer() == Ver
&& List
->IsNow(Pkg
) == true)
589 if (EarlyRemove(Pkg
) == false)
590 return _error
->Error("Internal Error, Could not early remove %s",Pkg
.Name());
596 // Check for reverse conflicts.
597 if (CheckRConflicts(Pkg
,Pkg
.RevDependsList(),
598 instVer
.VerStr()) == false)
601 for (PrvIterator P
= instVer
.ProvidesList();
602 P
.end() == false; ++P
)
603 if (Pkg
->Group
!= P
.OwnerPkg()->Group
)
604 CheckRConflicts(Pkg
,P
.ParentPkg().RevDependsList(),P
.ProvideVersion());
606 List
->Flag(Pkg
,pkgOrderList::UnPacked
,pkgOrderList::States
);
608 if (Immediate
== true && instVer
->MultiArch
== pkgCache::Version::Same
)
610 /* Do lockstep M-A:same unpacking in two phases:
611 First unpack all installed architectures, then the not installed.
612 This way we avoid that M-A: enabled packages are installed before
613 their older non-M-A enabled packages are replaced by newer versions */
614 bool const installed
= Pkg
->CurrentVer
!= 0;
615 if (installed
== true && Install(Pkg
,FileNames
[Pkg
->ID
]) == false)
617 for (PkgIterator P
= Pkg
.Group().PackageList();
618 P
.end() == false; P
= Pkg
.Group().NextPkg(P
))
620 if (P
->CurrentVer
== 0 || P
== Pkg
|| List
->IsFlag(P
,pkgOrderList::UnPacked
) == true ||
621 Cache
[P
].InstallVer
== 0 || (P
.CurrentVer() == Cache
[P
].InstallVer
&&
622 (Cache
[Pkg
].iFlags
& pkgDepCache::ReInstall
) != pkgDepCache::ReInstall
))
624 if (SmartUnPack(P
, false) == false)
627 if (installed
== false && Install(Pkg
,FileNames
[Pkg
->ID
]) == false)
629 for (PkgIterator P
= Pkg
.Group().PackageList();
630 P
.end() == false; P
= Pkg
.Group().NextPkg(P
))
632 if (P
->CurrentVer
!= 0 || P
== Pkg
|| List
->IsFlag(P
,pkgOrderList::UnPacked
) == true ||
633 Cache
[P
].InstallVer
== 0 || (P
.CurrentVer() == Cache
[P
].InstallVer
&&
634 (Cache
[Pkg
].iFlags
& pkgDepCache::ReInstall
) != pkgDepCache::ReInstall
))
636 if (SmartUnPack(P
, false) == false)
640 else if (Install(Pkg
,FileNames
[Pkg
->ID
]) == false)
643 // Perform immedate configuration of the package.
644 if (Immediate
== true &&
645 List
->IsFlag(Pkg
,pkgOrderList::Immediate
) == true)
646 if (SmartConfigure(Pkg
) == false)
647 return _error
->Error(_("Could not perform immediate configuration on '%s'. "
648 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg
.Name(),2);
653 // PM::OrderInstall - Installation ordering routine /*{{{*/
654 // ---------------------------------------------------------------------
656 pkgPackageManager::OrderResult
pkgPackageManager::OrderInstall()
658 if (CreateOrderList() == false)
664 clog
<< "Beginning to order" << endl
;
666 bool const ordering
=
667 _config
->FindB("PackageManager::UnpackAll",true) ?
668 List
->OrderUnpack(FileNames
) : List
->OrderCritical();
669 if (ordering
== false)
671 _error
->Error("Internal ordering error");
676 clog
<< "Done ordering" << endl
;
678 bool DoneSomething
= false;
679 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); ++I
)
681 PkgIterator
Pkg(Cache
,*I
);
683 if (List
->IsNow(Pkg
) == false)
686 clog
<< "Skipping already done " << Pkg
.Name() << endl
;
690 if (List
->IsMissing(Pkg
) == true)
693 clog
<< "Sequence completed at " << Pkg
.Name() << endl
;
694 if (DoneSomething
== false)
696 _error
->Error("Internal Error, ordering was unable to handle the media swap");
703 if (Cache
[Pkg
].Keep() == true &&
704 Pkg
.State() == pkgCache::PkgIterator::NeedsNothing
&&
705 (Cache
[Pkg
].iFlags
& pkgDepCache::ReInstall
) != pkgDepCache::ReInstall
)
707 _error
->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg
.Name());
711 // Perform a delete or an install
712 if (Cache
[Pkg
].Delete() == true)
714 if (SmartRemove(Pkg
) == false)
718 if (SmartUnPack(Pkg
) == false)
720 DoneSomething
= true;
723 // Final run through the configure phase
724 if (ConfigureAll() == false)
728 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); ++I
)
730 if (List
->IsFlag(*I
,pkgOrderList::Configured
) == false)
732 _error
->Error("Internal error, packages left unconfigured. %s",
733 PkgIterator(Cache
,*I
).Name());
741 // PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/
742 // ---------------------------------------------------------------------
743 pkgPackageManager::OrderResult
744 pkgPackageManager::DoInstallPostFork(int statusFd
)
747 // FIXME: use SetCloseExec here once it taught about throwing
748 // exceptions instead of doing _exit(100) on failure
749 fcntl(statusFd
,F_SETFD
,FD_CLOEXEC
);
750 bool goResult
= Go(statusFd
);
751 if(goResult
== false)
757 // PM::DoInstall - Does the installation /*{{{*/
758 // ---------------------------------------------------------------------
759 /* This uses the filenames in FileNames and the information in the
760 DepCache to perform the installation of packages.*/
761 pkgPackageManager::OrderResult
pkgPackageManager::DoInstall(int statusFd
)
763 if(DoInstallPreFork() == Failed
)
766 return DoInstallPostFork(statusFd
);