From: VMware, Inc <> Date: Mon, 22 Mar 2010 22:30:08 +0000 (-0700) Subject: Internal branch sync. Included in this change: X-Git-Tag: 2010.03.20-243334~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7cdbb623125729b41bf54068568dfbcc2dd58733;p=thirdparty%2Fopen-vm-tools.git Internal branch sync. Included in this change: . Unity: 'Interlock' minimize operations through the host. . Close up va_list before exiting. . Shutdown Linux Copy Paste and DnD on X IO error properly. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/include/vm_version.h b/open-vm-tools/lib/include/vm_version.h index 6e688278b..ea960f1c4 100644 --- a/open-vm-tools/lib/include/vm_version.h +++ b/open-vm-tools/lib/include/vm_version.h @@ -449,7 +449,7 @@ #define PRODUCT_VERSION_WORKSTATION_5 PRODUCT_WORKSTATION_BRIEF_NAME " 5.x" #define PRODUCT_VERSION_WORKSTATION_6 PRODUCT_WORKSTATION_BRIEF_NAME " 6.0" #define PRODUCT_VERSION_WORKSTATION_65 PRODUCT_WORKSTATION_BRIEF_NAME " 6.5" -#define PRODUCT_VERSION_WORKSTATION_70 PRODUCT_WORKSTATION_BRIEF_NAME " 7.0" +#define PRODUCT_VERSION_WORKSTATION_7 PRODUCT_WORKSTATION_BRIEF_NAME " 7.x" #define PRODUCT_VERSION_WORKSTATION_80 PRODUCT_WORKSTATION_BRIEF_NAME " 8.0" #define PRODUCT_VERSION_WORKSTATION_ENTERPRISE_1 "ACE 1.x" #define PRODUCT_VERSION_WORKSTATION_ENTERPRISE_2 "ACE 2.0" diff --git a/open-vm-tools/lib/misc/posixPosix.c b/open-vm-tools/lib/misc/posixPosix.c index 6340664fb..d5df87d4c 100644 --- a/open-vm-tools/lib/misc/posixPosix.c +++ b/open-vm-tools/lib/misc/posixPosix.c @@ -957,6 +957,7 @@ Posix_Execl(ConstUnicode pathName, // IN: va_start(vl, arg0); for (i = 1; i < count; i++) { if (!PosixConvertToCurrent(va_arg(vl, char *), &argv[i])) { + va_end(vl); goto exit; } } @@ -1035,6 +1036,7 @@ Posix_Execlp(ConstUnicode fileName, // IN: va_start(vl, arg0); for (i = 1; i < count; i++) { if (!PosixConvertToCurrent(va_arg(vl, char *), &argv[i])) { + va_end(vl); goto exit; } } diff --git a/open-vm-tools/lib/unity/unity.c b/open-vm-tools/lib/unity/unity.c index 21192b7ed..9cd56f486 100644 --- a/open-vm-tools/lib/unity/unity.c +++ b/open-vm-tools/lib/unity/unity.c @@ -153,6 +153,12 @@ static Bool UnityTcloSetWindowDesktop(char const **result, const char *args, size_t argsSize, void *clientData); +static Bool UnityTcloConfirmOperation(char const **result, + size_t *resultLen, + const char *name, + const char *args, + size_t argsSize, + void *clientData); static void UnitySetAddHiddenWindows(Bool enabled); static void UnitySetInterlockMinimizeOperation(Bool enabled); @@ -482,6 +488,8 @@ Unity_InitBackdoor(struct RpcIn *rpcIn) // IN UnityTcloSetDesktopActive, NULL); RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_DESKTOP_SET, UnityTcloSetWindowDesktop, NULL); + RpcIn_RegisterCallback(rpcIn, UNITY_RPC_CONFIRM_OPERATION, + UnityTcloConfirmOperation, NULL); RpcIn_RegisterCallbackEx(rpcIn, UNITY_RPC_SET_OPTIONS, UnityTcloSetUnityOptions, NULL); @@ -1127,6 +1135,67 @@ UnityTcloGetUpdate(char const **result, // OUT } +/* + *---------------------------------------------------------------------------- + * + * UnityTcloConfirmOperation -- + * + * RPC handler for 'unity.operation.confirm'. + * + * Results: + * TRUE if the confirmation could be handled sucessfully. + * FALSE otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------------- + */ + +static Bool +UnityTcloConfirmOperation(char const **result, // OUT + size_t *resultLen, // OUT + const char *name, // IN + const char *args, // IN + size_t argsSize, // IN + void *clientData) // ignored +{ + UnityConfirmOperation unityConfirmOpMsg = {0}; + UnityConfirmOperationV1 *confirmV1 = NULL; + Bool retVal = FALSE; + unsigned int ret; + Debug("%s: Enter.\n", __FUNCTION__); + + /* + * Deserialize the XDR data. Note that the data begins with args + 1 since + * there is a space between the RPC name and the XDR serialization. + */ + if (!XdrUtil_Deserialize((char *)args + 1, argsSize - 1, + xdr_UnityConfirmOperation, &unityConfirmOpMsg)) { + ret = RpcIn_SetRetVals(result, resultLen, "Failed to deserialize data", FALSE); + goto exit; + } + + confirmV1 = unityConfirmOpMsg.UnityConfirmOperation_u.unityConfirmOpV1; + if (MINIMIZE == confirmV1->details.op) { + retVal = UnityPlatformConfirmMinimizeOperation(unity.up, + confirmV1->windowId, + confirmV1->sequence, + confirmV1->allow); + } else { + Debug("%s: Confirmation for unknown operation ID = %d\n", __FUNCTION__, + confirmV1->details.op); + } + /* Free any memory allocated by XDR - we're done with unityConfirmOpMsg */ + VMX_XDR_FREE(xdr_UnityConfirmOperation, &unityConfirmOpMsg); + ret = RpcIn_SetRetVals(result, resultLen, "", retVal); + +exit: + Debug("%s: Exit.\n", __FUNCTION__); + return ret; +} + + /* *---------------------------------------------------------------------------- * @@ -1250,6 +1319,12 @@ UnityUpdateCallbackFn(void *param, // IN: dynbuf break; case UNITY_UPDATE_REMOVE_WINDOW: + /* + * Let the platform know that this window has been removed. This is + * useful on platforms that must poll for window changes. + */ + UnityPlatformWillRemoveWindow(unity.up, update->u.removeWindow.id); + Str_Sprintf(data, sizeof data, "remove %u", update->u.removeWindow.id); DynBuf_AppendString(buf, data); break; @@ -2111,8 +2186,8 @@ UnityTcloSetUnityOptions(RpcInData *data) while (unityFeatureTable[featureIndex].featureBit != 0) { if (featuresChanged & unityFeatureTable[featureIndex].featureBit) { unityFeatureTable[featureIndex].setter( - optionsMsg.UnityOptions_u.unityOptionsV1->featureMask & - unityFeatureTable[featureIndex].featureBit); + (optionsMsg.UnityOptions_u.unityOptionsV1->featureMask & + unityFeatureTable[featureIndex].featureBit) != 0); } featureIndex++; } @@ -2261,6 +2336,76 @@ out: } +/* + *---------------------------------------------------------------------------- + * + * UnityXdrRequestOperation -- + * + * XDR encoder function for UnityRequestOperation. + * + * See UnityXdrSendRpc(). + * + * Results: + * Returns true if the XDR struct was encoded successfully. + * + * Side-effects: + * None. + *------------------------------------------------------------------------------ + */ + +Bool +UnityXdrRequestOperation(XDR *xdrs, // IN + void *arg) // IN +{ + ASSERT(xdrs); + ASSERT(arg); + return xdr_UnityRequestOperation(xdrs, (UnityRequestOperation *) arg); +} + + +/* + *------------------------------------------------------------------------------ + * + * UnitySendRequestMinimizeOperation -- + * + * Send a request for a minimize operation to the host. + * + * Results: + * TRUE if everything is successful. + * FALSE otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------------- + */ + +Bool +UnitySendRequestMinimizeOperation(UnityWindowId windowId, // IN + uint32 sequence) // IN +{ + Bool ret = FALSE; + UnityRequestOperation msg = { 0 }; + UnityRequestOperationV1 v1 = { 0 }; + + Debug("%s: Enter.\n", __FUNCTION__); + + v1.windowId = windowId; + v1.sequence = sequence; + v1.details.op = MINIMIZE; + + msg.ver = UNITY_OP_V1; + msg.UnityRequestOperation_u.unityRequestOpV1 = &v1; + + ret = UnityXdrSendRpc(UNITY_RPC_REQUEST_OPERATION, + &UnityXdrRequestOperation, + &msg); + + Debug("%s: Exit.\n", __FUNCTION__); + return ret; +} + + /* *---------------------------------------------------------------------------- * @@ -2407,6 +2552,7 @@ UnitySetInterlockMinimizeOperation(Bool enabled) Debug("%s: Do not interlock minimize operations through the host\n", __FUNCTION__); } + UnityPlatformSetInterlockMinimizeOperation(unity.up, enabled); } diff --git a/open-vm-tools/lib/unity/unityPlatform.h b/open-vm-tools/lib/unity/unityPlatform.h index 5f686707b..ff9a26cc0 100644 --- a/open-vm-tools/lib/unity/unityPlatform.h +++ b/open-vm-tools/lib/unity/unityPlatform.h @@ -28,7 +28,6 @@ #include "unityWindowTracker.h" #include "unity.h" - /** * Container used to store and send Unity updates. */ @@ -122,6 +121,11 @@ Bool UnityPlatformStickWindow(UnityPlatform *up, UnityWindowId windowId); Bool UnityPlatformUnstickWindow(UnityPlatform *up, UnityWindowId windowId); +void UnityPlatformSetInterlockMinimizeOperation(UnityPlatform *up,Bool enabled); +Bool UnityPlatformConfirmMinimizeOperation(UnityPlatform *up, + UnityWindowId windowId, + uint32 sequence, + Bool allow); Bool UnityPlatformIsUnityRunning(UnityPlatform *up); Bool UnityPlatformStartHelperThreads(UnityPlatform *up); void UnityPlatformKillHelperThreads(UnityPlatform *up); @@ -139,11 +143,20 @@ Bool UnityPlatformRequestWindowContents(UnityPlatform *up, UnityWindowId windowIds[], uint32 numWindowIds); +/* + * Function called by UnityUpdateCallbackFn whenever a window is removed from + * the tracker. + * + * NOTE: This function is called with the platform lock held. + */ +void UnityPlatformWillRemoveWindow(UnityPlatform *up, UnityWindowId windowId); + /* Functions implemented in unity.c for use by the platform-specific code. */ void UnityGetUpdateCommon(int flags, DynBuf *buf); Bool UnityUpdateChannelInit(UnityUpdateChannel *updateChannel); void UnityUpdateChannelCleanup(UnityUpdateChannel *updateChannel); Bool UnitySendUpdates(UnityUpdateChannel *updateChannel); +Bool UnitySendRequestMinimizeOperation(UnityWindowId windowId, uint32 sequence); /* Sends the provided window contents to the host. */ Bool UnitySendWindowContents(UnityWindowId windowID, diff --git a/open-vm-tools/lib/unity/unityPlatformX11.c b/open-vm-tools/lib/unity/unityPlatformX11.c index fe6ef1ba9..abd5f943d 100644 --- a/open-vm-tools/lib/unity/unityPlatformX11.c +++ b/open-vm-tools/lib/unity/unityPlatformX11.c @@ -3083,6 +3083,82 @@ UnityPlatformRequestWindowContents(UnityPlatform *up, } +/* + *----------------------------------------------------------------------------- + * + * UnityPlatformConfirmMinimizeOperation -- + * + * Minimize a window (if allowed) by the host. + * + * Results: + * Returns TRUE if successful, and FALSE otherwise. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------------ + */ + +Bool +UnityPlatformConfirmMinimizeOperation(UnityPlatform *up, // IN + UnityWindowId windowId, // IN + uint32 sequence, // IN + Bool allow) // IN +{ + ASSERT(up); + return FALSE; +} + + +/* + *----------------------------------------------------------------------------- + * + * UnityPlatformSetInterlockMinimizeOperation -- + * + * Enable (or Disable) the interlocking (relaying) of minimize operations + * through the host. + * + * Results: + * None. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------------ + */ + +void UnityPlatformSetInterlockMinimizeOperation(UnityPlatform *up, // IN + Bool enabled) // IN +{ + ASSERT(up); +} + + +/* + *------------------------------------------------------------------------------ + * + * UnityPlatformWillRemoveWindow -- + * + * Called when a window is removed from the UnityWindowTracker. + * + * NOTE: This function is called with the platform lock held. + * + * Results: + * None. + * + * Side effects: + * None. + *------------------------------------------------------------------------------ + */ + +void +UnityPlatformWillRemoveWindow(UnityPlatform *up, // IN + UnityWindowId windowId) // IN +{ + ASSERT(up); +} + + /* ****************************************************************************** * Begin file-scope functions. diff --git a/open-vm-tools/vmware-user/copyPasteDnDWrapper.cpp b/open-vm-tools/vmware-user/copyPasteDnDWrapper.cpp index fe9f1c639..65d64f8fd 100644 --- a/open-vm-tools/vmware-user/copyPasteDnDWrapper.cpp +++ b/open-vm-tools/vmware-user/copyPasteDnDWrapper.cpp @@ -220,6 +220,25 @@ CopyPasteDnDWrapper::RegisterCP() } +/** + * + * Cancel DnD and copy paste. + */ + +void +CopyPasteDnDWrapper::Cancel() +{ +#if defined(HAVE_GTKMM) + if (m_dndUI) { + m_dndUI->Cancel(); + } + if (m_copyPasteUI) { + m_copyPasteUI->Cancel(); + } +#endif +} + + /** * * Register DnD capabilities with the VMX. Try newest version diff --git a/open-vm-tools/vmware-user/copyPasteDnDWrapper.h b/open-vm-tools/vmware-user/copyPasteDnDWrapper.h index 0e6c8f774..474c67251 100644 --- a/open-vm-tools/vmware-user/copyPasteDnDWrapper.h +++ b/open-vm-tools/vmware-user/copyPasteDnDWrapper.h @@ -61,6 +61,7 @@ public: void SetDnDIsRegistered(bool isRegistered); bool IsDnDRegistered(); void OnReset(); + void Cancel(); void SetBlockControl(DnDBlockControl *blockCtrl); void SetUserData(const void *userData); void SetHGWnd(GtkWidget *wnd) {m_hgWnd = wnd;}; diff --git a/open-vm-tools/vmware-user/copyPasteUI.cpp b/open-vm-tools/vmware-user/copyPasteUI.cpp index 8ffb5909f..46f923625 100644 --- a/open-vm-tools/vmware-user/copyPasteUI.cpp +++ b/open-vm-tools/vmware-user/copyPasteUI.cpp @@ -150,6 +150,37 @@ CopyPasteUI::~CopyPasteUI() } +/* + *----------------------------------------------------------------------------- + * + * CopyPasteUI::Cancel -- + * + * Cancel file transfer and remove block. + * + * Results: + * None. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +void +CopyPasteUI::Cancel() +{ + Debug("%s: enter\n", __FUNCTION__); + if (mBlockAdded) { + DnD_DeleteStagingFiles(mHGStagingDir.c_str(), FALSE); + Debug("%s: removing block for %s\n", __FUNCTION__, mHGStagingDir.c_str()); + mBlockCtrl->RemoveBlock(mBlockCtrl->fd, mHGStagingDir.c_str()); + mBlockAdded = false; + } + + mFileTransferDone = true; +} + + /* *----------------------------------------------------------------------------- * diff --git a/open-vm-tools/vmware-user/copyPasteUI.h b/open-vm-tools/vmware-user/copyPasteUI.h index 66d856a5b..5bb4a7907 100644 --- a/open-vm-tools/vmware-user/copyPasteUI.h +++ b/open-vm-tools/vmware-user/copyPasteUI.h @@ -60,6 +60,7 @@ public: void SetCopyPasteAllowed(bool isCopyPasteAllowed) { mCP.SetCopyPasteAllowed(isCopyPasteAllowed); } void Reset(void); + void Cancel(void); void SetBlockControl(DnDBlockControl *blockCtrl) { Debug("Setting mBlockCtrl to %p\n", blockCtrl); mBlockCtrl = blockCtrl; } diff --git a/open-vm-tools/vmware-user/dndUI.cpp b/open-vm-tools/vmware-user/dndUI.cpp index 7598c75b1..94a88c4f1 100644 --- a/open-vm-tools/vmware-user/dndUI.cpp +++ b/open-vm-tools/vmware-user/dndUI.cpp @@ -271,6 +271,26 @@ DnDUI::CommonResetCB(void) } +/** + * + * Cancel any DnD file transfers and reset. + */ + +void +DnDUI::Cancel() +{ + Debug("%s: enter\n", __FUNCTION__); + if (m_blockAdded) { + /* + * If we don't do this, the destination will have something to + * copy, and likely truncated. So remove it. + */ + DnD_DeleteStagingFiles(m_HGStagingDir.c_str(), false); + } + CommonResetCB(); +} + + /* Source functions for HG DnD. */ /** @@ -499,6 +519,10 @@ DnDUI::CommonUpdateDetWndCB(bool bShow, int32 x, int32 y) { + Debug("%s: enter 0x%lx show %d x %d y %d\n", + __FUNCTION__, + (unsigned long) m_detWnd->get_window()->gobj(), bShow, x, y); + /* If the window is being shown, move it to the right place. */ if (bShow) { x = MAX(x - DRAG_DET_WINDOW_WIDTH / 2, 0); @@ -538,6 +562,10 @@ DnDUI::CommonUpdateUnityDetWndCB(bool bShow, uint32 unityWndId, bool bottom) { + Debug("%s: enter 0x%lx unityID 0x%x\n", + __FUNCTION__, + (unsigned long) m_detWnd->get_window()->gobj(), + unityWndId); if (bShow && ((unityWndId > 0) || bottom)) { int width = m_detWnd->GetScreenWidth(); int height = m_detWnd->GetScreenHeight(); @@ -650,9 +678,9 @@ DnDUI::GtkDestDragMotionCB(const Glib::RefPtr &dc, /* * If this is a Host to Guest drag, we are done here, so return. */ - Debug("%s: enter", __FUNCTION__); - unsigned long curTime = GetTimeInMillis(); + Debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__, + dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL); if (curTime - m_destDropTime <= 1000) { Debug("%s: ignored %ld %ld %ld\n", __FUNCTION__, curTime, m_destDropTime, curTime - m_destDropTime); @@ -763,7 +791,21 @@ void DnDUI::GtkDestDragLeaveCB(const Glib::RefPtr &dc, guint time) { - Debug("%s: enter\n", __FUNCTION__); + Debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__, + dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL); + + /* + * If we reach here after reset DnD, or we are getting a late + * DnD drag leave signal (we have started another DnD), then + * finish the old DnD. Otherwise, Gtk will not reset and a new + * DnD will not start until Gtk+ times out (which appears to + * be 5 minutes). + * See http://bugzilla.eng.vmware.com/show_bug.cgi?id=528320 + */ + if (!m_dc || dc->gobj() != m_dc) { + Debug("%s: calling drag_finish\n", __FUNCTION__); + dc->drag_finish(true, false, time); + } } @@ -822,7 +864,9 @@ DnDUI::GtkSourceDragDataGetCB(const Glib::RefPtr &dc, selection_data.set(target.c_str(), ""); - Debug("%s: enter with target %s\n", __FUNCTION__, target.c_str()); + Debug("%s: enter dc %p, m_dc %p with target %s\n", __FUNCTION__, + dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL, + target.c_str()); if (!m_inHGDrag) { Debug("%s: not in drag, return\n", __FUNCTION__); @@ -994,7 +1038,8 @@ DnDUI::GtkDestDragDataReceivedCB(const Glib::RefPtr &dc, guint info, guint time) { - Debug("%s: enter\n", __FUNCTION__); + Debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__, + dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL); /* The GH DnD may already finish before we got response. */ if (!m_GHDnDInProgress) { Debug("%s: not valid\n", __FUNCTION__); @@ -1060,7 +1105,8 @@ DnDUI::GtkDestDragDropCB(const Glib::RefPtr &dc, int y, guint time) { - Debug("%s: enter x %d y %d\n", __FUNCTION__, x, y); + Debug("%s: enter dc %p, m_dc %p x %d y %d\n", __FUNCTION__, + (dc ? dc->gobj() : NULL), (m_dc ? m_dc : NULL), x, y); Glib::ustring target; diff --git a/open-vm-tools/vmware-user/dndUI.h b/open-vm-tools/vmware-user/dndUI.h index 233086c25..ab9925a9a 100644 --- a/open-vm-tools/vmware-user/dndUI.h +++ b/open-vm-tools/vmware-user/dndUI.h @@ -67,6 +67,7 @@ public: void SetBlockControl(DnDBlockControl *blockCtrl); void SetUnityMode(Bool mode) {m_unityMode = mode;}; + void Cancel(); DragDetWnd *GetFullDetWnd() {return m_detWnd;} GtkWidget *GetDetWndAsWidget(); diff --git a/open-vm-tools/vmware-user/vmware-user.cpp b/open-vm-tools/vmware-user/vmware-user.cpp index 3ebd2f3bd..28ac5c25e 100644 --- a/open-vm-tools/vmware-user/vmware-user.cpp +++ b/open-vm-tools/vmware-user/vmware-user.cpp @@ -176,8 +176,9 @@ static int const gSignals[] = { *----------------------------------------------------------------------------- */ -void VMwareUserCleanupRpc(void) +void VMwareUserCleanupRpc(Bool isXError) // IN { + Debug("%s: enter\n", __FUNCTION__); if (gRpcIn) { Unity_UnregisterCaps(); GHI_Cleanup(); @@ -190,7 +191,7 @@ void VMwareUserCleanupRpc(void) } if (!RpcIn_stop(gRpcIn)) { - Debug("Failed to stop RpcIn loop\n"); + Debug("%s: failed to stop RpcIn loop\n", __FUNCTION__); } if (gOpenUrlRegistered) { FoundryToolsDaemon_UnregisterOpenUrl(); @@ -198,10 +199,23 @@ void VMwareUserCleanupRpc(void) } CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance(); + + /* + * We can't call the normal APIs to tear down DnD/CP because they + * involve Xlib calls that can't be made after X IO error. So, use + * an entry point that performs a subset of the cleanup we normally + * do on a reset, to ensure that any file transfers in flight get + * failed properly. See bug 458626. + */ if (p) { - p->UnregisterDnD(); - p->UnregisterCP(); + if (!isXError) { + p->UnregisterDnD(); + p->UnregisterCP(); + } else { + p->Cancel(); + } } + RpcIn_Destruct(gRpcIn); gRpcIn = NULL; } @@ -241,7 +255,7 @@ void VMwareUserSignalHandler(int sig) // IN } if (gSigExit) { - VMwareUserCleanupRpc(); + VMwareUserCleanupRpc(FALSE); } #if defined(HAVE_GTKMM) @@ -273,7 +287,7 @@ void VMwareUser_OnDestroy(GtkWidget *widget, // IN: Unused gpointer data) // IN: Unused { - VMwareUserCleanupRpc(); + VMwareUserCleanupRpc(FALSE); #if defined(HAVE_GTKMM) Gtk::Main::quit(); #else @@ -653,13 +667,13 @@ int VMwareUserXIOErrorHandler(Display *dpy) * watching the process being run. When it dies, it will come * through here, so we don't want to let it shut down the Rpc */ - Debug("> VMwareUserXIOErrorHandler\n"); + Debug("> %s\n", __FUNCTION__); if (my_pid == gParentPid) { - VMwareUserCleanupRpc(); + VMwareUserCleanupRpc(TRUE); ReloadSelf(); exit(EXIT_FAILURE); } else { - Debug("VMwareUserXIOErrorHandler hit from forked() child, not cleaning Rpc\n"); + Debug("%s hit from forked() child, not cleaning Rpc\n", __FUNCTION__); _exit(EXIT_FAILURE); }