File: | src/usr.sbin/ldapd/imsgev.c |
Warning: | line 142, column 8 Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: imsgev.c,v 1.6 2017/03/01 00:53:39 gsoares Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 2009 Eric Faurot <eric@openbsd.org> |
5 | * |
6 | * Permission to use, copy, modify, and distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above |
8 | * copyright notice and this permission notice appear in all copies. |
9 | * |
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | */ |
18 | |
19 | #include <sys/queue.h> |
20 | #include <sys/socket.h> |
21 | #include <sys/uio.h> |
22 | |
23 | #include <errno(*__errno()).h> |
24 | #include <stdio.h> |
25 | #include <stdlib.h> |
26 | #include <string.h> |
27 | #include <unistd.h> |
28 | |
29 | #include "imsgev.h" |
30 | |
31 | void imsgev_add(struct imsgev *); |
32 | void imsgev_dispatch(int, short, void *); |
33 | void imsgev_disconnect(struct imsgev *, int); |
34 | |
35 | void |
36 | imsgev_init(struct imsgev *iev, int fd, void *data, |
37 | void (*callback)(struct imsgev *, int, struct imsg *), |
38 | void (*needfd)(struct imsgev *)) |
39 | { |
40 | imsg_init(&iev->ibuf, fd); |
41 | iev->terminate = 0; |
42 | |
43 | iev->data = data; |
44 | iev->handler = imsgev_dispatch; |
45 | iev->callback = callback; |
46 | iev->needfd = needfd; |
47 | |
48 | iev->events = EV_READ0x02; |
49 | event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); |
50 | event_add(&iev->ev, NULL((void *)0)); |
51 | } |
52 | |
53 | int |
54 | imsgev_compose(struct imsgev *iev, u_int16_t type, u_int32_t peerid, |
55 | uint32_t pid, int fd, void *data, u_int16_t datalen) |
56 | { |
57 | int r; |
58 | |
59 | r = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen); |
60 | if (r != -1) |
61 | imsgev_add(iev); |
62 | |
63 | return (r); |
64 | } |
65 | |
66 | void |
67 | imsgev_close(struct imsgev *iev) |
68 | { |
69 | iev->terminate = 1; |
70 | imsgev_add(iev); |
71 | } |
72 | |
73 | void |
74 | imsgev_clear(struct imsgev *iev) |
75 | { |
76 | event_del(&iev->ev); |
77 | msgbuf_clear(&iev->ibuf.w); |
78 | close(iev->ibuf.fd); |
79 | } |
80 | |
81 | void |
82 | imsgev_add(struct imsgev *iev) |
83 | { |
84 | short events = 0; |
85 | |
86 | if (!iev->terminate) |
87 | events = EV_READ0x02; |
88 | if (iev->ibuf.w.queued || iev->terminate) |
89 | events |= EV_WRITE0x04; |
90 | |
91 | /* optimization: skip event_{del/set/add} if already set */ |
92 | if (events == iev->events) |
93 | return; |
94 | |
95 | iev->events = events; |
96 | event_del(&iev->ev); |
97 | event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); |
98 | event_add(&iev->ev, NULL((void *)0)); |
99 | } |
100 | |
101 | void |
102 | imsgev_dispatch(int fd, short ev, void *humppa) |
103 | { |
104 | struct imsgev *iev = humppa; |
105 | struct imsgbuf *ibuf = &iev->ibuf; |
106 | struct imsg imsg; |
107 | ssize_t n; |
108 | |
109 | iev->events = 0; |
110 | |
111 | if (ev & EV_READ0x02) { |
112 | if ((n = imsg_read(ibuf)) == -1) { |
113 | /* if we don't have enough fds, free one up and retry */ |
114 | if (errno(*__errno()) == EAGAIN35) { |
115 | iev->needfd(iev); |
116 | n = imsg_read(ibuf); |
117 | } |
118 | |
119 | if (n == -1) { |
120 | imsgev_disconnect(iev, IMSGEV_EREAD2); |
121 | return; |
122 | } |
123 | } |
124 | if (n == 0) { |
125 | /* |
126 | * Connection is closed for reading, and we assume |
127 | * it is also closed for writing, so we error out |
128 | * if write data is pending. |
129 | */ |
130 | imsgev_disconnect(iev, |
131 | (iev->ibuf.w.queued) ? IMSGEV_EWRITE3 : IMSGEV_DONE1); |
132 | return; |
133 | } |
134 | } |
135 | |
136 | if (ev & EV_WRITE0x04) { |
137 | /* |
138 | * We wanted to write data out but the connection is either |
139 | * closed, or some error occured. Both case are not recoverable |
140 | * from the imsg perspective, so we treat it as a WRITE error. |
141 | */ |
142 | if ((n = msgbuf_write(&ibuf->w)) <= 0 && errno(*__errno()) != EAGAIN35) { |
Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' | |
143 | imsgev_disconnect(iev, IMSGEV_EWRITE3); |
144 | return; |
145 | } |
146 | } |
147 | |
148 | while (iev->terminate == 0) { |
149 | if ((n = imsg_get(ibuf, &imsg)) == -1) { |
150 | imsgev_disconnect(iev, IMSGEV_EIMSG4); |
151 | return; |
152 | } |
153 | if (n == 0) |
154 | break; |
155 | iev->callback(iev, IMSGEV_IMSG0, &imsg); |
156 | imsg_free(&imsg); |
157 | } |
158 | |
159 | if (iev->terminate && iev->ibuf.w.queued == 0) { |
160 | imsgev_disconnect(iev, IMSGEV_DONE1); |
161 | return; |
162 | } |
163 | |
164 | imsgev_add(iev); |
165 | } |
166 | |
167 | void |
168 | imsgev_disconnect(struct imsgev *iev, int code) |
169 | { |
170 | iev->callback(iev, code, NULL((void *)0)); |
171 | } |