~clint-fewbar/ubuntu/precise/squid3/ignore-sighup-early

« back to all changes in this revision

Viewing changes to src/ipc_win32.cc

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2010-05-04 11:15:49 UTC
  • mfrom: (1.3.1 upstream)
  • mto: (20.3.1 squeeze) (21.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20100504111549-1apjh2g5sndki4te
Tags: upstream-3.1.3
ImportĀ upstreamĀ versionĀ 3.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
1
/*
3
 
 * $Id: ipc_win32.cc,v 1.4.4.1 2008/02/17 19:34:44 serassio Exp $
 
2
 * $Id$
4
3
 *
5
4
 * DEBUG: section 54    Windows Interprocess Communication
6
5
 * AUTHOR: Andrey Shorin <tolsty@tushino.com>
22
21
 *  it under the terms of the GNU General Public License as published by
23
22
 *  the Free Software Foundation; either version 2 of the License, or
24
23
 *  (at your option) any later version.
25
 
 *  
 
24
 *
26
25
 *  This program is distributed in the hope that it will be useful,
27
26
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
28
27
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
28
 *  GNU General Public License for more details.
30
 
 *  
 
29
 *
31
30
 *  You should have received a copy of the GNU General Public License
32
31
 *  along with this program; if not, write to the Free Software
33
32
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
44
43
#endif
45
44
#include <process.h>
46
45
 
47
 
struct ipc_params
48
 
{
 
46
struct ipc_params {
49
47
    int type;
50
48
    int crfd;
51
49
    int cwfd;
52
 
 
53
 
    struct sockaddr_in PS;
 
50
    IpAddress local_addr;
 
51
    struct addrinfo PS;
54
52
    const char *prog;
55
53
    char **args;
56
54
};
57
55
 
58
 
struct thread_params
59
 
{
 
56
struct thread_params {
60
57
    int type;
61
58
    int rfd;
62
59
    int send_fd;
101
98
#if HAVE_PUTENV
102
99
    char *env_str;
103
100
    int tmp_s;
104
 
    env_str = (char *)xcalloc((tmp_s = strlen(Config.debugOptions) + 32), 1);
105
 
    snprintf(env_str, tmp_s, "SQUID_DEBUG=%s", Config.debugOptions);
 
101
    env_str = (char *)xcalloc((tmp_s = strlen(Debug::debugOptions) + 32), 1);
 
102
    snprintf(env_str, tmp_s, "SQUID_DEBUG=%s", Debug::debugOptions);
106
103
    putenv(env_str);
107
104
#endif
108
105
}
109
106
 
110
107
pid_t
111
 
ipcCreate(int type, const char *prog, const char *const args[], const char *name, int *rfd, int *wfd, void **hIpc)
 
108
ipcCreate(int type, const char *prog, const char *const args[], const char *name, IpAddress &local_addr, int *rfd, int *wfd, void **hIpc)
112
109
{
113
110
    unsigned long thread;
114
111
 
118
115
    DWORD ecode = 0;
119
116
    pid_t pid;
120
117
 
121
 
    struct sockaddr_in CS;
 
118
    IpAddress tmp_addr;
 
119
    struct addrinfo *aiCS = NULL;
 
120
    struct addrinfo *aiPS = NULL;
122
121
 
123
 
    struct sockaddr_in PS;
124
122
    int crfd = -1;
125
123
    int prfd = -1;
126
124
    int cwfd = -1;
127
125
    int pwfd = -1;
128
 
    socklen_t len;
129
126
    int x;
130
127
 
131
128
    requirePathnameExists(name, prog);
149
146
        crfd = cwfd = comm_open(SOCK_STREAM,
150
147
                                IPPROTO_TCP,
151
148
                                local_addr,
152
 
                                0,
153
149
                                COMM_NOCLOEXEC,
154
150
                                name);
155
151
        prfd = pwfd = comm_open(SOCK_STREAM,
156
152
                                IPPROTO_TCP,    /* protocol */
157
153
                                local_addr,
158
 
                                0,                      /* port */
159
154
                                0,                      /* blocking */
160
155
                                name);
161
156
    } else if (type == IPC_UDP_SOCKET) {
162
157
        crfd = cwfd = comm_open(SOCK_DGRAM,
163
158
                                IPPROTO_UDP,
164
159
                                local_addr,
165
 
                                0,
166
160
                                COMM_NOCLOEXEC,
167
161
                                name);
168
162
        prfd = pwfd = comm_open(SOCK_DGRAM,
169
163
                                IPPROTO_UDP,
170
164
                                local_addr,
171
165
                                0,
172
 
                                0,
173
166
                                name);
174
167
    } else if (type == IPC_FIFO) {
175
168
        debugs(54, 0, "ipcCreate: " << prog << ": use IPC_TCP_SOCKET instead of IP_FIFO on Windows");
199
192
        return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
200
193
    }
201
194
 
 
195
// AYJ: these flags should be neutral, but if not IPv6 version needs adding
202
196
    if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {
203
 
        len = sizeof(PS);
204
 
        memset(&PS, '\0', len);
205
 
 
206
 
        if (getsockname(pwfd, (struct sockaddr *) &PS, &len) < 0) {
207
 
            debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
208
 
            return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
209
 
        }
210
 
 
211
 
        debugs(54, 3, "ipcCreate: FD " << pwfd << " sockaddr " << inet_ntoa(PS.sin_addr) << ":" << ntohs(PS.sin_port));
212
 
        len = sizeof(CS);
213
 
        memset(&CS, '\0', len);
214
 
 
215
 
        if (getsockname(crfd, (struct sockaddr *) &CS, &len) < 0) {
216
 
            debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
217
 
            return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
218
 
        }
219
 
 
220
 
        debugs(54, 3, "ipcCreate: FD " << crfd << " sockaddr " << inet_ntoa(CS.sin_addr) << ":" << ntohs(CS.sin_port));
 
197
 
 
198
        tmp_addr.InitAddrInfo(aiPS);
 
199
 
 
200
        if (getsockname(pwfd, aiPS->ai_addr, &(aiPS->ai_addrlen) ) < 0) {
 
201
            debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
 
202
            return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
 
203
        }
 
204
 
 
205
        tmp_addr = *aiPS;
 
206
 
 
207
        debugs(54, 3, "ipcCreate: FD " << pwfd << " sockaddr " << tmp_addr );
 
208
 
 
209
        tmp_addr.InitAddrInfo(aiCS);
 
210
 
 
211
        if (getsockname(crfd, aiCS->ai_addr, &(aiCS->ai_addrlen) ) < 0) {
 
212
            debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
 
213
            return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
 
214
        }
 
215
 
 
216
        tmp_addr.SetEmpty();
 
217
        tmp_addr = *aiCS;
 
218
 
 
219
        debugs(54, 3, "ipcCreate: FD " << crfd << " sockaddr " << tmp_addr );
221
220
    }
222
221
 
223
222
    if (type == IPC_TCP_SOCKET) {
238
237
 
239
238
    params.cwfd = cwfd;
240
239
 
241
 
    params.PS = PS;
 
240
    params.PS = *aiPS;
 
241
 
 
242
    params.local_addr = local_addr;
242
243
 
243
244
    params.prog = prog;
244
245
 
251
252
        return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
252
253
    }
253
254
 
254
 
    if (comm_connect_addr(pwfd, &CS) == COMM_ERROR) {
 
255
    /* NP: tmp_addr was left with eiether empty or aiCS in IpAddress format */
 
256
    if (comm_connect_addr(pwfd, tmp_addr) == COMM_ERROR) {
255
257
        CloseHandle((HANDLE) thread);
256
258
        return ipcCloseAllFD(prfd, pwfd, -1, -1);
257
259
    }
360
362
ipc_thread_1(void *in_params)
361
363
{
362
364
    int t1, t2, t3, retval = -1;
363
 
    int p2c[2] =
364
 
        {-1, -1};
365
 
    int c2p[2] =
366
 
        {-1, -1};
 
365
    int p2c[2] = {-1, -1};
 
366
    int c2p[2] = {-1, -1};
367
367
    HANDLE hProcess = NULL, thread = NULL;
368
368
    pid_t pid = -1;
369
369
 
370
370
    struct thread_params thread_params;
371
371
    ssize_t x;
372
 
    int tmp_s, fd = -1;
 
372
    int fd = -1;
373
373
    char *str;
374
374
    STARTUPINFO si;
375
375
    PROCESS_INFORMATION pi;
377
377
    int prfd_ipc = -1, pwfd_ipc = -1, crfd_ipc = -1, cwfd_ipc = -1;
378
378
    char *prog = NULL, *buf1 = NULL;
379
379
 
380
 
    struct sockaddr_in CS_ipc, PS_ipc;
 
380
    IpAddress PS_ipc;
 
381
    IpAddress CS_ipc;
 
382
    struct addrinfo *aiPS_ipc = NULL;
 
383
    struct addrinfo *aiCS_ipc = NULL;
381
384
 
382
385
    struct ipc_params *params = (struct ipc_params *) in_params;
383
386
    int type = params->type;
385
388
    int cwfd = params->cwfd;
386
389
    char **args = params->args;
387
390
 
388
 
    struct sockaddr_in PS = params->PS;
389
 
 
 
391
    IpAddress PS = params->PS;
 
392
    IpAddress local_addr = params->local_addr;
390
393
 
391
394
    buf1 = (char *)xcalloc(1, 8192);
392
395
    strcpy(buf1, params->prog);
411
414
        debugs(54, 3, "ipcCreate: CHILD accepted new FD " << fd);
412
415
        comm_close(crfd);
413
416
        snprintf(buf1, 8191, "%s CHILD socket", prog);
414
 
        fdc_open(fd, FD_SOCKET, buf1);
 
417
        fd_open(fd, FD_SOCKET, buf1);
415
418
        fd_table[fd].flags.ipc = 1;
416
419
        cwfd = crfd = fd;
417
420
    } else if (type == IPC_UDP_SOCKET) {
418
 
        if (comm_connect_addr(crfd, &PS) == COMM_ERROR)
 
421
        if (comm_connect_addr(crfd, params->PS) == COMM_ERROR)
419
422
            goto cleanup;
420
423
    }
421
424
 
457
460
 
458
461
    if (type == IPC_UDP_SOCKET) {
459
462
        snprintf(buf1, 8192, "%s(%ld) <-> ipc CHILD socket", prog, -1L);
460
 
        crfd_ipc = cwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1);
 
463
        crfd_ipc = cwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, buf1);
461
464
 
462
465
        if (crfd_ipc < 0) {
463
466
            debugs(54, 0, "ipcCreate: CHILD: Failed to create child FD for " << prog << ".");
466
469
        }
467
470
 
468
471
        snprintf(buf1, 8192, "%s(%ld) <-> ipc PARENT socket", prog, -1L);
469
 
        prfd_ipc = pwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1);
 
472
        prfd_ipc = pwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, buf1);
470
473
 
471
474
        if (pwfd_ipc < 0) {
472
475
            debugs(54, 0, "ipcCreate: CHILD: Failed to create server FD for " << prog << ".");
474
477
            goto cleanup;
475
478
        }
476
479
 
477
 
        tmp_s = sizeof(PS_ipc);
478
 
        memset(&PS_ipc, '\0', tmp_s);
479
 
 
480
 
        if (getsockname(pwfd_ipc, (struct sockaddr *) &PS_ipc, &tmp_s) < 0) {
481
 
            debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
482
 
            ipcSend(cwfd, err_string, strlen(err_string));
483
 
            goto cleanup;
484
 
        }
485
 
 
486
 
        debugs(54, 3, "ipcCreate: FD " << pwfd_ipc << " sockaddr " << inet_ntoa(PS_ipc.sin_addr) << ":" << ntohs(PS_ipc.sin_port));
487
 
 
488
 
        tmp_s = sizeof(CS_ipc);
489
 
        memset(&CS_ipc, '\0', tmp_s);
490
 
 
491
 
        if (getsockname(crfd_ipc, (struct sockaddr *) &CS_ipc, &tmp_s) < 0) {
492
 
            debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
493
 
            ipcSend(cwfd, err_string, strlen(err_string));
494
 
            goto cleanup;
495
 
        }
496
 
 
497
 
        debugs(54, 3, "ipcCreate: FD " << crfd_ipc << " sockaddr " << inet_ntoa(CS_ipc.sin_addr) << ":" << ntohs(CS_ipc.sin_port));
498
 
 
499
 
        if (comm_connect_addr(pwfd_ipc, &CS_ipc) == COMM_ERROR) {
 
480
        PS_ipc.InitAddrInfo(aiPS_ipc);
 
481
 
 
482
        if (getsockname(pwfd_ipc, aiPS_ipc->ai_addr, &(aiPS_ipc->ai_addrlen)) < 0) {
 
483
            debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
 
484
            ipcSend(cwfd, err_string, strlen(err_string));
 
485
            goto cleanup;
 
486
        }
 
487
 
 
488
        PS_ipc = *aiPS_ipc;
 
489
 
 
490
        debugs(54, 3, "ipcCreate: FD " << pwfd_ipc << " sockaddr " << PS_ipc);
 
491
 
 
492
        CS_ipc.InitAddrInfo(aiCS_ipc);
 
493
 
 
494
        if (getsockname(crfd_ipc, aiCS_ipc->ai_addr, &(aiCS_ipc->ai_addrlen)) < 0) {
 
495
            debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
 
496
            ipcSend(cwfd, err_string, strlen(err_string));
 
497
            goto cleanup;
 
498
        }
 
499
 
 
500
        CS_ipc = *aiCS_ipc;
 
501
 
 
502
        debugs(54, 3, "ipcCreate: FD " << crfd_ipc << " sockaddr " << CS_ipc);
 
503
 
 
504
        if (comm_connect_addr(pwfd_ipc, CS_ipc) == COMM_ERROR) {
500
505
            ipcSend(cwfd, err_string, strlen(err_string));
501
506
            goto cleanup;
502
507
        }
503
508
 
504
509
        fd = crfd;
505
510
 
506
 
        if (comm_connect_addr(crfd_ipc, &PS_ipc) == COMM_ERROR) {
 
511
        if (comm_connect_addr(crfd_ipc, PS_ipc) == COMM_ERROR) {
507
512
            ipcSend(cwfd, err_string, strlen(err_string));
508
513
            goto cleanup;
509
514
        }
699
704
    if (-1 == ipcSend(cwfd, buf1, strlen(buf1)))
700
705
        goto cleanup;
701
706
 
702
 
        debugs(54, 2, "ipc(" << prog << "," << pid << "): started successfully");
 
707
    debugs(54, 2, "ipc(" << prog << "," << pid << "): started successfully");
703
708
 
704
709
    /* cycle */
705
710
    for (;;) {