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

📄 ipc.c

📁 -
💻 C
字号:
/* * $Id: ipc.c,v 1.15 1998/11/20 06:08:01 wessels Exp $ * * DEBUG: section 54    Interprocess Communication * AUTHOR: Duane Wessels * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"static const char *hello_string = "hi there\n";#define HELLO_BUF_SZ 32static char hello_buf[HELLO_BUF_SZ];static intipcCloseAllFD(int prfd, int pwfd, int crfd, int cwfd){    if (prfd >= 0)	comm_close(prfd);    if (prfd != pwfd)	if (pwfd >= 0)	    comm_close(pwfd);    if (crfd >= 0)	comm_close(crfd);    if (crfd != cwfd)	if (cwfd >= 0)	    comm_close(cwfd);    return -1;}intipcCreate(int type, const char *prog, char *const args[], const char *name, int *rfd, int *wfd){    pid_t pid;    struct sockaddr_in CS;    struct sockaddr_in PS;    int crfd = -1;    int prfd = -1;    int cwfd = -1;    int pwfd = -1;    int fd;    int t1, t2, t3;    socklen_t len;    int tmp_s;#if HAVE_PUTENV    char *env_str;#endif    int x;#if HAVE_POLL && defined(_SQUID_OSF_)    assert(type != IPC_FIFO);#endif    if (rfd)	*rfd = -1;    if (wfd)	*wfd = -1;    if (type == IPC_TCP_SOCKET) {	crfd = cwfd = comm_open(SOCK_STREAM,	    0,	    local_addr,	    0,	    COMM_NOCLOEXEC,	    name);	prfd = pwfd = comm_open(SOCK_STREAM,	    0,			/* protocol */	    local_addr,	    0,			/* port */	    0,			/* blocking */	    name);    } else if (type == IPC_UDP_SOCKET) {	crfd = cwfd = comm_open(SOCK_DGRAM,	    0,	    local_addr,	    0,	    COMM_NOCLOEXEC,	    name);	prfd = pwfd = comm_open(SOCK_DGRAM,	    0,	    local_addr,	    0,	    0,	    name);    } else if (type == IPC_FIFO) {	int p2c[2];	int c2p[2];	if (pipe(p2c) < 0) {	    debug(50, 0) ("ipcCreate: pipe: %s\n", xstrerror());	    return -1;	}	if (pipe(c2p) < 0) {	    debug(50, 0) ("ipcCreate: pipe: %s\n", xstrerror());	    return -1;	}	fd_open(prfd = p2c[0], FD_PIPE, "IPC FIFO Parent Read");	fd_open(cwfd = p2c[1], FD_PIPE, "IPC FIFO Child Write");	fd_open(crfd = c2p[0], FD_PIPE, "IPC FIFO Child Read");	fd_open(pwfd = c2p[1], FD_PIPE, "IPC FIFO Parent Write");    } else {	assert(IPC_NONE);    }    debug(54, 3) ("ipcCreate: prfd FD %d\n", prfd);    debug(54, 3) ("ipcCreate: pwfd FD %d\n", pwfd);    debug(54, 3) ("ipcCreate: crfd FD %d\n", crfd);    debug(54, 3) ("ipcCreate: cwfd FD %d\n", cwfd);    if (crfd < 0) {	debug(54, 0) ("ipcCreate: Failed to create child FD.\n");	return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);    }    if (pwfd < 0) {	debug(54, 0) ("ipcCreate: Failed to create server FD.\n");	return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);    }    if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {	len = sizeof(PS);	memset(&PS, '\0', len);	if (getsockname(pwfd, (struct sockaddr *) &PS, &len) < 0) {	    debug(50, 0) ("ipcCreate: getsockname: %s\n", xstrerror());	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);	}	debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n",	    pwfd, inet_ntoa(PS.sin_addr), ntohs(PS.sin_port));	len = sizeof(CS);	memset(&CS, '\0', len);	if (getsockname(crfd, (struct sockaddr *) &CS, &len) < 0) {	    debug(50, 0) ("ipcCreate: getsockname: %s\n", xstrerror());	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);	}	debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n",	    crfd, inet_ntoa(CS.sin_addr), ntohs(CS.sin_port));    }    if (type == IPC_TCP_SOCKET) {	if (listen(crfd, 1) < 0) {	    debug(50, 1) ("ipcCreate: listen FD %d: %s\n", crfd, xstrerror());	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);	}	debug(54, 3) ("ipcCreate: FD %d listening...\n", crfd);    }    /* flush or else we get dup data if unbuffered_logs is set */    logsFlush();    if ((pid = fork()) < 0) {	debug(50, 1) ("ipcCreate: fork: %s\n", xstrerror());	return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);    }    if (pid > 0) {		/* parent */	/* close shared socket with child */	comm_close(crfd);	if (cwfd != crfd)	    comm_close(cwfd);	cwfd = crfd = -1;	if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {	    if (comm_connect_addr(pwfd, &CS) == COMM_ERROR)		return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);	}	memset(hello_buf, '\0', HELLO_BUF_SZ);	if (type == IPC_UDP_SOCKET)	    x = recv(prfd, hello_buf, HELLO_BUF_SZ, 0);	else	    x = read(prfd, hello_buf, HELLO_BUF_SZ);	if (x < 0) {	    debug(50, 0) ("ipcCreate: PARENT: hello read test failed\n");	    debug(50, 0) ("--> read: %s\n", xstrerror());	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);	} else if (strcmp(hello_buf, hello_string)) {	    debug(54, 0) ("ipcCreate: PARENT: hello read test failed\n");	    debug(54, 0) ("--> got '%s'\n", rfc1738_escape(hello_buf));	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);	}	commSetTimeout(prfd, -1, NULL, NULL);	commSetNonBlocking(prfd);	commSetNonBlocking(pwfd);	if (rfd)	    *rfd = prfd;	if (wfd)	    *wfd = pwfd;	fd_table[prfd].flags.ipc = 1;	fd_table[pwfd].flags.ipc = 1;	return pwfd;    }    /* child */    no_suid();			/* give up extra priviliges */    /* close shared socket with parent */    close(prfd);    if (pwfd != prfd)	close(pwfd);    pwfd = prfd = -1;    if (type == IPC_TCP_SOCKET) {	debug(54, 3) ("ipcCreate: calling accept on FD %d\n", crfd);	if ((fd = accept(crfd, NULL, NULL)) < 0) {	    debug(50, 0) ("ipcCreate: FD %d accept: %s\n", crfd, xstrerror());	    _exit(1);	}	debug(54, 3) ("ipcCreate: CHILD accepted new FD %d\n", fd);	close(crfd);	cwfd = crfd = fd;    } else if (type == IPC_UDP_SOCKET) {	if (comm_connect_addr(crfd, &PS) == COMM_ERROR)	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);    }    if (type == IPC_UDP_SOCKET) {	x = send(cwfd, hello_string, strlen(hello_string), 0);	if (x < 0) {	    debug(50, 0) ("sendto FD %d: %s\n", cwfd, xstrerror());	    debug(50, 0) ("ipcCreate: CHILD: hello write test failed\n");	    _exit(1);	}    } else {	if (write(cwfd, hello_string, strlen(hello_string)) < 0) {	    debug(50, 0) ("write FD %d: %s\n", cwfd, xstrerror());	    debug(50, 0) ("ipcCreate: CHILD: hello write test failed\n");	    _exit(1);	}    }#if HAVE_PUTENV    env_str = xcalloc((tmp_s = strlen(Config.debugOptions) + 32), 1);    snprintf(env_str, tmp_s, "SQUID_DEBUG=%s", Config.debugOptions);    putenv(env_str);#endif    /*     * This double-dup stuff avoids problems when one of      *  crfd, cwfd, or debug_log are in the rage 0-2.     */    do {	x = open(_PATH_DEVNULL, 0, 0444);	commSetCloseOnExec(x);    } while (x < 3);    t1 = dup(crfd);    t2 = dup(cwfd);    t3 = dup(fileno(debug_log));    assert(t1 > 2 && t2 > 2 && t3 > 2);    close(crfd);    close(cwfd);    close(fileno(debug_log));    dup2(t1, 0);    dup2(t2, 1);    dup2(t3, 2);    close(t1);    close(t2);    close(t3);#if HAVE_SETSID    setsid();#endif    execvp(prog, args);    debug(50, 0) ("ipcCreate: %s: %s\n", prog, xstrerror());    _exit(1);    return 0;}

⌨️ 快捷键说明

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