]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/unlinkd.cc
3 * $Id: unlinkd.cc,v 1.57 2006/09/10 03:20:37 adrian Exp $
5 * DEBUG: section 2 Unlink Daemon
6 * AUTHOR: Duane Wessels
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
40 /* This is the external unlinkd process */
42 #define UNLINK_BUF_LEN 1024
45 main(int argc
, char *argv
[])
47 char buf
[UNLINK_BUF_LEN
];
53 open(_PATH_DEVNULL
, O_RDWR
);
55 while (fgets(buf
, UNLINK_BUF_LEN
, stdin
)) {
56 if ((t
= strchr(buf
, '\n')))
78 #else /* UNLINK_DAEMON */
80 #include "SquidTime.h"
83 /* This code gets linked to Squid */
85 static int unlinkd_wfd
= -1;
86 static int unlinkd_rfd
= -1;
91 #define UNLINKD_QUEUE_LIMIT 20
94 unlinkdUnlink(const char *path
)
99 static int queuelen
= 0;
101 if (unlinkd_wfd
< 0) {
102 debug_trap("unlinkdUnlink: unlinkd_wfd < 0");
108 * If the queue length is greater than our limit, then
109 * we pause for up to 100ms, hoping that unlinkd
110 * has some feedback for us. Maybe it just needs a slice
113 if (queuelen
>= UNLINKD_QUEUE_LIMIT
) {
118 * If there is at least one outstanding unlink request, then
119 * try to read a response. If there's nothing to read we'll
120 * get an EWOULDBLOCK or whatever. If we get a response, then
121 * decrement the queue size by the number of newlines read.
127 x
= read(unlinkd_rfd
, rbuf
, 511);
132 for (i
= 0; i
< x
; i
++)
136 assert(queuelen
>= 0);
141 assert(l
< MAXPATHLEN
);
142 xstrncpy(buf
, path
, MAXPATHLEN
);
144 x
= write(unlinkd_wfd
, buf
, l
);
147 debug(2, 1) ("unlinkdUnlink: write FD %d failed: %s\n",
148 unlinkd_wfd
, xstrerror());
152 debug(2, 1) ("unlinkdUnlink: FD %d only wrote %d of %d bytes\n",
158 statCounter
.unlink
.requests
++;
160 * Increment this syscalls counter here, even though the syscall
161 * is executed by the helper process. We try to be consistent
162 * in counting unlink operations.
164 statCounter
.syscalls
.disk
.unlinks
++;
173 if (unlinkd_wfd
> -1)
175 debugs(2, 1, "Closing unlinkd pipe on FD " << unlinkd_wfd
);
176 shutdown(unlinkd_wfd
, SD_BOTH
);
177 comm_close(unlinkd_wfd
);
179 if (unlinkd_wfd
!= unlinkd_rfd
)
180 comm_close(unlinkd_rfd
);
186 debugs(2, 0, "unlinkdClose: WARNING: unlinkd_wfd is " << unlinkd_wfd
);
190 if (WaitForSingleObject(hIpc
, 5000) != WAIT_OBJECT_0
) {
192 debugs(2, 1, "unlinkdClose: WARNING: (unlinkd," << pid
<< "d) didn't exit in 5 seconds");
204 debugs(2, 1, "Closing unlinkd pipe on FD " << unlinkd_wfd
);
206 file_close(unlinkd_wfd
);
208 if (unlinkd_wfd
!= unlinkd_rfd
)
209 file_close(unlinkd_rfd
);
224 args
[0] = "(unlinkd)";
227 #if USE_POLL && defined(_SQUID_OSF_)
228 /* pipes and poll() don't get along on DUNIX -DW */
230 #elif defined(_SQUID_MSWIN_)
231 /* select() will fail on a pipe */
234 /* We currently need to use FIFO.. see below */
237 Config
.Program
.unlinkd
,
245 fatal("Failed to create unlinkd subprocess");
249 slp
.tv_usec
= 250000;
251 select(0, NULL
, NULL
, NULL
, &slp
);
253 fd_note(unlinkd_wfd
, "squid -> unlinkd");
255 fd_note(unlinkd_rfd
, "unlinkd -> squid");
257 commSetTimeout(unlinkd_rfd
, -1, NULL
, NULL
);
259 commSetTimeout(unlinkd_wfd
, -1, NULL
, NULL
);
262 * unlinkd_rfd should already be non-blocking because of
263 * ipcCreate. We change unlinkd_wfd to blocking mode because
264 * we never want to lose an unlink request, and we don't have
265 * code to retry if we get EWOULDBLOCK. Unfortunately, we can
266 * do this only for the IPC_FIFO case.
268 assert(fd_table
[unlinkd_rfd
].flags
.nonblocking
);
270 if (FD_PIPE
== fd_table
[unlinkd_wfd
].type
)
271 commUnsetNonBlocking(unlinkd_wfd
);
273 debug(2, 1) ("Unlinkd pipe opened on FD %d\n", unlinkd_wfd
);
277 debug(2, 4) ("Unlinkd handle: 0x%x, PID: %d\n", (unsigned)hIpc
, pid
);
283 #endif /* ndef UNLINK_DAEMON */