annotate src/master/dup2-array.c @ 8971:163c3f85a3aa HEAD

namespaces: list=children wasn't working correctly.
author Timo Sirainen <tss@iki.fi>
date Mon, 20 Apr 2009 13:28:00 -0400
parents b9faf4db2a9f
children 00cd9aacd03c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8590
b9faf4db2a9f Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
1 /* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
5887
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "array.h"
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "fd-close-on-exec.h"
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6 #include "dup2-array.h"
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include <unistd.h>
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 void dup2_append(ARRAY_TYPE(dup2) *dups, int fd_src, int fd_dest)
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 struct dup2 d;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 d.fd_src = fd_src;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 d.fd_dest = fd_dest;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 array_append(dups, &d, 1);
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19 int dup2_array(ARRAY_TYPE(dup2) *dups_arr)
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 struct dup2 *dups;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 bool *moved, moves;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 unsigned int i, j, count, conflict;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 int fd;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 dups = array_get_modifiable(dups_arr, &count);
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 moved = t_new(bool, count);
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 for (;;) {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 conflict = count;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 moves = FALSE;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 for (i = 0; i < count; i++) {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 if (moved[i])
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 continue;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36 for (j = 0; j < count; j++) {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 if (dups[j].fd_src == dups[i].fd_dest &&
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 !moved[j]) {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 conflict = j;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 break;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44 if (j == count) {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 /* no conflicts, move it */
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 moved[i] = TRUE;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 moves = TRUE;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 if (dup2(dups[i].fd_src, dups[i].fd_dest) < 0) {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 i_error("dup2(%d, %d) failed: %m",
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 dups[i].fd_src,
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 dups[i].fd_dest);
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 return -1;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
55 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56 if (conflict == count)
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 break;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 if (moves) {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 /* it's possible that the conflicting fd was
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 moved already. try again. */
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 continue;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 /* ok, we have to dup() */
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 fd = dup(dups[conflict].fd_src);
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67 if (fd == -1) {
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 i_error("dup(%d) failed: %m", dups[conflict].fd_src);
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 return -1;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71 fd_close_on_exec(fd, TRUE);
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 dups[conflict].fd_src = fd;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 return 0;
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75 }
3f2eb1b9c555 Support listening multiple sockets. SIGHUP also doesn't anymore recreate
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76