⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbx_c_process.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -