summaryrefslogtreecommitdiffstats
path: root/src/libs/installer/adminauthorization_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/installer/adminauthorization_x11.cpp')
-rw-r--r--src/libs/installer/adminauthorization_x11.cpp66
1 files changed, 46 insertions, 20 deletions
diff --git a/src/libs/installer/adminauthorization_x11.cpp b/src/libs/installer/adminauthorization_x11.cpp
index 1146519d2..7068bb2c6 100644
--- a/src/libs/installer/adminauthorization_x11.cpp
+++ b/src/libs/installer/adminauthorization_x11.cpp
@@ -55,6 +55,7 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <errno.h>
#include <iostream>
@@ -130,10 +131,14 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
if (pipe(pipedData) != 0)
return false;
- int flags = ::fcntl(pipedData[0], F_GETFD);
+ int flags = ::fcntl(pipedData[0], F_GETFL);
if (flags != -1)
::fcntl(pipedData[0], F_SETFL, flags | O_NONBLOCK);
+ flags = ::fcntl(masterFD, F_GETFL);
+ if (flags != -1)
+ ::fcntl(masterFD, F_SETFL, flags | O_NONBLOCK);
+
pid_t child = fork();
if (child < -1) {
@@ -151,25 +156,36 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
::close(pipedData[1]);
QRegExp re(QLatin1String("[Pp]assword.*:"));
+ QByteArray data;
QByteArray errData;
- flags = ::fcntl(masterFD, F_GETFD);
int bytes = 0;
int errBytes = 0;
char buf[1024];
char errBuf[1024];
+ int status;
+ bool statusValid = false;
while (bytes >= 0) {
- int state;
- if (::waitpid(child, &state, WNOHANG) == -1)
+ const pid_t waitResult = ::waitpid(child, &status, WNOHANG);
+ if (waitResult == -1) {
break;
+ }
+ if (waitResult == child) {
+ statusValid = true;
+ break;
+ }
bytes = ::read(masterFD, buf, 1023);
+ if (bytes == -1 && errno == EAGAIN)
+ bytes = 0;
+ else if (bytes > 0)
+ data.append(buf, bytes);
errBytes = ::read(pipedData[0], errBuf, 1023);
if (errBytes > 0)
{
- errData.append(buf, errBytes);
+ errData.append(errBuf, errBytes);
errBytes=0;
}
if (bytes > 0) {
- const QString line = QString::fromLatin1(buf, bytes);
+ const QString line = QString::fromLatin1(data);
if (re.indexIn(line) != -1) {
const QString password = getPassword(parent);
if (password.isEmpty()) {
@@ -189,20 +205,28 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
if (bytes == 0)
::usleep(100000);
}
- if (!errData.isEmpty()) {
- printError(parent, QString::fromLocal8Bit(errData.constData()));
- return false;
+
+ while (true) {
+ errBytes = ::read(pipedData[0], errBuf, 1023);
+ if (errBytes == -1 && errno == EAGAIN) {
+ ::usleep(100000);
+ continue;
+ }
+
+ if (errBytes <= 0)
+ break;
+
+ errData.append(errBuf, errBytes);
}
- int status;
- child = ::wait(&status);
- const int exited = WIFEXITED(status);
- const int exitStatus = WEXITSTATUS(status);
- ::close(pipedData[1]);
- if (exited)
- return exitStatus == 0;
+ const bool success = statusValid && WIFEXITED(status) && WEXITSTATUS(status) == 0;
- return false;
+ if (!success && !errData.isEmpty()) {
+ printError(parent, QString::fromLocal8Bit(errData.constData()));
+ }
+
+ ::close(pipedData[0]);
+ return success;
}
// child process
@@ -229,7 +253,7 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
for (int i = 3; i < static_cast<int>(rlp.rlim_cur); ++i)
::close(i);
- char **argp = (char **) ::malloc(arguments.count() + 4 * sizeof(char *));
+ char **argp = (char **) ::malloc((arguments.count() + 4) * sizeof(char *));
QList<QByteArray> args;
args.push_back(SU_COMMAND);
args.push_back("-b");
@@ -245,8 +269,10 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
::unsetenv("LANG");
::unsetenv("LC_ALL");
- ::execv(SU_COMMAND, argp);
- _exit(0);
+ int exitStatus = 0;
+ if (::execv(SU_COMMAND, argp) == -1)
+ exitStatus = -errno;
+ _exit(exitStatus);
return false;
}
}