@@ -22,24 +22,30 @@ internal actual suspend fun executeCommand(
2222 timeoutMillis : Long ,
2323 clock : Clock ,
2424): Pair <Int , String > = withContext(SdkDispatchers .IO ) {
25- val pipeFd = IntArray (2 )
26- if (pipe(pipeFd .refTo(0 )) != 0 ) {
25+ val pipeFds = IntArray (2 )
26+ if (pipe(pipeFds .refTo(0 )) != 0 ) {
2727 error(" Failed to create pipe" )
2828 }
29+ val (readFd, writeFd) = pipeFds
2930
3031 val pid = fork()
3132 if (pid == - 1 ) {
33+ close(readFd)
34+ close(writeFd)
3235 error(" Failed to fork" )
3336 }
3437
3538 if (pid == 0 ) {
3639 // Child process
37- close(pipeFd[ 0 ] ) // Close read end
40+ close(readFd ) // Close read end
3841
3942 // Pass stdout and stderr back to parent
40- dup2(pipeFd[1 ], STDOUT_FILENO )
41- dup2(pipeFd[1 ], STDERR_FILENO )
42- close(pipeFd[1 ])
43+ try {
44+ dup2(writeFd, STDOUT_FILENO )
45+ dup2(writeFd, STDERR_FILENO )
46+ } finally {
47+ close(writeFd)
48+ }
4349
4450 val shell = when (platformProvider.osInfo().family) {
4551 OsFamily .Windows -> " cmd.exe"
@@ -57,28 +63,31 @@ internal actual suspend fun executeCommand(
5763 }
5864
5965 // Parent process
60- close(pipeFd[1 ]) // Close write end
61-
62- val output = buildString {
63- val buffer = ByteArray (maxOutputLengthBytes.toInt())
64-
65- withTimeout(timeoutMillis) {
66- while (true ) {
67- val bytesRead = read(pipeFd[0 ], buffer.refTo(0 ), buffer.size.toULong()).toInt()
68- if (bytesRead <= 0 ) break
69-
70- append(buffer.decodeToString(0 , bytesRead))
71-
72- if (length > maxOutputLengthBytes) {
73- close(pipeFd[0 ])
74- throw CredentialsProviderException (" Process output exceeded limit of $maxOutputLengthBytes bytes" )
66+ close(writeFd) // Close write end
67+
68+ val output = try {
69+ buildString {
70+ val buffer = ByteArray (1024 )
71+ var totalBytesRead = 0L
72+
73+ withTimeout(timeoutMillis) {
74+ while (true ) {
75+ val nBytes = minOf(maxOutputLengthBytes - totalBytesRead, buffer.size.toLong())
76+ if (nBytes == 0L ) {
77+ throw CredentialsProviderException (" Process output exceeded limit of $maxOutputLengthBytes bytes" )
78+ }
79+
80+ val rc = read(readFd, buffer.refTo(0 ), nBytes.toULong()).toInt()
81+ if (rc <= 0 ) break
82+ totalBytesRead + = rc
83+ append(buffer.decodeToString(0 , rc))
7584 }
7685 }
7786 }
87+ } finally {
88+ close(readFd)
7889 }
7990
80- close(pipeFd[0 ])
81-
8291 memScoped {
8392 val status = alloc<IntVar >()
8493 waitpid(pid, status.ptr, 0 )
0 commit comments