system/popen: Avoid copying FILE#3511
Conversation
Track popen streams in a small private list so pclose() can find the spawned shell pid without embedding a copied FILE object in the tracking container. This keeps the returned stream owned by fdopen()/fclose() and avoids depending on libc FILE layout details. Fixes apache#2937. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com>
|
@nightt5879 it would be nice to have some test coverage to test it too. |
Add a small popen test that opens two read streams, verifies their output, and closes the first stream before the second. This covers reading from the returned popen stream and exercises pclose lookup/removal when the stream is not the first entry in the tracking list. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com>
|
Thanks, I added a small The test opens two I verified the added test with:
The simulator run prints |
My bad, I looked only the first commit. So, everything is fine! |
Just to clarify: I added the additional commit after seeing your suggestion. |
| ****************************************************************************/ | ||
|
|
||
| static sem_t g_popen_sem = SEM_INITIALIZER(1); | ||
| static FAR struct popen_file_s *g_popen_files; |
There was a problem hiding this comment.
but it isn't good (or even worse) to add a global list to fix a minor issue.
Summary
Fixes #2937.
system/popenwas embedding a copiedFILEobject in its private tracking container and copying it back inpclose(). That depends on libcFILElayout details.This PR makes
popen()return the actual stream fromfdopen()and keeps a small privateFILE * -> pidtracking list sopclose()can find the spawned shell process without copyingFILE.Scope:
popen()modes.pclose()responsible for closing the stream and waiting for the shell pid.EINVALifpclose()cannot find the stream in the private popen list.Impact
popen()/pclose()no longer rely on libcFILEinternals.Testing
Host:
sim:nshChecks:
git diff --check: passcheckpatch.sh -g HEAD~1..HEAD: passsim:nshbuild withCONFIG_SYSTEM_POPEN=yandCONFIG_EXAMPLES_POPEN=y: passCC: popen.cSIM elf with dynamic libs archive in nuttx.tgzprintf 'popen\npoweroff\n' | timeout 30s ./nuttx: passpopen("help")output is readpclose()