Mercurial > dovecot > original-hg > dovecot-1.2
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 |
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 |