- struct termios tt;
- struct winsize win;
- int master = -1;
- int slave = -1;
-
- // if tcgetattr does not return zero there was a error
- // and we do not do any pty magic
- _error->PushToStack();
- if (tcgetattr(STDOUT_FILENO, &tt) == 0)
- {
- ioctl(1, TIOCGWINSZ, (char *)&win);
- d->nr_terminal_rows = win.ws_row;
- if (openpty(&master, &slave, NULL, &tt, &win) < 0)
- {
- _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
- master = slave = -1;
- } else {
- struct termios rtt;
- rtt = tt;
- cfmakeraw(&rtt);
- rtt.c_lflag &= ~ECHO;
- rtt.c_lflag |= ISIG;
- // block SIGTTOU during tcsetattr to prevent a hang if
- // the process is a member of the background process group
- // http://www.opengroup.org/onlinepubs/000095399/functions/tcsetattr.html
- sigemptyset(&sigmask);
- sigaddset(&sigmask, SIGTTOU);
- sigprocmask(SIG_BLOCK,&sigmask, &original_sigmask);
- tcsetattr(0, TCSAFLUSH, &rtt);
- sigprocmask(SIG_SETMASK, &original_sigmask, 0);
- }
- }
- // complain only if stdout is either a terminal (but still failed) or is an invalid
- // descriptor otherwise we would complain about redirection to e.g. /dev/null as well.
- else if (isatty(STDOUT_FILENO) == 1 || errno == EBADF)
- _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?"));
-
- if (_error->PendingError() == true)
- _error->DumpErrors(std::cerr);
- _error->RevertToStack();
-
- // Fork dpkg
- pid_t Child;
- _config->Set("APT::Keep-Fds::",fd[1]);
- // send status information that we are about to fork dpkg
- if(OutStatusFd > 0) {
- ostringstream status;
- status << "pmstatus:dpkg-exec:"
- << (PackagesDone/float(PackagesTotal)*100.0)
- << ":" << _("Running dpkg")
- << endl;
- FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
- }
-
- Child = ExecFork();
- // This is the child