* @brief Executor::executeBlocking blocking version of the executor, * takes input and presents it as stdin * @param app * @param args * @param input * @param process_out * @param process_err * @return * * Note: Returning error code instead of throwing to maintain compatibility * with the existing error handling pattern used throughout QtPass. */
| 221 | * with the existing error handling pattern used throughout QtPass. |
| 222 | */ |
| 223 | auto Executor::executeBlocking(const QString &app, const QStringList &args, |
| 224 | const QString &input, QString *process_out, |
| 225 | QString *process_err) -> int { |
| 226 | QProcess internal; |
| 227 | startProcessBlocking(internal, app, args); |
| 228 | if (!internal.waitForStarted(-1)) { |
| 229 | #ifdef QT_DEBUG |
| 230 | dbg() << "Process failed to start:" << app; |
| 231 | #endif |
| 232 | return -1; |
| 233 | } |
| 234 | if (!input.isEmpty()) { |
| 235 | QByteArray data = input.toUtf8(); |
| 236 | if (internal.write(data) != data.length()) { |
| 237 | #ifdef QT_DEBUG |
| 238 | dbg() << "Not all input written:" << app; |
| 239 | #endif |
| 240 | } |
| 241 | internal.closeWriteChannel(); |
| 242 | } |
| 243 | internal.waitForFinished(-1); |
| 244 | if (internal.exitStatus() == QProcess::NormalExit) { |
| 245 | QString pout = decodeAssumingUtf8(internal.readAllStandardOutput()); |
| 246 | QString perr = decodeAssumingUtf8(internal.readAllStandardError()); |
| 247 | if (process_out != nullptr) { |
| 248 | *process_out = pout; |
| 249 | } |
| 250 | if (process_err != nullptr) { |
| 251 | *process_err = perr; |
| 252 | } |
| 253 | return internal.exitCode(); |
| 254 | } |
| 255 | // Process failed to start or crashed; return -1 to indicate error. |
| 256 | // The calling code checks for non-zero exit codes for error handling. |
| 257 | return -1; |
| 258 | } |
| 259 | |
| 260 | /** |
| 261 | * @brief Executor::executeBlocking blocking version of the executor |
nothing calls this directly
no test coverage detected