popen.c
上传用户:tjescc
上传日期:2021-02-23
资源大小:419k
文件大小:5k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) Michel Arboi 2002
  3.  *
  4.  *   This library is free software; you can redistribute it and/or
  5.  *   modify it under the terms of the GNU Library General Public
  6.  *   License as published by the Free Software Foundation; either
  7.  *   version 2 of the License, or (at your option) any later version.
  8.  *
  9.  *   This library is distributed in the hope that it will be useful,
  10.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  *   Library General Public License for more details.
  13.  *
  14.  *   You should have received a copy of the GNU Library General Public
  15.  *   License along with this library; if not, write to the Free
  16.  *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  *
  18.  */
  19. #include <includes.h>
  20. #ifndef RLIM_INFINITY
  21. #define RLIM_INFINITY (1024*1024*1024)
  22. #endif
  23. FILE*
  24. nessus_popen4(const char* cmd, char *const args[], pid_t* ppid, int inice)
  25. {
  26.   int fd, pipes[2];
  27.   pid_t son;
  28.   FILE *fp;
  29. #if DEBUG
  30.   int i;
  31.   fprintf(stderr, "nessus_popen: running %s -", cmd);
  32.   for (i = 0; args[i] != NULL; i ++)
  33.     fprintf(stderr, " %s", args[i]);
  34.   fputc('n', stderr);
  35. #endif
  36. #if 0
  37.   {
  38.     char buffer[1024], *p;
  39.     int n, sz = sizeof(buffer)-1;
  40.     n = snprintf(buffer, sz, "%s", cmd);
  41.     if (n > 0)
  42.       {
  43. p = buffer + n; 
  44. sz -= n;
  45.       }
  46.     for (i = 0; args[i] != NULL && sz > 0; i ++)
  47.       {
  48. n = snprintf(p, sz, " %s", args[i]);
  49. if (n > 0)
  50.   {
  51.     p = buffer + n; 
  52.     sz -= n;
  53.   }
  54.       }
  55.     *p ++ = '';
  56.     log_write("nessus_popen: %s", buffer);
  57.   }
  58. #endif
  59.  /* pipe() does not always work well on some OS */
  60.   if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipes) < 0)  
  61.     {
  62.       perror("socketpair");
  63.       return NULL;
  64.       /* filedes[0]  is  for  reading, filedes[1] is for writing. */
  65.     }
  66.   if ((son = fork()) < 0)
  67.     {
  68.       perror("fork");
  69.       close(pipes[0]); close(pipes[1]);
  70.       return NULL;
  71.     }
  72.   if (son == 0)
  73.     {
  74.       struct rlimit rl;
  75.       int i;
  76.       
  77.       /* Child process */
  78.       if (inice)
  79. {
  80.   errno = 0;
  81.   /* Some systems returned the new nice value => it may be < 0 */
  82.   if (nice(inice) < 0 && errno)
  83.     perror("nice");
  84. }
  85.       /* Memory usage: unlimited */
  86.       rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
  87. #ifdef RLIMIT_DATA
  88.       if (setrlimit(RLIMIT_DATA, &rl) < 0) perror("RLIMIT_DATA");
  89. #endif
  90. #ifdef RLIMIT_RSS
  91.       if (setrlimit(RLIMIT_RSS, &rl) < 0) perror("RLIMIT_RSS");
  92. #endif
  93. #ifdef RLIMIT_STACK
  94.       if (setrlimit(RLIMIT_STACK, &rl) < 0) perror("RLIMIT_STACK");
  95. #endif
  96.       /* We could probably limit the CPU time, but to which value? */
  97.       if ((fd = open("/dev/null", O_RDONLY)) < 0)
  98. {
  99.   perror("/dev/null");
  100.   exit(1);
  101. }
  102.       close(0);
  103.       if (dup2(fd, 0) < 0)
  104. {
  105.   perror("dup2");
  106.   exit(1);
  107. }
  108.       close(fd);
  109.       close(1);
  110.       close(2);
  111.       if (dup2(pipes[1], 1) < 0 ||
  112.   dup2(pipes[1], 2) < 0)
  113. {
  114.   /* Cannot print error as 2 is closed! */
  115.   exit(1);
  116. }
  117.       /* 
  118.        * Close all the fd's
  119.        */
  120.       for(i=3;i<256;i++)
  121.       {
  122.        close(i);
  123.       }
  124.       signal(SIGTERM, _exit);
  125.       signal(SIGPIPE, _exit);
  126.       execvp(cmd, args);
  127.       perror("execvp");
  128.       _exit(1);
  129.     }
  130.   close(pipes[1]);
  131.   if ((fp = fdopen(pipes[0], "r")) == NULL)
  132.     {
  133.       perror("fdopen");
  134.       close(pipes[0]);
  135.       return NULL;
  136.     }
  137.   if (ppid != NULL) *ppid = son;
  138.   return fp;      
  139. }
  140. FILE*
  141. nessus_popen(const char* cmd, char *const args[], pid_t* ppid)
  142. {
  143.   return nessus_popen4(cmd, args, ppid, 0);
  144. }
  145. int
  146. nessus_pclose(FILE* fp, pid_t pid)
  147. {
  148.   if (pid > 0)
  149.     if (waitpid(pid, NULL, WNOHANG) == 0)
  150.       if (kill(pid, SIGTERM) >= 0)
  151. if (waitpid(pid, NULL, WNOHANG) == 0)
  152.   {
  153.     usleep(400);
  154.     (void) kill(pid, SIGKILL);
  155.     (void) waitpid(pid, NULL, WNOHANG);
  156.   }
  157.   return fclose(fp);
  158. }
  159. /* Code taken from ptycall by Jordan Hrycaj */
  160. ExtFunc char** append_argv(char **argv, char   *opt)
  161. {
  162.   int argc, n ;
  163.   
  164.   /* special case */
  165.   if (opt == 0) {
  166.     if (argv == 0) 
  167.       (argv = emalloc(sizeof (char*))) [0] = 0 ;
  168.     return argv ;
  169.   }
  170.   
  171.   if (argv == 0) {
  172.     argc = 1 ;
  173.     argv = emalloc(2 * sizeof (char*));
  174.   } else {
  175.     /* calculate dim (argv) - 1 */
  176.     argc = 0 ;
  177.     while (argv [argc ++] != 0)
  178.       ;
  179.     /* append one more item */
  180.     n = (++ argc) * sizeof (char*) ;
  181.     argv = erealloc(argv, n) ;
  182.     argv [-- argc] = 0 ;
  183.   }
  184.   /* append one duplicated item before the NULL entry */
  185.   argv [-- argc] = estrdup(opt);
  186.   return argv ;
  187. }
  188. ExtFunc void destroy_argv(char **argv)
  189. {
  190.   int argc ;
  191.   if (argv == 0)
  192.     return ;
  193.   for (argc = 0; argv [argc] != 0; argc ++)
  194.     efree (&argv [argc]) ;
  195.   efree (&argv);
  196. }