fix: use runInShell=false for iperf3 binary execution and add logging
CI / Analyze & Test (push) Failing after 27s
CI / Analyze & Test (push) Failing after 27s
- Android toybox ash cannot exec ELF binaries even with -rwx permissions - runInShell: true wraps in /system/bin/sh -c which refuses ELF - runInShell: false calls execve() directly, bypassing sh - Added debugPrint logging to capture actual output in logcat
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:iperf3gui/domain/models/iperf3_result.dart';
|
import 'package:iperf3gui/domain/models/iperf3_result.dart';
|
||||||
import 'package:iperf3gui/domain/models/test_configuration.dart';
|
import 'package:iperf3gui/domain/models/test_configuration.dart';
|
||||||
|
|
||||||
/// Service that runs iperf3 via [Process.spawn] and captures output.
|
/// Service that runs iperf3 via [Process.start] and captures output.
|
||||||
class Iperf3Service {
|
class Iperf3Service {
|
||||||
final String _binaryPath;
|
final String _binaryPath;
|
||||||
|
|
||||||
@@ -17,31 +18,46 @@ class Iperf3Service {
|
|||||||
Future<Iperf3Result> run(TestConfiguration config) async {
|
Future<Iperf3Result> run(TestConfiguration config) async {
|
||||||
final args = config.toCliArgs();
|
final args = config.toCliArgs();
|
||||||
|
|
||||||
|
debugPrint(
|
||||||
|
'Iperf3Service: running $_binaryPath ${args.join(" ")}',
|
||||||
|
);
|
||||||
|
|
||||||
final process = await Process.start(
|
final process = await Process.start(
|
||||||
_binaryPath,
|
_binaryPath,
|
||||||
args,
|
args,
|
||||||
runInShell: true,
|
runInShell: false, // must execve directly — Android sh can't exec ELF binaries
|
||||||
);
|
);
|
||||||
|
|
||||||
final stdoutBuffer = <int>[];
|
final stdoutBuffer = <int>[];
|
||||||
final stderrBuffer = <int>[];
|
final stderrBuffer = <int>[];
|
||||||
|
|
||||||
final stdoutStream = process.stdout.transform(utf8.decoder).listen(
|
final stdoutStream = process.stdout.transform(utf8.decoder).listen(
|
||||||
(data) => stdoutBuffer.addAll(utf8.encode(data)),
|
(data) {
|
||||||
|
stdoutBuffer.addAll(utf8.encode(data));
|
||||||
|
debugPrint('Iperf3Service stdout: $data');
|
||||||
|
},
|
||||||
);
|
);
|
||||||
final stderrStream = process.stderr.transform(utf8.decoder).listen(
|
final stderrStream = process.stderr.transform(utf8.decoder).listen(
|
||||||
(data) => stderrBuffer.addAll(utf8.encode(data)),
|
(data) {
|
||||||
|
stderrBuffer.addAll(utf8.encode(data));
|
||||||
|
debugPrint('Iperf3Service stderr: $data');
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
await process.exitCode;
|
final exitCode = await process.exitCode;
|
||||||
|
|
||||||
await stdoutStream.cancel();
|
await stdoutStream.cancel();
|
||||||
await stderrStream.cancel();
|
await stderrStream.cancel();
|
||||||
|
|
||||||
final rawOutput = utf8.decode(stdoutBuffer) + utf8.decode(stderrBuffer);
|
final rawOutput = utf8.decode(stdoutBuffer) + utf8.decode(stderrBuffer);
|
||||||
|
|
||||||
|
debugPrint(
|
||||||
|
'Iperf3Service: finished with exit code $exitCode, output length ${rawOutput.length}',
|
||||||
|
);
|
||||||
|
|
||||||
return Iperf3Result(
|
return Iperf3Result(
|
||||||
rawOutput: rawOutput,
|
rawOutput: rawOutput,
|
||||||
exitCode: await process.exitCode,
|
exitCode: exitCode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user