Changeset 18360 in vbox for trunk/src/VBox/Additions/x11/VBoxClient
- Timestamp:
- Mar 26, 2009 11:46:38 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 45146
- Location:
- trunk/src/VBox/Additions/x11/VBoxClient
- Files:
-
- 3 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
r16014 r18360 52 52 VBoxClient_DEFS += SEAMLESS_GUEST DYNAMIC_RESIZE 53 53 VBoxClient_SOURCES += \ 54 seamless.cpp \ 54 55 seamless-host.cpp \ 55 56 seamless-x11.cpp \ 56 57 thread.cpp \ 57 displaychange-x11.cpp58 autoresize.cpp 58 59 VBoxClient_LIBS += \ 59 60 Xext Xmu -
trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
r17004 r18360 42 42 #include <vector> 43 43 44 #include "VBoxClient.h" 44 45 #include "clipboard.h" 45 46 … … 1362 1363 } 1363 1364 1364 1365 1365 /** 1366 1366 * Connect the guest clipboard to the host. … … 1378 1378 /* Initialise the termination semaphore. */ 1379 1379 RTSemEventCreate(&g_ctx.terminating); 1380 1381 /* Initialise threading in X11 and in Xt. */ 1382 if (!XInitThreads() || !XtToolkitThreadInitialize()) 1383 { 1384 LogRel(("VBoxClient: error initialising threads in X11, exiting.\n")); 1385 return VERR_NOT_SUPPORTED; 1386 } 1380 1387 1381 1388 rc = VbglR3ClipboardConnect(&g_ctx.client); … … 1487 1494 } 1488 1495 1496 class ClipboardService : public VBoxClient::Service 1497 { 1498 public: 1499 virtual const char *getPidFilePath() 1500 { 1501 return ".vboxclient-clipboard.pid"; 1502 } 1503 virtual int run() 1504 { 1505 int rc = vboxClipboardConnect(); 1506 if (RT_SUCCESS(rc)) 1507 rc = vboxClipboardMain(); 1508 return rc; 1509 } 1510 virtual void cleanup() 1511 { 1512 /* Nothing to do. */ 1513 } 1514 }; 1515 1516 VBoxClient::Service *VBoxClient::GetClipboardService() 1517 { 1518 return new ClipboardService; 1519 } -
trunk/src/VBox/Additions/x11/VBoxClient/main.cpp
r18320 r18360 21 21 */ 22 22 23 #include <VBox/VBoxGuest.h> 24 #include <VBox/log.h> 23 #include <sys/types.h> 24 #include <stdlib.h> /* For exit */ 25 #include <stdio.h> 26 #include <string.h> 27 #include <unistd.h> 28 #include <errno.h> 29 #include <signal.h> 30 31 #include <iprt/env.h> 25 32 #include <iprt/initterm.h> 26 33 #include <iprt/path.h> 27 34 #include <iprt/stream.h> 28 29 #include <sys/types.h> 30 #include <stdlib.h> /* For exit */ 31 #include <stdio.h> 32 #include <unistd.h> 33 #include <errno.h> 34 #include <signal.h> 35 36 #include <X11/Xlib.h> 37 #include <X11/Intrinsic.h> 38 39 #include "clipboard.h" 35 #include <iprt/string.h> 36 #include <VBox/VBoxGuest.h> 37 #include <VBox/log.h> 38 39 #include "VBoxClient.h" 40 40 41 41 #ifdef DYNAMIC_RESIZE … … 50 50 static int (*gpfnOldIOErrorHandler)(Display *) = NULL; 51 51 52 /* Make these global so that the destructors are called if we make an "emergency exit", 53 i.e. a (handled) signal or an X11 error. */ 54 #ifdef DYNAMIC_RESIZE 55 VBoxGuestDisplayChangeMonitor gDisplayChange; 56 # ifdef SEAMLESS_GUEST 57 /** Our instance of the seamless class. This only makes sense if dynamic resizing 58 is enabled. */ 59 VBoxGuestSeamless gSeamless; 60 # endif /* SEAMLESS_GUEST defined */ 61 #endif /* DYNAMIC_RESIZE */ 62 #ifdef VBOX_X11_CLIPBOARD 63 VBoxGuestClipboard gClipboard; 64 #endif 65 66 /** 67 * Drop the programmes privileges to the caller's. 68 * @returns IPRT status code 69 * @todo move this into the R3 guest library 70 */ 71 int vboxClientDropPrivileges(void) 72 { 73 int rc = VINF_SUCCESS; 74 int rcSystem, rcErrno; 75 76 LogFlowFunc(("\n")); 77 #ifdef _POSIX_SAVED_IDS 78 rcSystem = setuid(getuid()); 79 #else 80 rcSystem = setreuid(-1, getuid()); 81 #endif 82 if (rcSystem < 0) 83 { 84 rcErrno = errno; 85 rc = RTErrConvertFromErrno(rcErrno); 86 LogRel(("VBoxClient: failed to drop privileges, error %Rrc.\n", rc)); 87 } 88 LogFlowFunc(("returning %Rrc\n", rc)); 89 return rc; 52 /** Object representing the service we are running. This has to be global 53 * so that the cleanup routine can access it. */ 54 VBoxClient::Service *g_pService; 55 /** The name of our pidfile. It is global for the benefit of the cleanup 56 * routine. */ 57 static char *g_pszPidFile; 58 /** The file handle of our pidfile. It is global for the benefit of the 59 * cleanup routine. */ 60 static RTFILE g_hPidFile; 61 62 /** Clean up if we get a signal or something. This is extern so that we 63 * can call it from other compilation units. */ 64 void VBoxClient::CleanUp() 65 { 66 if (g_pService) 67 { 68 g_pService->cleanup(); 69 delete g_pService; 70 } 71 if (g_pszPidFile && g_hPidFile) 72 VbglR3ClosePidFile(g_pszPidFile, g_hPidFile); 73 VbglR3Term(); 74 exit(0); 75 } 76 77 /** 78 * A standard signal handler which cleans up and exits. 79 */ 80 void vboxClientSignalHandler(int cSignal) 81 { 82 Log(("VBoxClient: terminated with signal %d\n", cSignal)); 83 /** Disable seamless mode */ 84 RTPrintf(("VBoxClient: terminating...\n")); 85 VBoxClient::CleanUp(); 90 86 } 91 87 … … 112 108 XGetErrorText(pDisplay, pError->error_code, errorText, sizeof(errorText)); 113 109 LogRel(("VBoxClient: an X Window protocol error occurred: %s (error code %d). Request code: %d, minor code: %d, serial number: %d\n", errorText, pError->error_code, pError->request_code, pError->minor_code, pError->serial)); 114 /** Disable seamless mode */ 115 VbglR3SeamlessSetCap(false); 116 VbglR3Term(); 117 exit(1); 110 VBoxClient::CleanUp(); 111 return 0; /* We should never reach this. */ 118 112 } 119 113 … … 122 116 * when X exits. 123 117 */ 124 int vboxClientXLibIOErrorHandler(Display *pDisplay)118 static int vboxClientXLibIOErrorHandler(Display *pDisplay) 125 119 { 126 120 Log(("VBoxClient: a fatal guest X Window error occurred. This may just mean that the Window system was shut down while the client was still running.\n")); 127 /** Disable seamless mode */ 128 VbglR3SeamlessSetCap(false); 129 VbglR3Term(); 130 return gpfnOldIOErrorHandler(pDisplay); 131 } 132 133 /** 134 * A standard signal handler which cleans up and exits. Our global static objects will 135 * be cleaned up properly as we exit using "exit". 136 */ 137 void vboxClientSignalHandler(int cSignal) 138 { 139 Log(("VBoxClient: terminated with signal %d\n", cSignal)); 140 /** Disable seamless mode */ 141 VbglR3SeamlessSetCap(false); 142 RTPrintf(("VBoxClient: terminating...\n")); 143 /* don't call VbglR3Term() here otherwise the /dev/vboxadd filehandle is closed */ 144 /* Our pause() call will now return and exit. */ 145 } 146 147 /** 148 * Reset all standard termination signals to call our signal handler, which cleans up 149 * and exits. 121 VBoxClient::CleanUp(); 122 return 0; /* We should never reach this. */ 123 } 124 125 /** 126 * Reset all standard termination signals to call our signal handler, which 127 * cleans up and exits. 150 128 */ 151 129 void vboxClientSetSignalHandlers(void) … … 174 152 void vboxClientUsage(const char *pcszFileName) 175 153 { 176 RTPrintf("Usage: %s [-d|--nodaemon]\n", pcszFileName);154 RTPrintf("Usage: %s --clipboard|--autoresize|--seamless [-d|--nodaemon]\n", pcszFileName); 177 155 RTPrintf("Start the VirtualBox X Window System guest services.\n\n"); 178 156 RTPrintf("Options:\n"); 179 RTPrintf(" -d, --nodaemon do not lower privileges and continue running as a system\n"); 180 RTPrintf(" service\n"); 157 RTPrintf(" --clipboard start the shared clipboard service\n"); 158 RTPrintf(" --autoresize start the display auto-resize service\n"); 159 RTPrintf(" --seamless start the seamless windows service\n"); 160 RTPrintf(" -d, --nodaemon continue running as a system service\n"); 181 161 RTPrintf("\n"); 182 162 exit(0); … … 191 171 const char *pszFileName = RTPathFilename(argv[0]); 192 172 bool fDaemonise = true; 173 /* Have any fatal errors occurred yet? */ 174 bool fSuccess = true; 175 /* Do we know which service we wish to run? */ 176 bool fHaveService = false; 193 177 194 178 if (NULL == pszFileName) … … 204 188 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--nodaemon")) 205 189 fDaemonise = false; 190 else if (!strcmp(argv[i], "--clipboard")) 191 { 192 if (g_pService == NULL) 193 g_pService = VBoxClient::GetClipboardService(); 194 else 195 fSuccess = false; 196 } 197 else if (!strcmp(argv[i], "--autoresize")) 198 { 199 if (g_pService == NULL) 200 g_pService = VBoxClient::GetAutoResizeService(); 201 else 202 fSuccess = false; 203 } 204 else if (!strcmp(argv[i], "--seamless")) 205 { 206 if (g_pService == NULL) 207 g_pService = VBoxClient::GetSeamlessService(); 208 else 209 fSuccess = false; 210 } 206 211 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) 207 212 { … … 216 221 } 217 222 } 223 if (!fSuccess || !g_pService) 224 { 225 vboxClientUsage(pszFileName); 226 exit(1); 227 } 218 228 if (fDaemonise) 219 229 { … … 221 231 if (RT_FAILURE(rc)) 222 232 { 223 RTPrintf("VBoxClient: failed to daemonize. exiting.\n"); 233 RTPrintf("VBoxClient: failed to daemonize. Exiting.\n"); 234 Log(("VBoxClient: failed to daemonize. Exiting.\n")); 224 235 #ifdef DEBUG 225 236 RTPrintf("Error %Rrc\n", rc); … … 228 239 } 229 240 } 241 const char *pszHome = RTEnvGet("HOME"); 242 if (pszHome == NULL) 243 { 244 RTPrintf("VBoxClient: failed to get home directory. Exiting.\n"); 245 Log(("VBoxClient: failed to get home directory. Exiting.\n")); 246 return 1; 247 } 248 if (RTStrAPrintf(&g_pszPidFile, "%s/%s", pszHome, g_pService->getPidFilePath()) == -1) 249 if (pszHome == NULL) 250 { 251 RTPrintf("VBoxClient: out of memory. Exiting.\n"); 252 Log(("VBoxClient: out of memory. Exiting.\n")); 253 return 1; 254 } 230 255 /* Initialise the guest library. */ 231 if (RT_FAILURE(VbglR3Init ()))256 if (RT_FAILURE(VbglR3InitUser())) 232 257 { 233 258 RTPrintf("Failed to connect to the VirtualBox kernel service\n"); 234 return 1; 235 } 236 if (fDaemonise && RT_FAILURE(vboxClientDropPrivileges())) 237 return 1; 238 LogRel(("VBoxClient: starting...\n")); 239 /* Initialise threading in X11 and in Xt. */ 240 if (!XInitThreads() || !XtToolkitThreadInitialize()) 241 { 242 LogRel(("VBoxClient: error initialising threads in X11, exiting.\n")); 243 return 1; 244 } 259 Log(("Failed to connect to the VirtualBox kernel service\n")); 260 return 1; 261 } 262 if (g_pszPidFile && RT_FAILURE(VbglR3PidFile(g_pszPidFile, &g_hPidFile))) 263 { 264 RTPrintf("Failed to create a pidfile. Exiting.\n"); 265 Log(("Failed to create a pidfile. Exiting.\n")); 266 VbglR3Term(); 267 return 1; 268 } 269 /* Set signal handlers to clean up on exit. */ 270 vboxClientSetSignalHandlers(); 245 271 /* Set an X11 error handler, so that we don't die when we get unavoidable errors. */ 246 272 XSetErrorHandler(vboxClientXLibErrorHandler); 247 273 /* Set an X11 I/O error handler, so that we can shutdown properly on fatal errors. */ 248 gpfnOldIOErrorHandler = XSetIOErrorHandler(vboxClientXLibIOErrorHandler); 249 vboxClientSetSignalHandlers(); 250 try 251 { 252 #ifdef VBOX_X11_CLIPBOARD 253 /* Connect to the host clipboard. */ 254 LogRel(("VBoxClient: starting clipboard Guest Additions...\n")); 255 rcClipboard = gClipboard.init(); 256 if (RT_FAILURE(rcClipboard)) 257 { 258 LogRel(("VBoxClient: vboxClipboardConnect failed with rc = %Rrc\n", rcClipboard)); 259 } 260 #endif /* VBOX_X11_CLIPBOARD defined */ 261 #ifdef DYNAMIC_RESIZE 262 LogRel(("VBoxClient: starting dynamic guest resizing...\n")); 263 rc = gDisplayChange.init(); 264 if (RT_FAILURE(rc)) 265 { 266 LogRel(("VBoxClient: failed to start dynamic guest resizing, rc = %Rrc\n", rc)); 267 } 268 # ifdef SEAMLESS_GUEST 269 if (RT_SUCCESS(rc)) 270 { 271 LogRel(("VBoxClient: starting seamless Guest Additions...\n")); 272 rc = gSeamless.init(); 273 if (RT_FAILURE(rc)) 274 { 275 LogRel(("VBoxClient: failed to start seamless Additions, rc = %Rrc\n", rc)); 276 } 277 } 278 # endif /* SEAMLESS_GUEST defined */ 279 #endif /* DYNAMIC_RESIZE defined */ 280 } 281 catch (std::exception e) 282 { 283 LogRel(("VBoxClient: failed to initialise Guest Additions - caught exception: %s\n", e.what())); 284 rc = VERR_UNRESOLVED_ERROR; 285 } 286 catch (...) 287 { 288 LogRel(("VBoxClient: failed to initialise Guest Additions - caught unknown exception.\n")); 289 rc = VERR_UNRESOLVED_ERROR; 290 } 291 LogRel(("VBoxClient: sleeping...\n")); 292 pause(); 293 LogRel(("VBoxClient: exiting...\n")); 294 try 295 { 296 /* r=frank: Why all these 2s delays? What are we waiting for? */ 297 #ifdef DYNAMIC_RESIZE 298 # ifdef SEAMLESS_GUEST 299 LogRel(("VBoxClient: shutting down seamless Guest Additions...\n")); 300 gSeamless.uninit(2000); 301 # endif /* SEAMLESS_GUEST defined */ 302 LogRel(("VBoxClient: shutting down dynamic guest resizing...\n")); 303 gDisplayChange.uninit(2000); 304 #endif /* DYNAMIC_RESIZE defined */ 305 #ifdef VBOX_X11_CLIPBOARD 306 /* Connect to the host clipboard. */ 307 LogRel(("VBoxClient: shutting down clipboard Guest Additions...\n")); 308 gClipboard.uninit(2000); 309 #endif /* VBOX_X11_CLIPBOARD defined */ 310 } 311 catch (std::exception e) 312 { 313 LogRel(("VBoxClient: failed to shut down Guest Additions - caught exception: %s\n", e.what())); 314 rc = VERR_UNRESOLVED_ERROR; 315 } 316 catch (...) 317 { 318 LogRel(("VBoxClient: failed to shut down Guest Additions - caught unknown exception.\n")); 319 rc = VERR_UNRESOLVED_ERROR; 320 } 321 VbglR3Term(); 322 return RT_SUCCESS(rc) ? 0 : 1; 323 } 274 XSetIOErrorHandler(vboxClientXLibIOErrorHandler); 275 g_pService->run(); 276 VBoxClient::CleanUp(); 277 return 1; /* We should never get here. */ 278 }
Note:
See TracChangeset
for help on using the changeset viewer.