@@ -13,6 +13,7 @@ in the source distribution for its full text.
1313#include <errno.h>
1414#include <fcntl.h>
1515#include <signal.h>
16+ #include <spawn.h>
1617#include <stdbool.h>
1718#include <stdio.h>
1819#include <stdlib.h>
@@ -28,6 +29,9 @@ in the source distribution for its full text.
2829#include "XUtils.h"
2930
3031
32+ // Helper to create a mutable string for argv arrays
33+ #define MUTABLE_STR (s ) (char[]){s}
34+
3135static const char * const TraceScreenFunctions [] = {"Search " , "Filter " , "AutoScroll " , "Stop Tracing " , "Done " , NULL };
3236
3337static const char * const TraceScreenKeys [] = {"F3" , "F4" , "F8" , "F9" , "Esc" };
@@ -78,45 +82,43 @@ bool TraceScreen_forkTracer(TraceScreen* this) {
7882 if (fcntl (fdpair [1 ], F_SETFL , O_NONBLOCK ) < 0 )
7983 goto err ;
8084
81- pid_t child = fork ();
82- if (child == -1 )
85+ pid_t child ;
86+ posix_spawnattr_t attr ;
87+ posix_spawnattr_init (& attr );
88+ posix_spawn_file_actions_t fa ;
89+ posix_spawn_file_actions_init (& fa );
90+ posix_spawn_file_actions_addclose (& fa , fdpair [0 ]);
91+ posix_spawn_file_actions_adddup2 (& fa , fdpair [1 ], STDOUT_FILENO );
92+ posix_spawn_file_actions_adddup2 (& fa , fdpair [1 ], STDERR_FILENO );
93+ posix_spawn_file_actions_addclose (& fa , fdpair [1 ]);
94+
95+ char buffer [32 ] = {0 };
96+ xSnprintf (buffer , sizeof (buffer ), "%d" , Process_getPid (this -> super .process ));
97+
98+ char * const * args ;
99+ #if defined(HTOP_FREEBSD ) || defined(HTOP_OPENBSD ) || defined(HTOP_NETBSD ) || defined(HTOP_DRAGONFLYBSD ) || defined(HTOP_SOLARIS )
100+ args = (char * const []){MUTABLE_STR ("truss" ), MUTABLE_STR ("-s" ), MUTABLE_STR ("512" ), MUTABLE_STR ("-p" ), buffer , NULL };
101+ #elif defined(HTOP_LINUX )
102+ args = (char * const []){MUTABLE_STR ("strace" ), MUTABLE_STR ("-T" ), MUTABLE_STR ("-tt" ), MUTABLE_STR ("-s" ), MUTABLE_STR ("512" ), MUTABLE_STR ("-p" ), buffer , NULL };
103+ #else
104+ args = NULL ;
105+ #endif
106+
107+ int spawn_ret = args ? posix_spawnp (& child , args [0 ], & fa , & attr , args , NULL ) : -1 ;
108+
109+ posix_spawnattr_destroy (& attr );
110+ posix_spawn_file_actions_destroy (& fa );
111+
112+ if (spawn_ret != 0 ) {
83113 goto err ;
84-
85- if (child == 0 ) {
86- close (fdpair [0 ]);
87-
88- dup2 (fdpair [1 ], STDOUT_FILENO );
89- dup2 (fdpair [1 ], STDERR_FILENO );
90- close (fdpair [1 ]);
91-
92- char buffer [32 ] = {0 };
93- xSnprintf (buffer , sizeof (buffer ), "%d" , Process_getPid (this -> super .process ));
94-
95- #if defined(HTOP_FREEBSD ) || defined(HTOP_OPENBSD ) || defined(HTOP_NETBSD ) || defined(HTOP_DRAGONFLYBSD ) || defined(HTOP_SOLARIS )
96- // Use of NULL in variadic functions must have a pointer cast.
97- // The NULL constant is not required by standard to have a pointer type.
98- execlp ("truss" , "truss" , "-s" , "512" , "-p" , buffer , (void * )NULL );
99-
100- // Should never reach here, unless execlp fails ...
101- const char * message = "Could not execute 'truss'. Please make sure it is available in your $PATH." ;
102- (void )! write (STDERR_FILENO , message , strlen (message ));
103- #elif defined(HTOP_LINUX )
104- execlp ("strace" , "strace" , "-T" , "-tt" , "-s" , "512" , "-p" , buffer , (void * )NULL );
105-
106- // Should never reach here, unless execlp fails ...
107- const char * message = "Could not execute 'strace'. Please make sure it is available in your $PATH." ;
108- (void )! write (STDERR_FILENO , message , strlen (message ));
109- #else // HTOP_DARWIN, HTOP_PCP == HTOP_UNSUPPORTED
110- const char * message = "Tracing unavailable on not supported system." ;
111- (void )! write (STDERR_FILENO , message , strlen (message ));
112- #endif
113-
114- exit (127 );
115114 }
116115
117116 FILE * fp = fdopen (fdpair [0 ], "r" );
118- if (!fp )
117+ if (!fp ) {
118+ kill (child , SIGTERM );
119+ waitpid (child , NULL , 0 );
119120 goto err ;
121+ }
120122
121123 close (fdpair [1 ]);
122124
0 commit comments