7 #include "wvresolver.h" 8 #include "wvloopback.h" 11 #include <sys/types.h> 16 #define WVRESOLVER_SKIP_FORK 19 #define waitpid(a,b,c) (0) 23 #include "wvautoconf.h" 34 WvIPAddrList addrlist;
41 { init(); addr = NULL; }
45 #ifndef WVRESOLVER_SKIP_FORK 51 while ((rv = waitpid(pid, NULL, 0)) != pid)
52 if (rv == -1 && errno != EINTR)
61 { done = negative =
false;
62 pid = 0; loop = NULL; last_tried = time(NULL); }
73 int WvResolver::numresolvers = 0;
74 WvResolverHostDict *WvResolver::hostmap = NULL;
75 WvResolverAddrDict *WvResolver::addrmap = NULL;
80 static void namelookup(
const char *name,
WvLoopback *loop)
87 for (
int count = 0; count < 10; count++)
89 he = gethostbyname(name);
92 char **addr = he->h_addr_list;
95 loop->print(
"%s ",
WvIPAddr((
unsigned char *)(*addr)));
105 if (h_errno != TRY_AGAIN)
124 WvResolver::WvResolver()
128 hostmap =
new WvResolverHostDict(10);
130 addrmap =
new WvResolverAddrDict(10);
134 WvResolver::~WvResolver()
137 if (numresolvers <= 0 && hostmap && addrmap)
151 WvIPAddrList *addrlist)
154 time_t now = time(NULL);
157 host = (*hostmap)[name];
162 if ((host->done && host->last_tried + 60*5 < now)
163 || (!host->done && host->last_tried + 60 < now))
166 hostmap->remove(host);
177 WvIPAddrList::Iter i(host->addrlist);
178 for (i.rewind(); i.next(); )
180 addrlist->append(i.ptr(),
false);
188 else if (host->negative)
204 hostmap->add(host,
true);
208 #ifdef WVRESOLVER_SKIP_FORK 210 namelookup(name, host->loop);
221 namelookup(name, host->loop);
230 #ifndef WVRESOLVER_SKIP_FORK 236 if (waitpid(host->pid, NULL, WNOHANG) == host->pid)
239 if (!host->loop->
select(msec_timeout < 0 ? 100 : msec_timeout,
244 if (msec_timeout >= 0)
250 WVRELEASE(host->loop);
252 host->negative =
true;
258 }
while (host->pid && msec_timeout < 0);
267 }
while (!line && host->loop->
isok());
269 if (line && line[0] != 0)
274 p = strtok(line,
" \n");
276 host->addr = resolvedaddr;
277 host->addrlist.append(resolvedaddr,
true);
281 addrlist->append(host->addr,
false);
284 p = strtok(NULL,
" \n");
289 host->addrlist.append(resolvedaddr,
true);
291 addrlist->append(resolvedaddr,
false);
297 host->negative =
true;
299 if (host->pid && waitpid(host->pid, NULL, 0) == host->pid)
301 WVRELEASE(host->loop);
305 return host->negative ? 0 : res;
312 hostmap->remove(host);
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
int getrfd() const
Returns the Unix file descriptor for reading from this stream.
void xpre_select(SelectInfo &si, const SelectRequest &r)
Like pre_select(), but still exists even if you override the other pre_select() in a subclass...
Provides support for forking processes.
virtual void nowrite()
Shuts down the writing side of the stream.
int findaddr(int msec_timeout, WvStringParm name, WvIPAddr const **addr, WvIPAddrList *addrlist=NULL)
Return -1 on timeout, or the number of addresses found, which may be 0 if the address does not exist...
An IP address is made up of a "dotted quad" – four decimal numbers in the form www.xxx.yyy.zzz.
Implementation of a WvLoopback stream.
char * blocking_getline(time_t wait_msec, int separator='\n', int readahead=1024)
This is a version of getline() that allows you to block for more data to arrive.
int getwfd() const
Returns the Unix file descriptor for writing to this stream.
bool xpost_select(SelectInfo &si, const SelectRequest &r)
Like post_select(), but still exists even if you override the other post_select() in a subclass...
the data structure used by pre_select()/post_select() and internally by select(). ...
A SelectRequest is a convenient way to remember what we want to do to a particular stream: read from ...
virtual bool isok() const
return true if the stream is actually usable right now
bool select(time_t msec_timeout)
Return true if any of the requested features are true on the stream.
WvString hostname()
Do gethostname() without a fixed-length buffer.
void pre_select(WvStringParm hostname, WvStream::SelectInfo &si)
add all of our waiting fds to an fd_set for use with select().
bool post_select(WvStringParm hostname, WvStream::SelectInfo &si)
determines whether the resolving process is complete.
pid_t wvfork(int dontclose1=-1, int dontclose2=-1)
wvfork() just runs fork(), but it closes all file descriptors that are flagged close-on-exec, since we don't necessarily always run exec() after we fork()...
WvString is an implementation of a simple and efficient printable-string class.
virtual void noread()
Shuts down the reading side of the stream.