@@ -735,10 +735,45 @@ struct Pos c_spawn_options_default() {
735735 return (struct Pos ) { .tag = 0 , .obj = options , };
736736}
737737
738+ static void my_alloc_cb (uv_handle_t * handle , size_t suggested_size , uv_buf_t * buf ) {
739+ (void )handle ;
740+ buf -> base = malloc (suggested_size );
741+ buf -> len = suggested_size ;
742+ }
743+
744+ typedef struct {
745+ struct Pos handler ;
746+ } stdout_cb_closure_t ;
747+ void stdout_cb (uv_stream_t * stream , ssize_t nread , const uv_buf_t * buf ) {
748+ stdout_cb_closure_t * clos = (stdout_cb_closure_t * )(stream -> data );
749+ if (nread >= 0 ) {
750+ struct Pos chunk = c_bytearray_construct (nread , (uint8_t * )(buf -> base ));
751+ sharePositive (clos -> handler );
752+ sharePositive (chunk );
753+ run_Pos (clos -> handler , chunk );
754+ } else {
755+ uv_read_stop (stream );
756+ erasePositive (clos -> handler );
757+ free (clos );
758+ }
759+ }
760+ struct Pos c_spawn_options_on_stdout (struct Pos opts , struct Pos callback ) {
761+ uv_process_options_t * options = (uv_process_options_t * )opts .obj ;
762+ options -> stdio [1 ].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE ;
763+ uv_pipe_t * pipe = (uv_pipe_t * )malloc (sizeof (uv_pipe_t ));
764+ uv_pipe_init (uv_default_loop (), pipe , 1 );
765+ options -> stdio [1 ].data .stream = (uv_stream_t * )pipe ;
766+ stdout_cb_closure_t * clos = (stdout_cb_closure_t * )malloc (sizeof (stdout_cb_closure_t ));
767+ clos -> handler = callback ;
768+ pipe -> data = clos ;
769+ return opts ;
770+ }
771+
738772void on_close (uv_handle_t * handle ) {
739773 free (handle );
740774}
741775void on_exit (uv_process_t * proc , int64_t exit_status , int term_signal ) {
776+ (void )term_signal ; (void )exit_status ;
742777 char * * _args = (char * * )proc -> data ;
743778 if (_args ) {
744779 for (int i = 0 ; _args [i ] != NULL ; i ++ ) {
@@ -754,15 +789,16 @@ struct Pos c_spawn(struct Pos cmd, struct Pos args, struct Pos options) {
754789 uv_process_t * proc = (uv_process_t * )malloc (sizeof (uv_process_t ));
755790
756791 // command
757- opts -> file = (char * )c_bytearray_data (cmd );
792+ char * cmd_s = c_bytearray_into_nullterminated_string (cmd );
793+ opts -> file = cmd_s ;
758794
759795 // args
760796 int _argc = (int )((uint64_t * )args .obj )[2 ];
761797 char * * _args = (char * * )malloc ((2 + _argc ) * sizeof (char * ));
762798 struct Pos * _argv = (struct Pos * )(((uint64_t * )args .obj ) + 3 );
763- _args [0 ] = strdup ( opts -> file ) ;
799+ _args [0 ] = cmd_s ;
764800 for (int i = 0 ; i < _argc ; i ++ ) {
765- _args [i + 1 ] = strdup (( char * ) c_bytearray_data ( _argv [i ]) );
801+ _args [i + 1 ] = c_bytearray_into_nullterminated_string ( _argv [i ]);
766802 }
767803 erasePositive (args );
768804 _args [_argc + 1 ] = NULL ;
@@ -773,6 +809,10 @@ struct Pos c_spawn(struct Pos cmd, struct Pos args, struct Pos options) {
773809
774810 // spawn process
775811 int err = uv_spawn (uv_default_loop (), proc , opts );
812+
813+ if (opts -> stdio [1 ].data .stream )
814+ uv_read_start ((uv_stream_t * )(opts -> stdio [1 ].data .stream ), my_alloc_cb , stdout_cb );
815+
776816 erasePositive (options );
777817 if (err ) {
778818 printf ("%s\n" , uv_strerror (err ));
0 commit comments