QProcess/Unix: update the start error messages to be all similar
The user doesn't care if it happened in the parent process or in the child. Windows says "Process failed to start: %1" which is a bit nicer, but I'm not going to update to that. Change-Id: If974ba44f84ffc236e48fffd4e48457fac21b248 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
This commit is contained in:
parent
675d6fd558
commit
030c93add8
@ -189,6 +189,36 @@ static_assert(std::is_trivial_v<ChildError>);
|
||||
static_assert(PIPE_BUF >= sizeof(ChildError)); // PIPE_BUF may be bigger
|
||||
#endif
|
||||
|
||||
// we need an errno value to use to indicate the child process modifier threw,
|
||||
// something the regular operations shouldn't set.
|
||||
static constexpr int FakeErrnoForThrow = std::numeric_limits<int>::max();
|
||||
|
||||
static QString errorMessageForSyscall(QUtf8StringView fnName, int errnoCode = -1)
|
||||
{
|
||||
QString msg = qt_error_string(errnoCode);
|
||||
return QProcess::tr("Child process set up failed: %1: %2").arg(fnName, std::move(msg));
|
||||
}
|
||||
|
||||
static QString startFailureErrorMessage(ChildError &err, [[maybe_unused]] ssize_t bytesRead)
|
||||
{
|
||||
// ChildError is less than the POSIX pipe buffer atomic size, so the read
|
||||
// must not have been truncated
|
||||
Q_ASSERT(bytesRead == sizeof(err));
|
||||
|
||||
qsizetype len = qstrnlen(err.function, sizeof(err.function));
|
||||
const QUtf8StringView complement(err.function, len);
|
||||
if (err.code == FakeErrnoForThrow)
|
||||
return QProcess::tr("Child process modifier threw an exception: %1")
|
||||
.arg(complement);
|
||||
if (err.code == 0)
|
||||
return QProcess::tr("Child process modifier reported error: %1")
|
||||
.arg(complement);
|
||||
if (err.code < 0)
|
||||
return QProcess::tr("Child process modifier reported error: %1: %2")
|
||||
.arg(complement, qt_error_string(-err.code));
|
||||
return errorMessageForSyscall(complement, err.code);
|
||||
}
|
||||
|
||||
struct QProcessPoller
|
||||
{
|
||||
QProcessPoller(const QProcessPrivate &proc);
|
||||
@ -262,7 +292,7 @@ struct QChildProcess
|
||||
if (!d->workingDirectory.isEmpty()) {
|
||||
workingDirectory = opendirfd(QFile::encodeName(d->workingDirectory));
|
||||
if (workingDirectory < 0) {
|
||||
d->setErrorAndEmit(QProcess::FailedToStart, "chdir: "_L1 + qt_error_string());
|
||||
d->setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("chdir"));
|
||||
d->cleanup();
|
||||
|
||||
// make sure our destructor does nothing
|
||||
@ -491,7 +521,7 @@ bool QProcessPrivate::openChannel(Channel &channel)
|
||||
if (channel.type == Channel::Normal) {
|
||||
// we're piping this channel to our own process
|
||||
if (qt_create_pipe(channel.pipe) != 0) {
|
||||
setErrorAndEmit(QProcess::FailedToStart, "pipe: "_L1 + qt_error_string(errno));
|
||||
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("pipe"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -573,7 +603,7 @@ bool QProcessPrivate::openChannel(Channel &channel)
|
||||
|
||||
Q_PIPE pipe[2] = { -1, -1 };
|
||||
if (qt_create_pipe(pipe) != 0) {
|
||||
setErrorAndEmit(QProcess::FailedToStart, "pipe: "_L1 + qt_error_string(errno));
|
||||
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("pipe"));
|
||||
return false;
|
||||
}
|
||||
sink->pipe[0] = pipe[0];
|
||||
@ -708,7 +738,7 @@ void QProcessPrivate::startProcess()
|
||||
return;
|
||||
}
|
||||
if (qt_create_pipe(childStartedPipe) != 0) {
|
||||
setErrorAndEmit(QProcess::FailedToStart, "pipe: "_L1 + qt_error_string(errno));
|
||||
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("pipe"));
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
@ -778,31 +808,6 @@ void QProcessPrivate::startProcess()
|
||||
::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK);
|
||||
}
|
||||
|
||||
// we need an errno number to use to indicate the child process modifier threw,
|
||||
// something the regular operations shouldn't set.
|
||||
static constexpr int FakeErrnoForThrow = std::numeric_limits<int>::max();
|
||||
|
||||
static QString startFailureErrorMessage(ChildError &err, [[maybe_unused]] ssize_t bytesRead)
|
||||
{
|
||||
// ChildError is less than the POSIX pipe buffer atomic size, so the read
|
||||
// must not have been truncated
|
||||
Q_ASSERT(bytesRead == sizeof(err));
|
||||
|
||||
qsizetype len = qstrnlen(err.function, sizeof(err.function));
|
||||
const QUtf8StringView complement(err.function, len);
|
||||
if (err.code == FakeErrnoForThrow)
|
||||
return QProcess::tr("Child process modifier threw an exception: %1")
|
||||
.arg(complement);
|
||||
if (err.code == 0)
|
||||
return QProcess::tr("Child process modifier reported error: %1")
|
||||
.arg(complement);
|
||||
if (err.code < 0)
|
||||
return QProcess::tr("Child process modifier reported error: %1: %2")
|
||||
.arg(complement, qt_error_string(-err.code));
|
||||
return QProcess::tr("Child process set up failed: %1: %2")
|
||||
.arg(complement, qt_error_string(err.code));
|
||||
}
|
||||
|
||||
Q_NORETURN void
|
||||
failChildProcess(const QProcessPrivate *d, const char *description, int code) noexcept
|
||||
{
|
||||
@ -1320,7 +1325,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
|
||||
{
|
||||
AutoPipe startedPipe, pidPipe;
|
||||
if (!startedPipe || !pidPipe) {
|
||||
setErrorAndEmit(QProcess::FailedToStart, "pipe: "_L1 + qt_error_string(errno));
|
||||
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("pipe"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1359,7 +1364,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
|
||||
|
||||
if (childPid == -1) {
|
||||
childProcess.cleanup();
|
||||
setErrorAndEmit(QProcess::FailedToStart, "fork: "_L1 + qt_error_string(savedErrno));
|
||||
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("fork", savedErrno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2884,7 +2884,8 @@ void tst_QProcess::detachedSetNonExistentWorkingDirectory()
|
||||
QCOMPARE(process.error(), QProcess::FailedToStart);
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
QVERIFY2(process.errorString().startsWith("chdir:"), process.errorString().toLocal8Bit());
|
||||
QVERIFY2(process.errorString().contains(": chdir: "), process.errorString().toLocal8Bit());
|
||||
QVERIFY2(process.errorString().contains(qt_error_string(ENOENT)), process.errorString().toLocal8Bit());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user