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

📄 pipespawn.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
字号:
#include "amanda.h"#include "pipespawn.h"#include "arglist.h"#include "clock.h"#include "util.h"char skip_argument[1];pid_t pipespawnv_passwd(char *prog, int pipedef,                  int *stdinfd, int *stdoutfd, int *stderrfd,                  char **my_argv);/* * this used to be a function in it's own write but became a wrapper around * pipespawnv to eliminate redundancy... */pid_tpipespawn(    char *	prog,    int		pipedef,    int *	stdinfd,    int *	stdoutfd,    int *	stderrfd,    ...){    va_list ap;    int argc = 0, i;    pid_t pid;    char **argv;    /* count args */    arglist_start(ap, stderrfd);    while(arglist_val(ap, char *) != NULL) {	argc++;    }    arglist_end(ap);    /*     * Create the argument vector.     */    arglist_start(ap, stderrfd);    argv = (char **)alloc((argc + 1) * SIZEOF(*argv));    i = 0;    while((argv[i] = arglist_val(ap, char *)) != NULL) {        if (argv[i] != skip_argument) {	    i++;        }    }    arglist_end(ap);    pid = pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, argv);    amfree(argv);    return pid;}pid_tpipespawnv(    char *	prog,    int		pipedef,    int *	stdinfd,    int *	stdoutfd,    int *	stderrfd,    char **	my_argv){    return pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd,	my_argv);}pid_tpipespawnv_passwd(    char *	prog,    int		pipedef,    int *	stdinfd,    int *	stdoutfd,    int *	stderrfd,    char **	my_argv){    int argc;    pid_t pid;    int i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];    char number[NUM_STR_SIZE];    char **arg;    char *e;    char **env;    char *cmdline;    char *quoted;    char **newenv;    char *passwdvar = NULL;    int  *passwdfd = NULL;    /*     * Log the command line and count the args.     */    if ((pipedef & PASSWD_PIPE) != 0) {	passwdvar = *my_argv++;	passwdfd  = (int *)*my_argv++;    }    memset(inpipe, -1, SIZEOF(inpipe));    memset(outpipe, -1, SIZEOF(outpipe));    memset(errpipe, -1, SIZEOF(errpipe));    memset(passwdpipe, -1, SIZEOF(passwdpipe));    argc = 0;    cmdline = stralloc(prog);    for(arg = my_argv; *arg != NULL; arg++) {	if (*arg != skip_argument) {	    argc++;	    quoted = quote_string(*arg);	    cmdline = vstrextend(&cmdline, " ", quoted, NULL);	    amfree(quoted);	}    }    dbprintf(_("Spawning \"%s\" in pipeline\n"), cmdline);    /*     * Create the pipes     */    if ((pipedef & STDIN_PIPE) != 0) {	if(pipe(inpipe) == -1) {	    error(_("error [open pipe to %s: %s]"), prog, strerror(errno));	    /*NOTREACHED*/	}    }    if ((pipedef & STDOUT_PIPE) != 0) {	if(pipe(outpipe) == -1) {	    error(_("error [open pipe to %s: %s]"), prog, strerror(errno));	    /*NOTREACHED*/	}    }    if ((pipedef & STDERR_PIPE) != 0) {	if(pipe(errpipe) == -1) {	    error(_("error [open pipe to %s: %s]"), prog, strerror(errno));	    /*NOTREACHED*/	}    }    if ((pipedef & PASSWD_PIPE) != 0) {	if(pipe(passwdpipe) == -1) {	    error(_("error [open pipe to %s: %s]"), prog, strerror(errno));	    /*NOTREACHED*/	}    }    /*     * Fork and set up the return or run the program.     */    switch(pid = fork()) {    case -1:	e = strerror(errno);	error(_("error [fork %s: %s]"), prog, e);	/*NOTREACHED*/    default:	/* parent process */	if ((pipedef & STDIN_PIPE) != 0) {	    aclose(inpipe[0]);		/* close input side of pipe */	    *stdinfd = inpipe[1];	}	if ((pipedef & STDOUT_PIPE) != 0) {	    aclose(outpipe[1]);		/* close output side of pipe */	    *stdoutfd = outpipe[0];	}	if ((pipedef & STDERR_PIPE) != 0) {	    aclose(errpipe[1]);		/* close output side of pipe */	    *stderrfd = errpipe[0];	}	if ((pipedef & PASSWD_PIPE) != 0) {	    aclose(passwdpipe[0]);	/* close input side of pipe */	    *passwdfd = passwdpipe[1];	}	break;    case 0:		/* child process */	if ((pipedef & STDIN_PIPE) != 0) {	    aclose(inpipe[1]);		/* close output side of pipe */	} else {	    inpipe[0] = *stdinfd;	}	if ((pipedef & STDOUT_PIPE) != 0) {	    aclose(outpipe[0]);		/* close input side of pipe */	} else {	    outpipe[1] = *stdoutfd;	}	if ((pipedef & STDERR_PIPE) != 0) {	    aclose(errpipe[0]);		/* close input side of pipe */	} else {	    errpipe[1] = *stderrfd;	}        if ((pipedef & PASSWD_PIPE) != 0) {             aclose(passwdpipe[1]);      /* close output side of pipe */        }	/*	 * Shift the pipes to the standard file descriptors as requested.	 */	if(dup2(inpipe[0], 0) == -1) {	    error(_("error [spawn %s: dup2 in: %s]"), prog, strerror(errno));	    /*NOTREACHED*/	}	if(dup2(outpipe[1], 1) == -1) {	    error(_("error [spawn %s: dup2 out: %s]"), prog, strerror(errno));	    /*NOTREACHED*/	}	if(dup2(errpipe[1], 2) == -1) {	    error(_("error [spawn %s: dup2 err: %s]"), prog, strerror(errno));	    /*NOTREACHED*/	}	/*	 * Get the "safe" environment.  If we are sending a password to	 * the child via a pipe, add the environment variable for that.	 */	env = safe_env();	if ((pipedef & PASSWD_PIPE) != 0) {	    for (i = 0; env[i] != NULL; i++)		(void)i; /* make lint happy and do nothing */		    newenv = (char **)alloc((i + 1 + 1) * SIZEOF(*newenv));	    g_snprintf(number, SIZEOF(number), "%d", passwdpipe[0]);	    newenv[0] = vstralloc(passwdvar, "=", number, NULL);	    for(i = 0; env[i] != NULL; i++)	    	newenv[i + 1] = env[i];	    newenv[i + 1] = NULL;	    amfree(env);	    env = newenv;	    safe_fd(passwdpipe[0], 1);	} else {	    safe_fd(-1, 0);	}	execve(prog, my_argv, env);	e = strerror(errno);	error(_("error [exec %s: %s]"), prog, e);	/*NOTREACHED*/    }    amfree(cmdline);    return pid;}

⌨️ 快捷键说明

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