📄 system.c
字号:
static char rcsid[] = "system.c,v 1.49 1996/01/05 20:28:35 duane Exp";/* * system.c - system(3) routines for Essence system. * * DEBUG: section 82, level 1 Common utilities system(3) routines * * Darren Hardy, hardy@cs.colorado.edu, February 1994 * * ---------------------------------------------------------------------- * Copyright (c) 1994, 1995. All rights reserved. * * The Harvest software was developed by the Internet Research Task * Force Research Group on Resource Discovery (IRTF-RD): * * Mic Bowman of Transarc Corporation. * Peter Danzig of the University of Southern California. * Darren R. Hardy of the University of Colorado at Boulder. * Udi Manber of the University of Arizona. * Michael F. Schwartz of the University of Colorado at Boulder. * Duane Wessels of the University of Colorado at Boulder. * * This copyright notice applies to software in the Harvest * ``src/'' directory only. Users should consult the individual * copyright notices in the ``components/'' subdirectories for * copyright information about other software bundled with the * Harvest source code distribution. * * TERMS OF USE * * The Harvest software may be used and re-distributed without * charge, provided that the software origin and research team are * cited in any use of the system. Most commonly this is * accomplished by including a link to the Harvest Home Page * (http://harvest.cs.colorado.edu/) from the query page of any * Broker you deploy, as well as in the query result pages. These * links are generated automatically by the standard Broker * software distribution. * * The Harvest software is provided ``as is'', without express or * implied warranty, and with no support nor obligation to assist * in its use, correction, modification or enhancement. We assume * no liability with respect to the infringement of copyrights, * trade secrets, or any patents, and are not responsible for * consequential damages. Proper use of the Harvest software is * entirely the responsibility of the user. * * DERIVATIVE WORKS * * Users may make derivative works from the Harvest software, subject * to the following constraints: * * - You must include the above copyright notice and these * accompanying paragraphs in all forms of derivative works, * and any documentation and other materials related to such * distribution and use acknowledge that the software was * developed at the above institutions. * * - You must notify IRTF-RD regarding your distribution of * the derivative work. * * - You must clearly notify users that your are distributing * a modified version and not the original Harvest software. * * - Any derivative product is also subject to these copyright * and use restrictions. * * Note that the Harvest software is NOT in the public domain. We * retain copyright, as specified above. * * HISTORY OF FREE SOFTWARE STATUS * * Originally we required sites to license the software in cases * where they were going to build commercial products/services * around Harvest. In June 1995 we changed this policy. We now * allow people to use the core Harvest software (the code found in * the Harvest ``src/'' directory) for free. We made this change * in the interest of encouraging the widest possible deployment of * the technology. The Harvest software is really a reference * implementation of a set of protocols and formats, some of which * we intend to standardize. We encourage commercial * re-implementations of code complying to this set of standards. * */#include <stdlib.h>#include <unistd.h>#include <memory.h>#include <signal.h>#include <fcntl.h>#include <sys/socket.h>#include "util.h"#ifdef HAVE_SETRLIMIT#include <sys/time.h>#include <sys/resource.h>#endifstatic void redirect_stdout();static void redirect_stdin();/* * do_system() - calls system(3). */int do_system(cmd) char *cmd;{ Debug(82, 1, ("RUNNING as shell: %s\n", cmd)); return (system(cmd));}/* * run_cmd() - simplified system(3). Parses the command, will redirect * stdout and then fork/exec() to save a sh process. */int run_cmd(cmd) char *cmd;{ int pid, status = 0; Debug(82, 1, ("run_cmd: RUNNING: %s\n", cmd));/* * PURFIY: * use fork() here instead of vfork(). With vfork parent and child * share memory space. In the child we strdup a bunch of argv's * which would otherwise never get free'd causing a memory leak in * the parent. */ if ((pid = fork()) < 0) { log_errno("run_cmd: fork"); return (1); } if (pid == 0) { /* child */ char *argv[64], buf[BUFSIZ]; int i; memset(argv, '\0', sizeof(char *) * 64); parse_argv(argv, cmd); for (i = 0; argv[i] != NULL; i++) { if (argv[i][0] == '>' && argv[i + 1] != NULL) { argv[i] = NULL; redirect_stdout(argv[++i]); } if (argv[i][0] == '<' && argv[i + 1] != NULL) { argv[i] = NULL; redirect_stdin(argv[++i]); } } execvp(argv[0], argv); sprintf(buf, "execvp: %s", argv[0]); log_errno(buf); _exit(1); } /* parent */ (void) waitpid(pid, &status, (int) NULL); if (WIFSIGNALED(status)) return -1; return (WEXITSTATUS(status));}static void redirect_stdout(filename) char *filename;{ int fd; if (filename == NULL) return; if ((fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) { log_errno(filename); return; } close(1); dup2(fd, 1); /* make stdout */}static void redirect_stdin(filename) char *filename;{ int fd; if (filename == NULL) return; if ((fd = open(filename, O_RDONLY)) < 0) { log_errno(filename); return; } close(0); dup2(fd, 0); /* make stdin */}static int dsl_pid = -1;static int dsl_timeout = 0;/* * dsl_alarm_handler - We want to kill the dsl_pid process here. * The parent is blocked on the wait4 call until the child process * is killed. So, on the first pass through we send the child a * SIGTERM to kill it, then reset the alarm for 5 seconds. After * 5 seconds if the child has not died then we send it the uncatchable * SIGKILL to kill it for good. After the parent exits from wait4() * it will disable the alarm. */static void dsl_alarm_handler(){ if (dsl_timeout == 1) { (void) kill(dsl_pid, SIGKILL); } else { dsl_timeout = 1; (void) kill(dsl_pid, SIGTERM); alarm(5); }}/* * do_system_lifetime() - calls system(3). Only lives for lifetime seconds. * return 0 on error (if 'cmd' exceeds lifetime and must be killed). * return 1 on success */int do_system_lifetime(cmd, lifetime) char *cmd; int lifetime;{ int rc = 1; char *argv[64]; static char buf[BUFSIZ]; int i; Debug(82, 1, ("do_system_lifetime: RUNNING: %s\n", cmd)); Debug(82, 1, ("do_system_lifetime: Lifetime is %d seconds.\n", lifetime)); /* * PURFIY: * use fork() here instead of vfork(). With vfork parent and child * share memory space. In the child we strdup a bunch of argv's * which would otherwise never get free'd causing a memory leak in * the parent. */ if ((dsl_pid = fork()) < 0) { log_errno("fork"); return (0); } if (dsl_pid) { /* parent */ /* Set the alarm to lifetime seconds */ alarm(0); /* reset timer */ dsl_timeout = 0; signal(SIGALRM, dsl_alarm_handler); alarm(lifetime); /* start timer */ /* SIGALRM will NOT interrupt waitpid - kill child in handler */ (void) waitpid(dsl_pid, (int *) NULL, (int) NULL); /* reset the alarm */ alarm(0); signal(SIGALRM, SIG_DFL); /* if it timed out, then log what happened */ if (dsl_timeout) { Log("WARNING: Child process (pid %d) exceeded lifetime of %d seconds. Killed.\n", dsl_pid, lifetime); rc = 0; } return rc; } /* child process */ memset(argv, '\0', sizeof(char *) * 64); parse_argv(argv, cmd); for (i = 0; argv[i] != NULL; i++) { if (argv[i][0] == '>' && argv[i + 1] != NULL) { argv[i] = NULL; redirect_stdout(argv[++i]); } else if (argv[i][0] == '<' && argv[i + 1] != NULL) { argv[i] = NULL; redirect_stdin(argv[++i]); } }#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_CPU) { struct rlimit rlp; /* * CPU time isn't the same as real time; oh well * But we can use this as a hard limit anyway. */ rlp.rlim_cur = rlp.rlim_max = lifetime; (void) setrlimit(RLIMIT_CPU, &rlp); }#endif execvp(argv[0], argv); sprintf(buf, "execvp: %s", argv[0]); log_errno(buf); _exit(1); /* NOTREACHED */}/* * close_all_fds_except() - closes all of the file descriptors starting * with start, except the fds in e[] which is terminated by a seminal of -1. */void close_all_fds_except(start, e) int start, *e;{ int i, j, skip; Debug(82, 1, ("Closing all file descs starting with %d,except\n", start));#if defined(HAVE_GETDTABLESIZE) for (i = start; i < getdtablesize(); i++) {#elif defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) for (i = start; i < sysconf(_SC_OPEN_MAX); i++) {#elif defined(OPEN_MAX) for (i = start; i < OPEN_MAX; i++) {#else for (i = start; i < 64; i++) {#endif skip = 0; for (j = 0; e[j] != -1; j++) { if (i == e[j]) { skip = 1; break; } } if (skip == 0) { (void) close(i); } }}void close_all_fds(start) int start;{ int e[1]; e[0] = -1; close_all_fds_except(start, e);}/* * setsocket_linger - sets the LINGER time on the given socket. */void setsocket_linger(s, t) int s, t;{ struct linger l; l.l_onoff = 1; l.l_linger = t; if (setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &l, sizeof(l)) < 0) log_errno("setsockopt (SO_LINGER)");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -