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

📄 gbx_c_process.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************  CProcess.c  The process management class  (c) 2000-2004 Beno顃 Minisini <gambas@users.sourceforge.net>  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 1, or (at your option)  any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __GBX_C_PROCESS_C#include "gb_common.h"#include "gb_common_buffer.h"#include <signal.h>#include <fcntl.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#include "gbx_api.h"#include "gambas.h"#include "gbx_stream.h"#include "gb_array.h"#include "gbx_exec.h"#include "gbx_trace.h"#include "gbx_class.h"#include "gbx_watch.h"#include "gbx_c_array.h"#include "gbx_c_process.h"//#define DEBUG_MEextern char **environ;DECLARE_EVENT(EVENT_Read);DECLARE_EVENT(EVENT_Error);DECLARE_EVENT(EVENT_Kill);static CPROCESS *RunningProcessList = NULL;static int _pipe_child[2];static bool _init = FALSE;static void init_child(void);static void exit_child(void);static void callback_write(int fd, int type, CPROCESS *process){  #if 0  if (process->to_string)  {    int n = read(fd, COMMON_buffer, 256);    if (n > 0)    {      STRING_add(&process->result, COMMON_buffer, n);      CSTREAM_stream(process)->process.read_something = TRUE;      #ifdef DEBUG_ME      fprintf(stderr, "callback_write: result = '%s'\n", process->result);      #endif    }  }  else   #endif  if (!STREAM_eof(CSTREAM_stream(process))) //process->running &&    GB_Raise(process, EVENT_Read, 0);}static int callback_error(int fd, int type, CPROCESS *process){  /*fprintf(stderr, ">> Write\n"); fflush(stderr);*/  char buffer[256];  int n;  n = read(fd, buffer, sizeof(buffer));  if (n <= 0) /* || !process->running)*/  {    /*close(process->err);*/    return TRUE;  }  /*printf("callback_error: (%d) %.*s\n", n, n, buffer);*/  GB_Raise(process, EVENT_Error, 1,    GB_T_STRING, buffer, n);  return FALSE;      /*fprintf(stderr, "<< Write\n"); fflush(stderr);*/}static void update_stream(CPROCESS *process){  STREAM *stream = &process->ob.stream;  stream->type = &STREAM_process;  (*stream->type->open)(stream, NULL, 0, process);}static void init_process(CPROCESS *process){  process->watch = GB_WATCH_NONE;  process->in = process->out = process->err = -1;  update_stream(process);}static void exit_process(CPROCESS *_object){  /* Normalement impossible */  /*  if (THIS->running)  {    fprintf(stderr, "WARNING: CPROCESS_free: running ?\n");    stop_process(THIS);  }  */  #ifdef DEBUG_ME  fprintf(stderr, "exit_process: %p\n", _object);  #endif    if (THIS->in >= 0)  {    if (THIS->in != THIS->out)      close(THIS->in);    THIS->in = -1;  }  if (THIS->out >= 0)  {    GB_Watch(THIS->out, GB_WATCH_NONE, NULL, 0);    close(THIS->out);    THIS->out = -1;  }    if (THIS->err >= 0)  {    GB_Watch(THIS->err, GB_WATCH_NONE, NULL, 0);    close(THIS->err);    THIS->err = -1;  }   update_stream(THIS);}static void stop_process_after(CPROCESS *_object){  STREAM *stream;  //long long len;  #ifdef DEBUG_ME  fprintf(stderr, "stop_process_after: %p\n", _object);  #endif  /* Vidage du tampon d'erreur */  if (THIS->err >= 0)    while (callback_error(THIS->err, 0, THIS) == 0);    /* Vidage du tampon de sortie */  if (THIS->out >= 0)  {    stream = CSTREAM_stream(THIS);    while (!STREAM_eof(stream))    {      stream->process.read_something = FALSE;      callback_write(THIS->out, 0, THIS);      //GB_Raise(THIS, EVENT_Read, 0);      if (!stream->process.read_something)        break;    }  }    GB_Raise(THIS, EVENT_Kill, 0);  exit_process(THIS);    GB_Detach(THIS);    /*printf("** stop_process_after\n");*/  //GB_Unref((void **)&_object); /* Ref du post */}static void stop_process(CPROCESS *process){  if (!process->running)    return;      #ifdef DEBUG_ME  fprintf(stderr, "stop_process: %p\n", process);  #endif  /*process->pid = -1;*/  /* Remove from running process list */  if (process->prev)    process->prev->next = process->next;  if (process->next)    process->next->prev = process->prev;  if (process == RunningProcessList)    RunningProcessList = process->next;  process->running = FALSE;  /*printf("** stop_process\n");*/    stop_process_after(process);    GB_Unref((void **)&process); /* Le processus ne tourne plus */    if (!RunningProcessList)    exit_child();}static void run_process(CPROCESS *process, int mode, void *cmd){  static const char *shell[] = { "sh", "-c", NULL, NULL };  int fdin[2], fdout[2], fderr[2];  pid_t pid;  char **argv;  CARRAY *array;  int n;  sigset_t sig, old;    /* for terminal */  /*int fd_master = -1;  int fd_slave;  char *slave = NULL;  struct termios termios_stdin;  struct termios termios_master;*/  init_child();    if (mode & PM_SHELL)  {    #ifdef DEBUG_ME    fprintf(stderr, "run_process %p: %s\n", process, (char *)cmd);    #endif    argv = (char **)shell;    argv[2] = (char *)cmd;    if (argv[2] == NULL || *argv[2] == 0)    {      /*stop_process(process, FALSE);*/      return;    }  }  else  {    array = (CARRAY *)cmd;    n = ARRAY_count(array->data);    if (n == 0)    {      /*stop_process(process, FALSE);*/      return;    }    ALLOC(&argv, sizeof(*argv) * (n + 1), "run_process");    memcpy(argv, array->data, sizeof(*argv) * n);    argv[n] = NULL;    #ifdef DEBUG_ME    {      int i;            fprintf(stderr, "run_process %p: ", process);      for (i = 0; i < n; i++)        fprintf(stderr, "%s ", argv[i]);      fprintf(stderr, "\n");    }    #endif  }  /*printf("** run_process\n");*/  GB_Ref(process); /* Process is running */  /* Adding to the running process list */  if (RunningProcessList)    RunningProcessList->prev = process;  process->next = RunningProcessList;  process->prev = NULL;  RunningProcessList = process;  process->running = TRUE;  #if 0  if (mode & PM_STRING)  {    process->to_string = TRUE;    process->result = NULL;    mode |= PM_READ;  }  #endif    #if 0  if (mode & PM_TERM)  {    fd_master = getpt();    if (fd_master < 0)      THROW_SYSTEM(errno, NULL);          grantpt(fd_master);    unlockpt(fd_master);        slave = ptsname(fd_master);    tcgetattr(STDIN_FILENO, &termios_stdin);  }  else  #endif  {    /* Create pipes */    if ((mode & PM_WRITE) && pipe(fdin) != 0)      THROW_SYSTEM(errno, NULL);      if ((mode & PM_READ) && (pipe(fdout) != 0 || pipe(fderr) != 0))      THROW_SYSTEM(errno, NULL);  }  /* Block SIGCHLD */  sigemptyset(&sig);  sigaddset(&sig, SIGCHLD);  sigprocmask(SIG_BLOCK, &sig, &old);  pid = fork();  if (pid == (-1))  {    stop_process(process);    sigprocmask(SIG_SETMASK, &old, &sig);    THROW_SYSTEM(errno, NULL);  }  if (pid)  {    process->pid = pid;    #ifdef DEBUG_ME    fprintf(stderr, "fork: pid = %d\n", pid);    #endif    /*printf("Running process %d\n", pid);    fflush(NULL);*/    #if 0    if (mode & PM_TERM)    {      tcgetattr(fd_master, &termios_master);      cfmakeraw(&termios_master);      //termios_master.c_lflag &= ~ECHO;      tcsetattr(fd_master, TCSANOW, &termios_master);    }    #endif        if (mode & PM_WRITE)    {      #if 0      if (mode & PM_TERM)      {        process->in = fd_master;      }      else      #endif      {        close(fdin[0]);        process->in = fdin[1];      }    }    if (mode & PM_READ)    {      #if 0      if (mode & PM_TERM)      {        process->out = fd_master;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -