]>
git.saurik.com Git - apt.git/blob - apt-pkg/deb/dpkgpm.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: dpkgpm.cc,v 1.1 1998/11/13 04:23:39 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];
98 Args
[n
++] = "--force-depends";
99 Args
[n
++] = "--force-remove-essential";
100 Args
[n
++] = "--remove";
103 case Item::Configure
:
104 Args
[n
++] = "--configure";
108 Args
[n
++] = "--unpack";
112 // Write in the file or package names
113 if (I
->Op
== Item::Install
)
115 Args
[n
++] = I
->File
.c_str();
118 Args
[n
++] = I
->Pkg
.Name();
121 /* for (int k = 0; k != n; k++)
122 cout << Args[k] << ' ';
129 /* Mask off sig int/quit. We do this because dpkg also does when
130 it forks scripts. What happens is that when you hit ctrl-c it sends
131 it to all processes in the group. Since dpkg ignores the signal
132 it doesn't die but we do! So we must also ignore it */
133 signal(SIGQUIT
,SIG_IGN
);
134 signal(SIGINT
,SIG_IGN
);
137 pid_t Child
= fork();
139 return _error
->Errno("fork","Could't fork");
144 signal(SIGQUIT
,SIG_DFL
);
145 signal(SIGINT
,SIG_DFL
);
146 signal(SIGWINCH
,SIG_DFL
);
147 signal(SIGCONT
,SIG_DFL
);
148 signal(SIGTSTP
,SIG_DFL
);
150 if (chdir(_config
->FindDir("Dir::Cache::Archives").c_str()) != 0)
153 // Close all of our FDs - just in case
154 for (int K
= 3; K
!= 40; K
++)
155 fcntl(K
,F_SETFD
,FD_CLOEXEC
);
158 if ((Flags
= fcntl(STDIN_FILENO
,F_GETFL
,dummy
)) < 0)
161 // Discard everything in stdin before forking dpkg
162 if (fcntl(STDIN_FILENO
,F_SETFL
,Flags
| O_NONBLOCK
) < 0)
165 while (read(STDIN_FILENO
,&dummy
,1) == 1);
167 if (fcntl(STDIN_FILENO
,F_SETFL
,Flags
& (~(long)O_NONBLOCK
)) < 0)
170 /* No Job Control Stop Env is a magic dpkg var that prevents it
171 from using sigstop */
172 setenv("DPKG_NO_TSTP","yes",1);
173 execvp("dpkg",(char **)Args
);
174 cerr
<< "Could not exec dpkg!" << endl
;
180 while (waitpid(Child
,&Status
,0) != Child
)
184 return _error
->Errno("waitpid","Couldn't wait for subprocess");
187 // Check for an error code.
188 if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0)
189 return _error
->Error("Sub-process returned an error code");
191 // Restore sig int/quit
192 signal(SIGQUIT
,SIG_DFL
);
193 signal(SIGINT
,SIG_DFL
);