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
|
static_assert(PIPE_BUF >= sizeof(ChildError)); // PIPE_BUF may be bigger
|
||||||
#endif
|
#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
|
struct QProcessPoller
|
||||||
{
|
{
|
||||||
QProcessPoller(const QProcessPrivate &proc);
|
QProcessPoller(const QProcessPrivate &proc);
|
||||||
@ -262,7 +292,7 @@ struct QChildProcess
|
|||||||
if (!d->workingDirectory.isEmpty()) {
|
if (!d->workingDirectory.isEmpty()) {
|
||||||
workingDirectory = opendirfd(QFile::encodeName(d->workingDirectory));
|
workingDirectory = opendirfd(QFile::encodeName(d->workingDirectory));
|
||||||
if (workingDirectory < 0) {
|
if (workingDirectory < 0) {
|
||||||
d->setErrorAndEmit(QProcess::FailedToStart, "chdir: "_L1 + qt_error_string());
|
d->setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("chdir"));
|
||||||
d->cleanup();
|
d->cleanup();
|
||||||
|
|
||||||
// make sure our destructor does nothing
|
// make sure our destructor does nothing
|
||||||
@ -491,7 +521,7 @@ bool QProcessPrivate::openChannel(Channel &channel)
|
|||||||
if (channel.type == Channel::Normal) {
|
if (channel.type == Channel::Normal) {
|
||||||
// we're piping this channel to our own process
|
// we're piping this channel to our own process
|
||||||
if (qt_create_pipe(channel.pipe) != 0) {
|
if (qt_create_pipe(channel.pipe) != 0) {
|
||||||
setErrorAndEmit(QProcess::FailedToStart, "pipe: "_L1 + qt_error_string(errno));
|
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("pipe"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,7 +603,7 @@ bool QProcessPrivate::openChannel(Channel &channel)
|
|||||||
|
|
||||||
Q_PIPE pipe[2] = { -1, -1 };
|
Q_PIPE pipe[2] = { -1, -1 };
|
||||||
if (qt_create_pipe(pipe) != 0) {
|
if (qt_create_pipe(pipe) != 0) {
|
||||||
setErrorAndEmit(QProcess::FailedToStart, "pipe: "_L1 + qt_error_string(errno));
|
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("pipe"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sink->pipe[0] = pipe[0];
|
sink->pipe[0] = pipe[0];
|
||||||
@ -708,7 +738,7 @@ void QProcessPrivate::startProcess()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (qt_create_pipe(childStartedPipe) != 0) {
|
if (qt_create_pipe(childStartedPipe) != 0) {
|
||||||
setErrorAndEmit(QProcess::FailedToStart, "pipe: "_L1 + qt_error_string(errno));
|
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("pipe"));
|
||||||
cleanup();
|
cleanup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -778,31 +808,6 @@ void QProcessPrivate::startProcess()
|
|||||||
::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK);
|
::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
|
Q_NORETURN void
|
||||||
failChildProcess(const QProcessPrivate *d, const char *description, int code) noexcept
|
failChildProcess(const QProcessPrivate *d, const char *description, int code) noexcept
|
||||||
{
|
{
|
||||||
@ -1320,7 +1325,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
|
|||||||
{
|
{
|
||||||
AutoPipe startedPipe, pidPipe;
|
AutoPipe startedPipe, pidPipe;
|
||||||
if (!startedPipe || !pidPipe) {
|
if (!startedPipe || !pidPipe) {
|
||||||
setErrorAndEmit(QProcess::FailedToStart, "pipe: "_L1 + qt_error_string(errno));
|
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("pipe"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1359,7 +1364,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
|
|||||||
|
|
||||||
if (childPid == -1) {
|
if (childPid == -1) {
|
||||||
childProcess.cleanup();
|
childProcess.cleanup();
|
||||||
setErrorAndEmit(QProcess::FailedToStart, "fork: "_L1 + qt_error_string(savedErrno));
|
setErrorAndEmit(QProcess::FailedToStart, errorMessageForSyscall("fork", savedErrno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2884,7 +2884,8 @@ void tst_QProcess::detachedSetNonExistentWorkingDirectory()
|
|||||||
QCOMPARE(process.error(), QProcess::FailedToStart);
|
QCOMPARE(process.error(), QProcess::FailedToStart);
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user