[BACK]Return to shell_cmd.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libwrap

Annotation of src/lib/libwrap/shell_cmd.c, Revision 1.5.58.2

1.5.58.2! riz         1: /*     $NetBSD: shell_cmd.c,v 1.5.58.1 2012/04/23 16:48:54 riz Exp $   */
1.2       christos    2:
1.1       mrg         3:  /*
                      4:   * shell_cmd() takes a shell command after %<character> substitutions. The
                      5:   * command is executed by a /bin/sh child process, with standard input,
                      6:   * standard output and standard error connected to /dev/null.
1.4       simonb      7:   *
1.1       mrg         8:   * Diagnostics are reported through syslog(3).
1.4       simonb      9:   *
1.1       mrg        10:   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
                     11:   */
                     12:
1.2       christos   13: #include <sys/cdefs.h>
1.1       mrg        14: #ifndef lint
1.2       christos   15: #if 0
1.1       mrg        16: static char sccsid[] = "@(#) shell_cmd.c 1.5 94/12/28 17:42:44";
1.2       christos   17: #else
1.5.58.2! riz        18: __RCSID("$NetBSD: shell_cmd.c,v 1.5.58.1 2012/04/23 16:48:54 riz Exp $");
1.2       christos   19: #endif
1.1       mrg        20: #endif
                     21:
                     22: /* System libraries. */
                     23:
                     24: #include <sys/types.h>
                     25: #include <sys/param.h>
1.2       christos   26: #include <sys/wait.h>
1.1       mrg        27: #include <signal.h>
                     28: #include <stdio.h>
1.2       christos   29: #include <stdlib.h>
                     30: #include <unistd.h>
                     31: #include <fcntl.h>
1.1       mrg        32: #include <syslog.h>
                     33: #include <string.h>
                     34:
                     35: /* Local stuff. */
                     36:
                     37: #include "tcpd.h"
                     38:
                     39: /* Forward declarations. */
                     40:
1.2       christos   41: static void do_child __P((char *));
1.1       mrg        42:
                     43: /* shell_cmd - execute shell command */
                     44:
1.5.58.2! riz        45: void    shell_cmd(command)
        !            46: char   *command;
1.1       mrg        47: {
                     48:     int     child_pid;
                     49:     int     wait_pid;
                     50:
                     51:     /*
                     52:      * Most of the work is done within the child process, to minimize the
                     53:      * risk of damage to the parent.
                     54:      */
                     55:
                     56:     switch (child_pid = fork()) {
                     57:     case -1:                                   /* error */
                     58:        tcpd_warn("cannot fork: %m");
                     59:        break;
                     60:     case 00:                                   /* child */
                     61:        do_child(command);
                     62:        /* NOTREACHED */
                     63:     default:                                   /* parent */
                     64:        while ((wait_pid = wait((int *) 0)) != -1 && wait_pid != child_pid)
                     65:             /* void */ ;
                     66:     }
                     67: }
                     68:
                     69: /* do_child - exec command with { stdin, stdout, stderr } to /dev/null */
                     70:
1.5.58.2! riz        71: static void do_child(command)
        !            72: char   *command;
1.1       mrg        73: {
                     74:     int     tmp_fd;
                     75:
                     76:     /*
                     77:      * Systems with POSIX sessions may send a SIGHUP to grandchildren if the
                     78:      * child exits first. This is sick, sessions were invented for terminals.
                     79:      */
                     80:
                     81:     signal(SIGHUP, SIG_IGN);
                     82:
                     83:     /* Set up new stdin, stdout, stderr, and exec the shell command. */
                     84:
                     85:     for (tmp_fd = 0; tmp_fd < 3; tmp_fd++)
                     86:        (void) close(tmp_fd);
                     87:     if (open("/dev/null", 2) != 0) {
1.5       sommerfe   88:        tcpd_warn("open /dev/null: %m");
1.1       mrg        89:     } else if (dup(0) != 1 || dup(0) != 2) {
1.5       sommerfe   90:        tcpd_warn("dup: %m");
1.1       mrg        91:     } else {
                     92:        (void) execl("/bin/sh", "sh", "-c", command, (char *) 0);
1.5       sommerfe   93:        tcpd_warn("execl /bin/sh: %m");
1.1       mrg        94:     }
                     95:
                     96:     /* Something went wrong. We MUST terminate the child process. */
                     97:     _exit(0);
                     98: }

CVSweb <webmaster@jp.NetBSD.org>