1
/*********************************************************
2
* Copyright (C) 2010 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License as published
6
* by the Free Software Foundation version 2.1 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
11
* License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
*********************************************************/
22
* Handles responding to X11 I/O errors.
25
#include "desktopEventsInt.h"
27
#include <sys/types.h>
32
static int gParentPid;
33
static ToolsAppCtx *gCtx;
34
static XIOErrorHandler gOrigHandler;
37
******************************************************************************
38
* DEXIOErrorHandler -- */ /**
40
* Handler for all X I/O errors. Xlib documentation says we should not
41
* return when handling I/O errors.
43
* @param[in] dpy Unused.
45
* @return 1 (but doesn't really return).
47
******************************************************************************
51
DEXIOErrorHandler(Display *dpy)
53
pid_t my_pid = getpid();
56
* ProcMgr_ExecAsync() needs to fork off a child to handle watching the
57
* process being run. When it dies, it will come through here, so we don't
58
* want to let it shut down the RPC channel.
60
if (my_pid == gParentPid) {
61
g_debug("%s", __func__);
64
* XXX: the really correct thing to do here would be to properly stop all
65
* plugins so that capabilities are unset and all other "clean shutdown"
66
* tasks are performed. Unfortunately two things currently prevent that:
68
* . we can't rely on g_main_loop_quit() because we can't return from this
69
* function (well, we can, but Xlib will exit() before vmtoolsd is able
70
* to clean up things), so the main loop will never regain control off
73
* . we can't access the internal vmtoolsd functions that cleanly shuts
76
* So, right now, let's stick with just stopping the RPC channel so that
77
* the host is notified the application is gone. This may cause temporary
78
* issues with clients that only look at capabilities and not at the
81
if (gCtx->rpc != NULL) {
82
RpcChannel_Stop(gCtx->rpc);
88
* _exit is used here so that any atexit() registered routines don't
89
* interfere with any resources shared with the parent.
91
g_debug("%s hit from forked() child", __func__);
100
******************************************************************************
101
* XIOError_Init -- */ /**
103
* Sets up an X11 I/O error callback that stops the daemon.
105
* @param[in] ctx Application context.
106
* @param[in] pdata Registration data.
110
******************************************************************************
114
XIOError_Init(ToolsAppCtx *ctx,
115
ToolsPluginData *pdata)
118
gParentPid = getpid();
119
gOrigHandler = XSetIOErrorHandler(DEXIOErrorHandler);
125
******************************************************************************
126
* XIOError_Shutdown -- */ /**
128
* Shutdown function, restores the original X I/O error handler.
130
* @param[in] ctx Application context.
131
* @param[in] pdata Plugin data (unused).
133
******************************************************************************
137
XIOError_Shutdown(ToolsAppCtx *ctx,
138
ToolsPluginData *pdata)
140
XSetIOErrorHandler(gOrigHandler);