VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp@ 49312

Last change on this file since 49312 was 49268, checked in by vboxsync, 11 years ago

Main/HostDnsServiceLinux: Warning and spaces.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.5 KB
Line 
1/* $Id: HostDnsServiceLinux.cpp 49268 2013-10-24 08:03:17Z vboxsync $ */
2/** @file
3 * Linux specific DNS information fetching.
4 */
5
6/*
7 * Copyright (C) 2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <iprt/assert.h>
19#include <iprt/err.h>
20#include <iprt/initterm.h>
21#include <iprt/file.h>
22#include <iprt/log.h>
23#include <iprt/stream.h>
24#include <iprt/string.h>
25#include <iprt/semaphore.h>
26#include <iprt/thread.h>
27
28#include <errno.h>
29#include <poll.h>
30#include <string.h>
31#include <unistd.h>
32
33#include <fcntl.h>
34
35#include <sys/inotify.h>
36#include <sys/types.h>
37#include <sys/socket.h>
38
39#include <string>
40#include <vector>
41#include "../HostDnsService.h"
42
43
44static RTTHREAD g_DnsMonitoringThread;
45static RTSEMEVENT g_DnsInitEvent;
46static int g_DnsMonitorStop[2];
47
48class FileDescriptor
49{
50 public:
51 FileDescriptor(int d = -1):fd(d){}
52
53 virtual ~FileDescriptor() {
54 if (fd != -1)
55 close(fd);
56 }
57
58 int fileDescriptor() const {return fd;}
59
60 protected:
61 int fd;
62};
63
64
65class AutoNotify:public FileDescriptor
66{
67 public:
68 AutoNotify()
69 {
70 FileDescriptor::fd = inotify_init();
71 AssertReturnVoid(FileDescriptor::fd != -1);
72 }
73
74};
75
76
77class AutoWatcher:public FileDescriptor
78{
79 public:
80 AutoWatcher(const AutoNotify& notifier, const std::string& filename, uint32_t mask = IN_CLOSE_WRITE)
81 :name(filename)
82 {
83 nfd = notifier.fileDescriptor();
84 fd = inotify_add_watch(nfd, name.c_str(), mask);
85 AssertMsgReturnVoid(fd != -1, ("failed to add watcher %s\n", name.c_str()));
86
87 int opt = fcntl(fd, F_GETFL);
88 opt |= O_NONBLOCK;
89 fcntl(fd, F_SETFL, opt);
90 }
91
92 ~AutoWatcher()
93 {
94 int rc = inotify_rm_watch(nfd, fd);
95 AssertMsgReturnVoid(rc != -1, ("Can't detach watcher %d from %d (%d: %s)\n", nfd, fd,
96 errno, strerror(errno)));
97 }
98
99 private:
100 std::string name;
101 int nfd;
102};
103
104
105HostDnsServiceLinux::~HostDnsServiceLinux()
106{
107 send(g_DnsMonitorStop[0], "", 1, 0);
108}
109
110
111int HostDnsServiceLinux::hostMonitoringRoutine(RTTHREAD ThreadSelf, void *pvUser)
112{
113 NOREF(ThreadSelf);
114 AutoNotify a;
115 HostDnsServiceLinux *dns = static_cast<HostDnsServiceLinux *>(pvUser);
116 AutoWatcher w(a, std::string(dns->resolvConf().c_str()));
117
118 int rc = socketpair(AF_LOCAL, SOCK_DGRAM, 0, g_DnsMonitorStop);
119 AssertMsgReturn(rc == 0, ("socketpair: failed (%d: %s)\n", errno, strerror(errno)), E_FAIL);
120
121 FileDescriptor stopper0(g_DnsMonitorStop[0]);
122 FileDescriptor stopper1(g_DnsMonitorStop[1]);
123
124 pollfd polls[2];
125 RT_ZERO(polls);
126
127 polls[0].fd = a.fileDescriptor();
128 polls[0].events = POLLIN;
129
130 polls[1].fd = g_DnsMonitorStop[1];
131 polls[1].events = POLLIN;
132
133 RTSemEventSignal(g_DnsInitEvent);
134
135 while(true)
136 {
137 rc = poll(polls, 2, -1);
138 if (rc == -1)
139 continue;
140
141 AssertMsgReturn( ((polls[0].revents & (POLLERR|POLLNVAL)) == 0)
142 && ((polls[1].revents & (POLLERR|POLLNVAL)) == 0),
143 ("Debug Me"), VERR_INTERNAL_ERROR);
144
145 if (polls[1].revents & POLLIN)
146 return VINF_SUCCESS; /* time to shutdown */
147
148 if (polls[0].revents & POLLIN)
149 {
150 dns->readResolvConf();
151 /* notifyAll() takes required locks */
152 dns->notifyAll();
153
154 polls[0].revents = 0;
155
156 inotify_event ev;
157 rc = read(a.fileDescriptor(), static_cast<void *>(&ev), sizeof(ev));
158 AssertMsg(rc == sizeof(ev) && ev.wd == w.fileDescriptor(), ("Hmm, debug me"));
159 }
160 }
161}
162
163
164HRESULT HostDnsServiceLinux::init(const char *aResolvConfFileName)
165{
166 HRESULT hrc = HostDnsServiceResolvConf::init(aResolvConfFileName);
167 AssertComRCReturnRC(hrc);
168
169 int rc = RTThreadCreate(&g_DnsMonitoringThread, HostDnsServiceLinux::hostMonitoringRoutine,
170 this, 128 * _1K, RTTHREADTYPE_IO, 0, "dns-monitor");
171 AssertRCReturn(rc, E_FAIL);
172
173 rc = RTSemEventCreate(&g_DnsInitEvent);
174 AssertRCReturn(rc, E_FAIL);
175
176 RTSemEventWait(g_DnsInitEvent, RT_INDEFINITE_WAIT);
177
178 return S_OK;
179}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette