|
|
@@ -19,6 +19,7 @@
|
|
|
#include <apt-pkg/fileutl.h>
|
|
|
#include <apt-pkg/cachefile.h>
|
|
|
#include <apt-pkg/packagemanager.h>
|
|
|
+#include <apt-pkg/iprogress.h>
|
|
|
|
|
|
#include <unistd.h>
|
|
|
#include <stdlib.h>
|
|
|
@@ -54,16 +55,21 @@ class pkgDPkgPMPrivate
|
|
|
public:
|
|
|
pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0),
|
|
|
term_out(NULL), history_out(NULL),
|
|
|
- last_reported_progress(0.0), nr_terminal_rows(0),
|
|
|
- fancy_progress_output(false)
|
|
|
+ last_reported_progress(0.0)
|
|
|
{
|
|
|
dpkgbuf[0] = '\0';
|
|
|
- if(_config->FindB("Dpkg::Progress-Fancy", false) == true)
|
|
|
- {
|
|
|
- fancy_progress_output = true;
|
|
|
- _config->Set("DpkgPM::Progress", true);
|
|
|
- }
|
|
|
+ if(_config->FindB("DpkgPM::Progress-Fancy", false) == true)
|
|
|
+ progress = new APT::Progress::PackageManagerFancy();
|
|
|
+ else if (_config->FindB("DpkgPM::Progress", false) == true)
|
|
|
+ progress = new APT::Progress::PackageManagerText();
|
|
|
+ else
|
|
|
+ progress = new APT::Progress::PackageManager();
|
|
|
}
|
|
|
+ ~pkgDPkgPMPrivate()
|
|
|
+ {
|
|
|
+ delete progress;
|
|
|
+ }
|
|
|
+
|
|
|
bool stdin_is_dev_null;
|
|
|
// the buffer we use for the dpkg status-fd reading
|
|
|
char dpkgbuf[1024];
|
|
|
@@ -73,8 +79,7 @@ public:
|
|
|
string dpkg_error;
|
|
|
|
|
|
float last_reported_progress;
|
|
|
- int nr_terminal_rows;
|
|
|
- bool fancy_progress_output;
|
|
|
+ APT::Progress::PackageManager *progress;
|
|
|
};
|
|
|
|
|
|
namespace
|
|
|
@@ -644,8 +649,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
|
|
|
<< ":" << (PackagesDone/float(PackagesTotal)*100.0)
|
|
|
<< ":" << s
|
|
|
<< endl;
|
|
|
- if(_config->FindB("DPkgPM::Progress", false) == true)
|
|
|
- SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0);
|
|
|
+ d->progress->StatusChanged(pkg, PackagesDone, PackagesTotal);
|
|
|
|
|
|
if(OutStatusFd > 0)
|
|
|
FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
|
|
|
@@ -889,52 +893,6 @@ bool pkgDPkgPM::CloseLog()
|
|
|
return true;
|
|
|
}
|
|
|
/*}}}*/
|
|
|
-// DPkgPM::SendTerminalProgress /*{{{*/
|
|
|
-// ---------------------------------------------------------------------
|
|
|
-/* Send progress info to the terminal
|
|
|
- */
|
|
|
-void pkgDPkgPM::SendTerminalProgress(float percentage)
|
|
|
-{
|
|
|
- int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1);
|
|
|
-
|
|
|
- if(percentage < (d->last_reported_progress + reporting_steps))
|
|
|
- return;
|
|
|
-
|
|
|
- std::string progress_str;
|
|
|
- strprintf(progress_str, "Progress: [%3i%%]", (int)percentage);
|
|
|
- if (d->fancy_progress_output)
|
|
|
- {
|
|
|
- int row = d->nr_terminal_rows;
|
|
|
-
|
|
|
- static string save_cursor = "\033[s";
|
|
|
- static string restore_cursor = "\033[u";
|
|
|
-
|
|
|
- static string set_bg_color = "\033[42m"; // green
|
|
|
- static string set_fg_color = "\033[30m"; // black
|
|
|
-
|
|
|
- static string restore_bg = "\033[49m";
|
|
|
- static string restore_fg = "\033[39m";
|
|
|
-
|
|
|
- std::cout << save_cursor
|
|
|
- // move cursor position to last row
|
|
|
- << "\033[" << row << ";0f"
|
|
|
- << set_bg_color
|
|
|
- << set_fg_color
|
|
|
- << progress_str
|
|
|
- << restore_cursor
|
|
|
- << restore_bg
|
|
|
- << restore_fg;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- std::cout << progress_str << "\r\n";
|
|
|
- }
|
|
|
- std::flush(std::cout);
|
|
|
-
|
|
|
- d->last_reported_progress = percentage;
|
|
|
-}
|
|
|
- /*}}}*/
|
|
|
-/*{{{*/
|
|
|
// This implements a racy version of pselect for those architectures
|
|
|
// that don't have a working implementation.
|
|
|
// FIXME: Probably can be removed on Lenny+1
|
|
|
@@ -956,27 +914,6 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds,
|
|
|
}
|
|
|
/*}}}*/
|
|
|
|
|
|
-void pkgDPkgPM::SetupTerminalScrollArea(int nr_rows)
|
|
|
-{
|
|
|
- if(!d->fancy_progress_output)
|
|
|
- return;
|
|
|
-
|
|
|
- // scroll down a bit to avoid visual glitch when the screen
|
|
|
- // area shrinks by one row
|
|
|
- std::cout << "\n";
|
|
|
-
|
|
|
- // save cursor
|
|
|
- std::cout << "\033[s";
|
|
|
-
|
|
|
- // set scroll region (this will place the cursor in the top left)
|
|
|
- std::cout << "\033[1;" << nr_rows - 1 << "r";
|
|
|
-
|
|
|
- // restore cursor but ensure its inside the scrolling area
|
|
|
- std::cout << "\033[u";
|
|
|
- static const char *move_cursor_up = "\033[1A";
|
|
|
- std::cout << move_cursor_up;
|
|
|
- std::flush(std::cout);
|
|
|
-}
|
|
|
|
|
|
// DPkgPM::Go - Run the sequence /*{{{*/
|
|
|
// ---------------------------------------------------------------------
|
|
|
@@ -1334,8 +1271,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
|
|
|
_error->PushToStack();
|
|
|
if (tcgetattr(STDOUT_FILENO, &tt) == 0)
|
|
|
{
|
|
|
- ioctl(1, TIOCGWINSZ, (char *)&win);
|
|
|
- d->nr_terminal_rows = win.ws_row;
|
|
|
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win);
|
|
|
if (openpty(&master, &slave, NULL, &tt, &win) < 0)
|
|
|
{
|
|
|
_error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
|
|
|
@@ -1415,7 +1351,6 @@ bool pkgDPkgPM::Go(int OutStatusFd)
|
|
|
if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0)
|
|
|
_exit(100);
|
|
|
}
|
|
|
- SetupTerminalScrollArea(d->nr_terminal_rows);
|
|
|
|
|
|
/* No Job Control Stop Env is a magic dpkg var that prevents it
|
|
|
from using sigstop */
|
|
|
@@ -1424,6 +1359,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
|
|
|
cerr << "Could not exec dpkg!" << endl;
|
|
|
_exit(100);
|
|
|
}
|
|
|
+ d->progress->Started();
|
|
|
|
|
|
// apply ionice
|
|
|
if (_config->FindB("DPkg::UseIoNice", false) == true)
|
|
|
@@ -1510,14 +1446,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
|
|
|
|
|
|
signal(SIGHUP,old_SIGHUP);
|
|
|
|
|
|
- // reset scroll area
|
|
|
- SetupTerminalScrollArea(d->nr_terminal_rows + 1);
|
|
|
- if(d->fancy_progress_output)
|
|
|
- {
|
|
|
- // override the progress line (sledgehammer)
|
|
|
- static const char* clear_screen_below_cursor = "\033[J";
|
|
|
- std::cout << clear_screen_below_cursor;
|
|
|
- }
|
|
|
+ // tell the progress
|
|
|
+ d->progress->Finished();
|
|
|
|
|
|
if(master >= 0)
|
|
|
{
|
|
|
@@ -1556,8 +1486,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
|
|
|
CloseLog();
|
|
|
|
|
|
// dpkg is done at this point
|
|
|
- if(_config->FindB("DPkgPM::Progress", false) == true)
|
|
|
- SendTerminalProgress(100);
|
|
|
+ d->progress->StatusChanged("", PackagesDone, PackagesTotal);
|
|
|
|
|
|
if (pkgPackageManager::SigINTStop)
|
|
|
_error->Warning(_("Operation was interrupted before it could finish"));
|