📄 gbx_c_process.c
字号:
process->err = -1; } else #endif { close(fdout[1]); close(fderr[1]); process->out = fdout[0]; process->err = fderr[0]; } fcntl(process->err, F_SETFL, fcntl(process->err, F_GETFL) | O_NONBLOCK); GB_Watch(process->out, GB_WATCH_READ, (void *)callback_write, (long)process); if (process->err >= 0) GB_Watch(process->err, GB_WATCH_READ, (void *)callback_error, (long)process); } if ((mode & PM_SHELL) == 0) { FREE(&argv, "run_process"); } sigprocmask(SIG_SETMASK, &old, &sig); } else /* child */ { sigprocmask(SIG_SETMASK, &old, &sig); #if 0 if (mode & PM_TERM) { close(fd_master); setsid(); fd_slave = open(slave, O_RDWR); if (fd_slave < 0) exit(127); tcsetattr(fd_slave, TCSANOW, &termios_stdin); if (mode & PM_WRITE) { if (dup2(fd_slave, STDIN_FILENO) == -1) exit(127); } if (mode & PM_READ) { if ((dup2(fd_slave, STDOUT_FILENO) == -1) || (dup2(fd_slave, STDERR_FILENO) == -1)) exit(127); } } else #endif { if (mode & PM_WRITE) { close(fdin[1]); /*else fdin[0] = open("/dev/null", O_RDONLY);*/ if (dup2(fdin[0], STDIN_FILENO) == -1) exit(127); } if (mode & PM_READ) { close(fdout[0]); close(fderr[0]); /* else { fdout[1] = open("/dev/null", O_WRONLY); fderr[1] = fdout[1]; } */ if ((dup2(fdout[1], STDOUT_FILENO) == -1) || (dup2(fderr[1], STDERR_FILENO) == -1)) exit(127); } } execvp(argv[0], (char **)argv); //execve(argv[0], (char **)argv, environ); exit(127); } update_stream(process);}static void callback_child(int fd, int type, void *data){ int status; CPROCESS *process, *next; long buffer; /*old = signal(SIGCHLD, signal_child);*/ read(fd, (char *)&buffer, 1); #ifdef DEBUG_ME fprintf(stderr, "<< callback_child\n"); #endif for (process = RunningProcessList; process; ) { next = process->next; if (wait4(process->pid, &status, WNOHANG, NULL) == process->pid) { process->status = status; #ifdef DEBUG_ME fprintf(stderr, "Process %d has returned %d\n", process->pid, status); #endif /*printf("** signal_child\n");*/ //GB_Ref(process); stop_process(process); //stop_process_after(process); } process = next; } #ifdef DEBUG_ME fprintf(stderr, ">> callback_child\n"); #endif}static void signal_child(int sig){ #ifdef DEBUG_ME fprintf(stderr, "SIGCHLD\n"); #endif long buffer = 0; write(_pipe_child[1], &buffer, 1);}static void init_child(void){ if (_init) return; #ifdef DEBUG_ME fprintf(stderr, "init_child()\n"); #endif if (pipe(_pipe_child) != 0) ERROR_panic("Cannot create SIGCHLD pipes"); /* This may work only on Linux. Should use sigaction() instead! */ signal(SIGCHLD, signal_child); GB_Watch(_pipe_child[0], GB_WATCH_READ, (void *)callback_child, 0); _init = TRUE;}static void exit_child(void){ if (!_init) return; #ifdef DEBUG_ME fprintf(stderr, "exit_child()\n"); #endif GB_Watch(_pipe_child[0], GB_WATCH_NONE, NULL, 0); close(_pipe_child[0]); close(_pipe_child[1]); _init = FALSE;}PUBLIC CPROCESS *CPROCESS_create(int mode, void *cmd){ CPROCESS *process; /*printf("** CPROCESS_create <<<< \n");*/ OBJECT_new((void **)&process, CLASS_Process, "Process", OP ? (OBJECT *)OP : (OBJECT *)CP); init_process(process); run_process(process, mode, cmd); OBJECT_UNREF_KEEP((void **)&process, "CPROCESS_create"); /*printf("** CPROCESS_create >>>> \n");*/ return process;}/* Attention, l'objet Process est d閞閒閞enc閑 une fois la fonction termin閑 ! */PUBLIC void CPROCESS_wait_for(CPROCESS *process){ //sigset_t sig, old; //bool have_sigchld; int ret; #ifdef DEBUG_ME printf("Waiting for %d\n", process->pid); #endif /*sigemptyset(&sig); sigaddset(&sig, SIGCHLD); sigprocmask(SIG_BLOCK, &sig, &old); have_sigchld = sigismember(&old, SIGCHLD); if (have_sigchld) sigdelset(&old, SIGCHLD);*/ /*if (process->to_string) { while (process->running) WATCH_loop(); } else { while (process->running) WATCH_loop(); //sigsuspend(&old); }*/ GB_Ref(process); while (process->running) { //HOOK_DEFAULT(wait, WATCH_wait)(0); ret = WATCH_process(_pipe_child[0], process->out); if (ret == _pipe_child[0]) callback_child(_pipe_child[0], GB_WATCH_READ, 0); else if (ret == process->out) callback_write(process->out, GB_WATCH_READ, process); } GB_Unref((void **)&process); #if 0 { sigsuspend(&old); if (!process->running) break; #ifdef DEBUG_ME fprintf(stderr, "Waiting: %d\n", process->running); #endif sleep(10); } #endif /*if (have_sigchld) sigaddset(&old, SIGCHLD); sigprocmask(SIG_SETMASK, &old, NULL);*/ #ifdef DEBUG_ME printf("Got it !\n"); #endif}BEGIN_METHOD_VOID(CPROCESS_exit) while (RunningProcessList) stop_process(RunningProcessList); exit_child();END_METHODBEGIN_METHOD_VOID(CPROCESS_new) init_process(THIS);END_METHODBEGIN_METHOD_VOID(CPROCESS_free) #ifdef DEBUG_ME printf("CPROCESS_free %p\n", THIS); #endif exit_process(THIS); END_METHODBEGIN_PROPERTY(CPROCESS_id) GB_ReturnInt(THIS->pid);END_PROPERTYBEGIN_METHOD_VOID(CPROCESS_kill) if (!THIS->running) return; kill(THIS->pid, SIGKILL); CPROCESS_wait_for(THIS);END_METHODBEGIN_METHOD_VOID(CPROCESS_signal) if (!THIS->running) return; /* printf("Send SIGUSR1 to process %d\n", THIS->pid); fflush(NULL);*/ kill(THIS->pid, SIGUSR1);END_METHOD#if 0BEGIN_METHOD(CPROCESS_send, GB_STRING text) if (!THIS->running || THIS->in < 0) return; STREAM_write(&THIS->ob.stream, STRING(text), LENGTH(text));END_METHOD#endifBEGIN_PROPERTY(CPROCESS_state) if (THIS->running) GB_ReturnInteger(1); else { if (WIFEXITED(THIS->status)) GB_ReturnInteger(0); else GB_ReturnInteger(2); }END_PROPERTYBEGIN_PROPERTY(CPROCESS_value) int status; if (THIS->running) { GB_ReturnInteger(0); return; } status = THIS->status; if (WIFEXITED(status)) GB_ReturnInteger(WEXITSTATUS(status)); else if (WIFSIGNALED(status)) GB_ReturnInteger(WTERMSIG(status)); else GB_ReturnInteger(-1);END_PROPERTYPUBLIC GB_DESC NATIVE_Process[] ={ GB_DECLARE("Process", sizeof(CPROCESS)), GB_NOT_CREATABLE(), GB_INHERITS(".Stream"), GB_CONSTANT("Stopped", "i", 0), GB_CONSTANT("Running", "i", 1), GB_CONSTANT("Crashed", "i", 2), GB_PROPERTY_READ("Id", "i", CPROCESS_id), GB_PROPERTY_READ("Handle", "i", CPROCESS_id), GB_PROPERTY_READ("State", "i", CPROCESS_state), GB_PROPERTY_READ("Value", "i", CPROCESS_value), //GB_STATIC_METHOD("_init", NULL, CPROCESS_init, NULL), GB_STATIC_METHOD("_exit", NULL, CPROCESS_exit, NULL), GB_METHOD("_new", NULL, CPROCESS_new, NULL), GB_METHOD("_free", NULL, CPROCESS_free, NULL), GB_METHOD("Kill", NULL, CPROCESS_kill, NULL), GB_METHOD("Signal", NULL, CPROCESS_signal, NULL), //GB_METHOD("Send", NULL, CPROCESS_send, "(Input)s"), //GB_METHOD("_print", NULL, CPROCESS_send, "(Input)s"), GB_EVENT("Read", NULL, NULL, &EVENT_Read), GB_EVENT("Error", NULL, "(Error)s", &EVENT_Error), GB_EVENT("Kill", NULL, NULL, &EVENT_Kill), GB_END_DECLARE};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -