C 捕获子进程';带libuv的s stdout
我在用libuv。我已经读过了,但仍然无法解决如何捕获子进程的stdout,以便它在父进程中可用(但不能代替父进程的stdin) 我的代码当前为:C 捕获子进程';带libuv的s stdout,c,spawn,libuv,C,Spawn,Libuv,我在用libuv。我已经读过了,但仍然无法解决如何捕获子进程的stdout,以便它在父进程中可用(但不能代替父进程的stdin) 我的代码当前为: #include <stdio.h> #include <stdlib.h> #include "../../libuv/include/uv.h" uv_loop_t *loop; uv_process_t child_req; uv_process_options_t options; uv_pipe_t apipe;
#include <stdio.h>
#include <stdlib.h>
#include "../../libuv/include/uv.h"
uv_loop_t *loop;
uv_process_t child_req;
uv_process_options_t options;
uv_pipe_t apipe;
void on_child_exit(uv_process_t *req, int exit_status, int term_signal) {
fprintf(stderr, "Process exited with status %d, signal %d\n", exit_status, term_signal);
uv_close((uv_handle_t*) req, NULL);
}
uv_buf_t alloc_buffer(uv_handle_t *handle, size_t len) {
printf("alloc_buffer called\n");
uv_buf_t buf;
buf.base = malloc(len);
buf.len = len;
return buf;
}
void read_apipe(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
printf("read %li bytes from the child process\n", nread);
}
int main(int argc, char *argv[]) {
printf("spawn_test\n");
loop = uv_default_loop();
char* args[3];
args[0] = "dummy";
args[1] = NULL;
args[2] = NULL;
uv_pipe_init(loop, &apipe, 0);
uv_pipe_open(&apipe, 0);
options.stdio_count = 3;
uv_stdio_container_t child_stdio[3];
child_stdio[0].flags = UV_IGNORE;
child_stdio[1].flags = UV_INHERIT_STREAM;
child_stdio[1].data.stream = (uv_stream_t *) &apipe;
child_stdio[2].flags = UV_IGNORE;
options.stdio = child_stdio;
options.exit_cb = on_child_exit;
options.file = args[0];
options.args = args;
uv_read_start((uv_stream_t*)&apipe, alloc_buffer, read_apipe);
if (uv_spawn(loop, &child_req, options)) {
fprintf(stderr, "%s\n", uv_strerror(uv_last_error(loop)));
return 1;
}
return uv_run(loop, UV_RUN_DEFAULT);
}
#包括
#包括
#包括“../../libuv/include/uv.h”
uv_环_t*环;
uv_工艺_t子_要求;
紫外线处理选项;
紫外线管;
子项退出时无效(uv处理请求、int退出状态、int term信号){
fprintf(标准,“进程退出,状态为%d,信号为%d\n”,退出状态,术语为信号);
uv_关闭((uv_句柄*)请求,NULL);
}
紫外缓冲区(紫外手柄,大小透镜){
printf(“称为alloc_缓冲区的\n”);
紫外线照射;
buf.base=malloc(len);
buf.len=len;
返回buf;
}
无效读取apipe(uv\u流\u t*流、ssize\u t nread、uv\u buf\u t buf){
printf(“从子进程读取%li字节”,nread);
}
int main(int argc,char*argv[]){
printf(“繁殖测试”\n);
loop=uv_default_loop();
char*args[3];
args[0]=“虚拟”;
args[1]=NULL;
args[2]=NULL;
uv_管道_init(回路和apipe,0);
uv管道打开(&apipe,0);
options.stdio_count=3;
uv_stdio_container_u t child_stdio[3];
child_stdio[0]。标志=UV_忽略;
child_stdio[1]。flags=UV_INHERIT_STREAM;
child_stdio[1]。data.stream=(uv_stream_t*)和apipe;
child_stdio[2]。flags=UV_IGNORE;
options.stdio=child\u stdio;
options.exit_cb=在子项上_exit;
options.file=args[0];
options.args=args;
uv_读取_开始((uv_流_t*)和apipe、分配缓冲区、读取apipe);
if(uv_繁殖(循环和子_请求,选项)){
fprintf(stderr,“%s\n”,uv_strerror(uv_last_error(loop));
返回1;
}
返回uv_运行(循环,uv_运行默认值);
}
D.c:
#include <unistd.h>
#include <stdio.h>
int main() {
printf("child starting\n");
sleep(1);
printf("child running\n");
sleep(2);
printf("child ending\n");
return 0;
}
#include <unistd.h>
#include <stdio.h>
int main() {
printf("child starting\n");
fflush(stdout);
sleep(1);
printf("child running\n");
fflush(stdout);
sleep(2);
printf("child ending\n");
fflush(stdout);
return 0;
}
#包括
#包括
int main(){
printf(“子启动\n”);
睡眠(1);
printf(“子运行\n”);
睡眠(2);
printf(“子结尾\n”);
返回0;
}
我有一种烦人的感觉,我还不太了解libuv管道的意义。我找到了解决方案:
UV\u CREATE\u PIPE | UV\u READABLE\u PIPE
而不是UV\u INHERIT\u STREAM
uv\u spawn
之后调用uv\u read\u start
。我假设数据不会丢失,因为还没有调用uv_rundummy
到一次到达的所有输出,而不是三次到达(就像在命令行上那样)。dummy.c中的fflush
修复了此问题
#include <stdio.h>
#include <stdlib.h>
#include "../../libuv/include/uv.h"
uv_loop_t *loop;
uv_process_t child_req;
uv_process_options_t options;
uv_pipe_t apipe;
void on_child_exit(uv_process_t *req, int exit_status, int term_signal) {
fprintf(stderr, "Process exited with status %d, signal %d\n", exit_status, term_signal);
uv_close((uv_handle_t*) req, NULL);
}
uv_buf_t alloc_buffer(uv_handle_t *handle, size_t len) {
printf("alloc_buffer called, requesting a %lu byte buffer\n");
uv_buf_t buf;
buf.base = malloc(len);
buf.len = len;
return buf;
}
void read_apipe(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
printf("read %li bytes in a %lu byte buffer\n", nread, buf.len);
if (nread + 1 > buf.len) return;
buf.base[nread] = '\0'; // turn it into a cstring
printf("read: |%s|", buf.base);
}
int main(int argc, char *argv[]) {
printf("spawn_test\n");
loop = uv_default_loop();
char* args[3];
args[0] = "dummy";
args[1] = NULL;
args[2] = NULL;
uv_pipe_init(loop, &apipe, 0);
uv_pipe_open(&apipe, 0);
options.stdio_count = 3;
uv_stdio_container_t child_stdio[3];
child_stdio[0].flags = UV_IGNORE;
child_stdio[1].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
child_stdio[1].data.stream = (uv_stream_t *) &apipe;
child_stdio[2].flags = UV_IGNORE;
options.stdio = child_stdio;
options.exit_cb = on_child_exit;
options.file = args[0];
options.args = args;
if (uv_spawn(loop, &child_req, options)) {
fprintf(stderr, "%s\n", uv_strerror(uv_last_error(loop)));
return 1;
}
uv_read_start((uv_stream_t*)&apipe, alloc_buffer, read_apipe);
return uv_run(loop, UV_RUN_DEFAULT);
}
#包括
#包括
#包括“../../libuv/include/uv.h”
uv_环_t*环;
uv_工艺_t子_要求;
紫外线处理选项;
紫外线管;
子项退出时无效(uv处理请求、int退出状态、int term信号){
fprintf(标准,“进程退出,状态为%d,信号为%d\n”,退出状态,术语为信号);
uv_关闭((uv_句柄*)请求,NULL);
}
紫外缓冲区(紫外手柄,大小透镜){
printf(“调用alloc_缓冲区,请求%lu字节缓冲区\n”);
紫外线照射;
buf.base=malloc(len);
buf.len=len;
返回buf;
}
无效读取apipe(uv\u流\u t*流、ssize\u t nread、uv\u buf\u t buf){
printf(“在%lu字节缓冲区中读取%li字节,\n”,nread,buf.len);
如果(nread+1>buf.len)返回;
buf.base[nread]='\0';//将其转换为cstring
printf(“读取:|%s |”,基本单位);
}
int main(int argc,char*argv[]){
printf(“繁殖测试”\n);
loop=uv_default_loop();
char*args[3];
args[0]=“虚拟”;
args[1]=NULL;
args[2]=NULL;
uv_管道_init(回路和apipe,0);
uv管道打开(&apipe,0);
options.stdio_count=3;
uv_stdio_container_u t child_stdio[3];
child_stdio[0]。标志=UV_忽略;
child_stdio[1]。flags=UV_CREATE_PIPE | UV_READABLE_PIPE;
child_stdio[1]。data.stream=(uv_stream_t*)和apipe;
child_stdio[2]。flags=UV_IGNORE;
options.stdio=child\u stdio;
options.exit_cb=在子项上_exit;
options.file=args[0];
options.args=args;
if(uv_繁殖(循环和子_请求,选项)){
fprintf(stderr,“%s\n”,uv_strerror(uv_last_error(loop));
返回1;
}
uv_读取_开始((uv_流_t*)和apipe、分配缓冲区、读取apipe);
返回uv_运行(循环,uv_运行默认值);
}
D.c:
#include <unistd.h>
#include <stdio.h>
int main() {
printf("child starting\n");
sleep(1);
printf("child running\n");
sleep(2);
printf("child ending\n");
return 0;
}
#include <unistd.h>
#include <stdio.h>
int main() {
printf("child starting\n");
fflush(stdout);
sleep(1);
printf("child running\n");
fflush(stdout);
sleep(2);
printf("child ending\n");
fflush(stdout);
return 0;
}
#包括
#包括
int main(){
printf(“子启动\n”);
fflush(stdout);
睡眠(1);
printf(“子运行\n”);
fflush(stdout);
睡眠(2);
printf(“子结尾\n”);
fflush(stdout);
返回0;
}
查看他们如何在libuv单元测试中执行此操作:
- 不要呼叫
uv\u管道\u打开
- 儿童标准的标志:
UV_创建_管道| UV_可读_管道
- 儿童标准输出和标准输出的标志:
UV_创建_管道| UV_可写_管道
uv\u spawn
即使遇到错误也可能返回零,在这种情况下,您需要检查仅存在于Windows上的process.spawn\u error