Mercurial > dovecot > core-2.2
annotate src/master/dict-process.c @ 4907:5b4c9b20eba0 HEAD
Replaced void *context from a lot of callbacks with the actual context
type. Also added/fixed some context type checks.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 15 Dec 2006 20:38:08 +0200 |
parents | 9928ebb54719 |
children | f655c4d4a419 |
rev | line source |
---|---|
3855 | 1 /* Copyright (C) 2006 Timo Sirainen */ |
2 | |
3 #include "common.h" | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
4 #include "array.h" |
3855 | 5 #include "ioloop.h" |
6 #include "network.h" | |
7 #include "fd-close-on-exec.h" | |
8 #include "env-util.h" | |
9 #include "log.h" | |
10 #include "dict-process.h" | |
11 | |
12 #include <syslog.h> | |
13 #include <unistd.h> | |
14 #include <sys/stat.h> | |
15 | |
3885
b624b687fe13
Create dict-server socket to base_dir.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
16 #define DICT_SERVER_SOCKET_NAME "dict-server" |
3855 | 17 |
18 struct dict_process { | |
3885
b624b687fe13
Create dict-server socket to base_dir.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
19 char *path; |
3855 | 20 int fd; |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
21 |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
22 struct log_io *log; |
3855 | 23 struct io *io; |
24 }; | |
25 | |
26 static struct dict_process *process; | |
27 | |
28 static void dict_process_unlisten(struct dict_process *process); | |
29 | |
30 static int dict_process_start(struct dict_process *process) | |
31 { | |
32 struct log_io *log; | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
33 const char *executable, *const *dicts; |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
34 unsigned int i, count; |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
35 int log_fd; |
3855 | 36 pid_t pid; |
37 | |
38 log_fd = log_create_pipe(&log, 0); | |
39 if (log_fd < 0) | |
40 pid = -1; | |
41 else { | |
42 pid = fork(); | |
43 if (pid < 0) | |
44 i_error("fork() failed: %m"); | |
45 } | |
46 | |
47 if (pid < 0) { | |
48 (void)close(log_fd); | |
49 return -1; | |
50 } | |
51 | |
52 if (pid != 0) { | |
53 /* master */ | |
54 PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_DICT); | |
55 log_set_prefix(log, "dict: "); | |
56 (void)close(log_fd); | |
57 | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
58 process->log = log; |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
59 log_ref(process->log); |
3855 | 60 dict_process_unlisten(process); |
61 return 0; | |
62 } | |
63 log_set_prefix(log, "master-dict: "); | |
64 | |
65 /* set stdin and stdout to /dev/null, so anything written into it | |
66 gets ignored. */ | |
67 if (dup2(null_fd, 0) < 0) | |
68 i_fatal("dup2(stdin) failed: %m"); | |
69 if (dup2(null_fd, 1) < 0) | |
70 i_fatal("dup2(stdout) failed: %m"); | |
71 | |
72 /* stderr = log, 3 = listener */ | |
73 if (dup2(log_fd, 2) < 0) | |
74 i_fatal("dup2(stderr) failed: %m"); | |
75 if (dup2(process->fd, 3) < 0) | |
76 i_fatal("dup2(3) failed: %m"); | |
77 | |
78 for (i = 0; i <= 3; i++) | |
79 fd_close_on_exec(i, FALSE); | |
80 | |
81 child_process_init_env(); | |
82 env_put(t_strconcat("DICT_LISTEN_FROM_FD=", process->path, NULL)); | |
83 | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
84 dicts = array_get(&settings_root->dicts, &count); |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
85 i_assert((count % 2) == 0); |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
86 for (i = 0; i < count; i += 2) |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
87 env_put(t_strdup_printf("DICT_%s=%s", dicts[i], dicts[i+1])); |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
88 |
3855 | 89 /* make sure we don't leak syslog fd, but do it last so that |
90 any errors above will be logged */ | |
91 closelog(); | |
92 | |
93 executable = PKG_LIBEXECDIR"/dict"; | |
94 client_process_exec(executable, ""); | |
95 i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", executable); | |
96 return -1; | |
97 } | |
98 | |
4907
5b4c9b20eba0
Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents:
4393
diff
changeset
|
99 static void dict_process_listen_input(struct dict_process *process) |
3855 | 100 { |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
101 i_assert(process->log == NULL); |
3855 | 102 dict_process_start(process); |
103 } | |
104 | |
105 static int dict_process_listen(struct dict_process *process) | |
106 { | |
107 mode_t old_umask; | |
108 int fd, i = 0; | |
109 | |
110 for (;;) { | |
111 old_umask = umask(0); | |
112 process->fd = net_listen_unix(process->path, 64); | |
113 umask(old_umask); | |
114 | |
115 if (process->fd != -1) | |
116 break; | |
117 | |
118 if (errno != EADDRINUSE || ++i == 2) { | |
119 i_error("net_listen_unix(%s) failed: %m", | |
120 process->path); | |
121 return -1; | |
122 } | |
123 | |
124 /* see if it really exists */ | |
125 fd = net_connect_unix(process->path); | |
126 if (fd != -1 || errno != ECONNREFUSED) { | |
127 if (fd != -1) (void)close(fd); | |
128 i_error("Socket already exists: %s", process->path); | |
129 return -1; | |
130 } | |
131 | |
132 /* delete and try again */ | |
133 if (unlink(process->path) < 0 && errno != ENOENT) { | |
134 i_error("unlink(%s) failed: %m", process->path); | |
135 return -1; | |
136 } | |
137 } | |
138 | |
139 fd_close_on_exec(process->fd, TRUE); | |
140 process->io = io_add(process->fd, IO_READ, | |
141 dict_process_listen_input, process); | |
142 | |
143 return process->fd != -1 ? 0 : -1; | |
144 } | |
145 | |
146 static void dict_process_unlisten(struct dict_process *process) | |
147 { | |
148 if (process->fd == -1) | |
149 return; | |
150 | |
3960
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3892
diff
changeset
|
151 io_remove(&process->io); |
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3892
diff
changeset
|
152 |
3855 | 153 if (close(process->fd) < 0) |
154 i_error("close(dict) failed: %m"); | |
155 process->fd = -1; | |
156 } | |
157 | |
158 void dict_process_init(void) | |
159 { | |
160 process = i_new(struct dict_process, 1); | |
161 process->fd = -1; | |
3885
b624b687fe13
Create dict-server socket to base_dir.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
162 process->path = i_strconcat(settings_root->defaults->base_dir, |
3975
9de8bce1077e
Added plugin {} section to dovecot.conf for passing extra environment
Timo Sirainen <tss@iki.fi>
parents:
3960
diff
changeset
|
163 "/"DICT_SERVER_SOCKET_NAME, NULL); |
9de8bce1077e
Added plugin {} section to dovecot.conf for passing extra environment
Timo Sirainen <tss@iki.fi>
parents:
3960
diff
changeset
|
164 (void)dict_process_listen(process); |
3855 | 165 } |
166 | |
167 void dict_process_deinit(void) | |
168 { | |
169 dict_process_unlisten(process); | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
170 if (process->log != NULL) |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
171 log_unref(process->log); |
3885
b624b687fe13
Create dict-server socket to base_dir.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
172 i_free(process->path); |
3855 | 173 i_free(process); |
174 } | |
175 | |
176 void dict_process_restart(void) | |
177 { | |
178 dict_process_deinit(); | |
179 dict_process_init(); | |
180 } | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
181 |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
182 void dict_process_kill(void) |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
183 { |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
184 if (process->log != NULL) { |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
185 log_unref(process->log); |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
186 process->log = NULL; |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
187 } |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
188 } |