]>
git.saurik.com Git - apt.git/blob - apt-pkg/deb/dpkgpm.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: dpkgpm.cc,v 1.2 1998/11/22 03:20:35 jgg Exp $
4 /* ######################################################################
6 DPKG Package Manager - Provide an interface to dpkg
8 ##################################################################### */
12 #pragma implementation "apt-pkg/dpkgpm.h"
14 #include <apt-pkg/dpkgpm.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/configuration.h>
21 #include <sys/types.h>
27 // DPkgPM::pkgDPkgPM - Constructor /*{{{*/
28 // ---------------------------------------------------------------------
30 pkgDPkgPM::pkgDPkgPM(pkgDepCache
&Cache
) : pkgPackageManager(Cache
)
34 // DPkgPM::pkgDPkgPM - Destructor /*{{{*/
35 // ---------------------------------------------------------------------
37 pkgDPkgPM::~pkgDPkgPM()
41 // DPkgPM::Install - Install a package /*{{{*/
42 // ---------------------------------------------------------------------
43 /* Add an install operation to the sequence list */
44 bool pkgDPkgPM::Install(PkgIterator Pkg
,string File
)
46 if (File
.empty() == true || Pkg
.end() == true)
47 return _error
->Error("Internal Error, No file name for %s",Pkg
.Name());
49 List
.push_back(Item(Item::Install
,Pkg
,File
));
53 // DPkgPM::Configure - Configure a package /*{{{*/
54 // ---------------------------------------------------------------------
55 /* Add a configure operation to the sequence list */
56 bool pkgDPkgPM::Configure(PkgIterator Pkg
)
58 if (Pkg
.end() == true)
61 List
.push_back(Item(Item::Configure
,Pkg
));
65 // DPkgPM::Remove - Remove a package /*{{{*/
66 // ---------------------------------------------------------------------
67 /* Add a remove operation to the sequence list */
68 bool pkgDPkgPM::Remove(PkgIterator Pkg
)
70 if (Pkg
.end() == true)
73 List
.push_back(Item(Item::Remove
,Pkg
));
77 // DPkgPM::Go - Run the sequence /*{{{*/
78 // ---------------------------------------------------------------------
79 /* This globs the operations and calls dpkg */
82 for (vector
<Item
>::iterator I
= List
.begin(); I
!= List
.end();)
84 vector
<Item
>::iterator J
= I
;
85 for (; J
!= List
.end() && J
->Op
== I
->Op
; J
++);
87 // Generate the argument list
88 const char *Args
[400];
93 unsigned long Size
= 0;
94 Args
[n
++] = _config
->Find("Dir::Bin::dpkg","dpkg").c_str();
95 Size
+= strlen(Args
[n
-1]);
100 Args
[n
++] = "--force-depends";
101 Size
+= strlen(Args
[n
-1]);
102 Args
[n
++] = "--force-remove-essential";
103 Size
+= strlen(Args
[n
-1]);
104 Args
[n
++] = "--remove";
105 Size
+= strlen(Args
[n
-1]);
108 case Item::Configure
:
109 Args
[n
++] = "--configure";
110 Size
+= strlen(Args
[n
-1]);
114 Args
[n
++] = "--unpack";
115 Size
+= strlen(Args
[n
-1]);
119 // Write in the file or package names
120 if (I
->Op
== Item::Install
)
122 for (;I
!= J
&& Size
< 1024; I
++)
124 Args
[n
++] = I
->File
.c_str();
125 Size
+= strlen(Args
[n
-1]);
130 for (;I
!= J
&& Size
< 1024; I
++)
132 Args
[n
++] = I
->Pkg
.Name();
133 Size
+= strlen(Args
[n
-1]);
139 if (_config
->FindB("Debug::pkgDPkgPM",false) == true)
141 for (unsigned int k
= 0; k
!= n
; k
++)
142 clog
<< Args
[k
] << ' ';
151 /* Mask off sig int/quit. We do this because dpkg also does when
152 it forks scripts. What happens is that when you hit ctrl-c it sends
153 it to all processes in the group. Since dpkg ignores the signal
154 it doesn't die but we do! So we must also ignore it */
155 signal(SIGQUIT
,SIG_IGN
);
156 signal(SIGINT
,SIG_IGN
);
159 pid_t Child
= fork();
161 return _error
->Errno("fork","Could't fork");
166 signal(SIGQUIT
,SIG_DFL
);
167 signal(SIGINT
,SIG_DFL
);
168 signal(SIGWINCH
,SIG_DFL
);
169 signal(SIGCONT
,SIG_DFL
);
170 signal(SIGTSTP
,SIG_DFL
);
172 if (chdir(_config
->FindDir("Dir::Cache::Archives").c_str()) != 0)
175 // Close all of our FDs - just in case
176 for (int K
= 3; K
!= 40; K
++)
177 fcntl(K
,F_SETFD
,FD_CLOEXEC
);
180 if ((Flags
= fcntl(STDIN_FILENO
,F_GETFL
,dummy
)) < 0)
183 // Discard everything in stdin before forking dpkg
184 if (fcntl(STDIN_FILENO
,F_SETFL
,Flags
| O_NONBLOCK
) < 0)
187 while (read(STDIN_FILENO
,&dummy
,1) == 1);
189 if (fcntl(STDIN_FILENO
,F_SETFL
,Flags
& (~(long)O_NONBLOCK
)) < 0)
192 /* No Job Control Stop Env is a magic dpkg var that prevents it
193 from using sigstop */
194 setenv("DPKG_NO_TSTP","yes",1);
195 execvp("dpkg",(char **)Args
);
196 cerr
<< "Could not exec dpkg!" << endl
;
202 while (waitpid(Child
,&Status
,0) != Child
)
206 return _error
->Errno("waitpid","Couldn't wait for subprocess");
209 // Check for an error code.
210 if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0)
211 return _error
->Error("Sub-process returned an error code");
213 // Restore sig int/quit
214 signal(SIGQUIT
,SIG_DFL
);
215 signal(SIGINT
,SIG_DFL
);