@ -42,43 +42,42 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
wlr_log ( L_ERROR , " Unable to create pipe for fork " ) ;
wlr_log ( L_ERROR , " Unable to create pipe for fork " ) ;
}
}
pid_t pid ;
pid_t pid , child ;
pid_t * child = malloc ( sizeof ( pid_t ) ) ; // malloc'd so that Linux can avoid copying the process space
if ( ! child ) {
return cmd_results_new ( CMD_FAILURE , " exec_always " , " Unable to allocate child pid " ) ;
}
// Fork process
// Fork process
if ( ( pid = fork ( ) ) = = 0 ) {
if ( ( pid = fork ( ) ) = = 0 ) {
// Fork child process again
// Fork child process again
setsid ( ) ;
setsid ( ) ;
if ( ( * child = fork ( ) ) = = 0 ) {
close ( fd [ 0 ] ) ;
if ( ( child = fork ( ) ) = = 0 ) {
close ( fd [ 1 ] ) ;
execl ( " /bin/sh " , " /bin/sh " , " -c " , cmd , ( void * ) NULL ) ;
execl ( " /bin/sh " , " /bin/sh " , " -c " , cmd , ( void * ) NULL ) ;
// Not reached
_exit ( 0 ) ;
}
}
close ( fd [ 0 ] ) ;
ssize_t s = 0 ;
ssize_t s = 0 ;
while ( ( size_t ) s < sizeof ( pid_t ) ) {
while ( ( size_t ) s < sizeof ( pid_t ) ) {
s + = write ( fd [ 1 ] , ( ( uint8_t * ) child ) + s , sizeof ( pid_t ) - s ) ;
s + = write ( fd [ 1 ] , ( ( uint8_t * ) & child ) + s , sizeof ( pid_t ) - s ) ;
}
}
close ( fd [ 1 ] ) ;
close ( fd [ 1 ] ) ;
_exit ( 0 ) ; // Close child process
_exit ( 0 ) ; // Close child process
} else if ( pid < 0 ) {
} else if ( pid < 0 ) {
free ( child ) ;
close ( fd [ 0 ] ) ;
close ( fd [ 1 ] ) ;
return cmd_results_new ( CMD_FAILURE , " exec_always " , " fork() failed " ) ;
return cmd_results_new ( CMD_FAILURE , " exec_always " , " fork() failed " ) ;
}
}
close ( fd [ 1 ] ) ; // close write
close ( fd [ 1 ] ) ; // close write
ssize_t s = 0 ;
ssize_t s = 0 ;
while ( ( size_t ) s < sizeof ( pid_t ) ) {
while ( ( size_t ) s < sizeof ( pid_t ) ) {
s + = read ( fd [ 0 ] , ( ( uint8_t * ) child ) + s , sizeof ( pid_t ) - s ) ;
s + = read ( fd [ 0 ] , ( ( uint8_t * ) & child ) + s , sizeof ( pid_t ) - s ) ;
}
}
close ( fd [ 0 ] ) ;
close ( fd [ 0 ] ) ;
// cleanup child process
// cleanup child process
waitpid ( pid , NULL , 0 ) ;
waitpid ( pid , NULL , 0 ) ;
if ( * child > 0 ) {
if ( child > 0 ) {
wlr_log ( L_DEBUG , " Child process created with pid %d " , * child ) ;
wlr_log ( L_DEBUG , " Child process created with pid %d " , child ) ;
// TODO: add PID to active workspace
// TODO: add PID to active workspace
} else {
} else {
free ( child ) ;
return cmd_results_new ( CMD_FAILURE , " exec_always " ,
" Second fork() failed " ) ;
}
}
return cmd_results_new ( CMD_SUCCESS , NULL , NULL ) ;
return cmd_results_new ( CMD_SUCCESS , NULL , NULL ) ;