VirtualBox

Changeset 7264 in vbox for trunk/src/VBox/Additions/x11


Ignore:
Timestamp:
Mar 4, 2008 9:14:24 AM (17 years ago)
Author:
vboxsync
Message:

Additions/x11: some cleaning up in the VBoxClient module

Location:
trunk/src/VBox/Additions/x11/xclient
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/xclient/clipboard.cpp

    r7118 r7264  
    4848# define LogFlow(a) do {} while (0)
    4949#endif
     50
     51#define TRACE printf("%s: %d\n", __PRETTY_FUNCTION__, __LINE__); Log(("%s: %d\n", __PRETTY_FUNCTION__, __LINE__))
    5052
    5153/** The formats which we support in the guest. These can be deactivated in order to test specific code paths. */
     
    13571359
    13581360    AssertReturn(g_ctx.client != 0, (void) 0);
    1359 #if 0
    1360     /* Currently, disconnecting is not needed, as the new "connect clipboard" ioctl in the Guest Additions kernel
    1361      * module disconnects the last connection made automatically.  The reason for this change was that currently
    1362      * only one clipboard connection is allowed, and that if the client holding that connection was terminated
    1363      * too abruptly, the information needed to disconnect that connection was lost.  If the subsystem is ever
    1364      * changed to allow several connections, this will have to be rethought.
    1365      */
    1366     vmmdevInitRequest((VMMDevRequestHeader*)&request, VMMDevReq_HGCMDisconnect);
    1367     request.u32ClientID = g_ctx.client;
    1368     ioctl(g_ctx.sendDevice, IOCTL_VBOXGUEST_VMMREQUEST, (void*)&request);
    1369 #endif
     1361    VbglR3ClipboardDisconnect(g_ctx.client);
    13701362    LogFlowFunc(("returning\n"));
    13711363}
     
    14761468    LogFlowFunc(("\n"));
    14771469
     1470    TRACE;
    14781471    rc = vboxClipboardCreateWindow();
    14791472    if (VBOX_FAILURE(rc))
    14801473        return rc;
    14811474
     1475    TRACE;
    14821476    rc = RTThreadCreate(&g_ctx.thread, vboxClipboardThread, 0, 0, RTTHREADTYPE_IO,
    14831477                        RTTHREADFLAGS_WAITABLE, "SHCLIP");
    14841478    AssertRCReturn(rc, rc);
    14851479    /* Set up a timer to poll the host clipboard */
     1480    TRACE;
    14861481    XtAppAddTimeOut(g_ctx.appContext, 200 /* ms */, vboxClipboardTimerProc, 0);
    14871482
     1483    TRACE;
    14881484    XtAppMainLoop(g_ctx.appContext);
     1485    TRACE;
    14891486    g_ctx.formatList.clear();
     1487    TRACE;
    14901488    XtDestroyApplicationContext(g_ctx.appContext);
    14911489    /* Set the termination signal. */
    14921490    RTSemEventSignal(g_ctx.terminating);
    14931491    LogFlowFunc(("returning %d\n", rc));
     1492    TRACE;
    14941493    return rc;
    14951494}
  • trunk/src/VBox/Additions/x11/xclient/clipboard.h

    r6202 r7264  
    2020# define __Additions_linux_clipboard_h
    2121
     22#include "thread.h"                 /* for VBoxGuestThread */
     23
    2224extern void vboxClipboardDisconnect (void);
    2325extern int vboxClipboardConnect (void);
    2426extern int vboxClipboardMain (void);
    2527
     28/**
     29 * Display change request monitor thread function
     30 */
     31class VBoxGuestClipboardThread : public VBoxGuestThreadFunction
     32{
     33private:
     34    // Copying or assigning a thread object is not sensible
     35    VBoxGuestClipboardThread(const VBoxGuestClipboardThread&);
     36    VBoxGuestClipboardThread& operator=(const VBoxGuestClipboardThread&);
     37
     38    // Private member variables
     39    /** Have we been initialised yet? */
     40    bool mInit;
     41    /** The thread object running us. */
     42    VBoxGuestThread *mThread;
     43public:
     44    VBoxGuestClipboardThread() { mInit = false; }
     45    /**
     46     * Initialise the class and check that the guest supports dynamic resizing.
     47     * @returns iprt status value
     48     */
     49    int init(void)
     50    {
     51        if (mInit)
     52            return true;
     53        return vboxClipboardConnect();
     54    }
     55    /**
     56     * The actual thread function.
     57     *
     58     * @returns iprt status code as thread return value
     59     * @param pParent the VBoxGuestThread running this thread function
     60     */
     61    virtual int threadFunction(VBoxGuestThread *pThread)
     62    {
     63        vboxClipboardMain();
     64        return VINF_SUCCESS;
     65    }
     66    /**
     67     * Send a signal to the thread function that it should exit
     68     */
     69    virtual void stop(void) { vboxClipboardDisconnect(); }
     70};
     71
     72class VBoxGuestClipboard
     73{
     74private:
     75    /** No copying or assignment. */
     76    VBoxGuestClipboard(const VBoxGuestClipboard &);
     77    VBoxGuestClipboard& operator=(const VBoxGuestClipboard &);
     78
     79    /** Our monitor thread function */
     80    VBoxGuestClipboardThread mThreadFunction;
     81    /** And the thread for the thread function */
     82    VBoxGuestThread mThread;
     83    /** Are we initialised? */
     84    bool mInit;
     85public:
     86    /**
     87     * Initialise the class.
     88     * @returns iprt status value
     89     */
     90    int init(void)
     91    {
     92        int rc = mThreadFunction.init();
     93        if (RT_SUCCESS(rc))
     94            rc = mThread.start();
     95        if (RT_SUCCESS(rc))
     96            mInit = true;
     97        return rc;
     98    }
     99    /**
     100     * Uninitialise the class.
     101     * @param cMillies how long to wait for the thread to stop
     102     */
     103    void uninit(unsigned cMillies = RT_INDEFINITE_WAIT)
     104    {
     105        if (mInit)
     106            mThread.stop(cMillies, NULL);
     107    }
     108
     109    VBoxGuestClipboard() : mThread(&mThreadFunction, 0, RTTHREADTYPE_MSG_PUMP,
     110                                   RTTHREADFLAGS_WAITABLE, "SHCLIP MAIN")
     111    { mInit = false; }
     112    ~VBoxGuestClipboard()
     113    {
     114        if (mInit)
     115            try {
     116                uninit(2000);
     117            } catch (...) { }
     118    }
     119};
     120
    26121#endif /* __Additions_linux_clipboard_h not defined */
  • trunk/src/VBox/Additions/x11/xclient/main.cpp

    r7008 r7264  
    2222#include <VBox/log.h>
    2323#include <iprt/initterm.h>
     24#include <iprt/path.h>
    2425
    2526#include <iostream>
     27#include <cstdio>
    2628
    2729#include <sys/types.h>
    2830#include <stdlib.h>       /* For exit */
    2931#include <unistd.h>
    30 #include <getopt.h>
    3132#include <errno.h>
     33#include <signal.h>
    3234
    3335#include <X11/Xlib.h>
     
    4345#endif
    4446
    45 static bool gbDaemonise = true;
     47#define TRACE printf("%s: %d\n", __PRETTY_FUNCTION__, __LINE__); Log(("%s: %d\n", __PRETTY_FUNCTION__, __LINE__))
     48
    4649static int (*gpfnOldIOErrorHandler)(Display *) = NULL;
     50
     51/* Make these global so that the destructors are called if we make an "emergency exit",
     52   i.e. a (handled) signal or an X11 error. */
     53#ifdef DYNAMIC_RESIZE
     54VBoxGuestDisplayChangeMonitor gDisplayChange;
     55# ifdef SEAMLESS_GUEST
     56    /** Our instance of the seamless class.  This only makes sense if dynamic resizing
     57        is enabled. */
     58    VBoxGuestSeamless gSeamless;
     59# endif /* SEAMLESS_GUEST defined */
     60#endif /* DYNAMIC_RESIZE */
     61#ifdef VBOX_X11_CLIPBOARD
     62    VBoxGuestClipboard gClipboard;
     63#endif
    4764
    4865/**
     
    90107        return 0;
    91108    }
    92 #ifdef VBOX_X11_CLIPBOARD
    93     vboxClipboardDisconnect();
    94 #endif
    95109    XGetErrorText(pDisplay, pError->error_code, errorText, sizeof(errorText));
    96110    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));
     
    110124}
    111125
     126/**
     127 * A standard signal handler which cleans up and exits.  Our global static objects will
     128 * be cleaned up properly as we exit using "exit".
     129 */
     130void vboxClientSignalHandler(int cSignal)
     131{
     132    Log(("VBoxClient: terminated with signal %d\n", cSignal));
     133    /* Our pause() call will now return and exit. */
     134}
     135
     136/**
     137 * Reset all standard termination signals to call our signal handler, which cleans up
     138 * and exits.
     139 */
     140void vboxClientSetSignalHandlers(void)
     141{
     142    struct sigaction sigAction = { { 0 } };
     143
     144    sigAction.sa_handler = vboxClientSignalHandler;
     145    sigemptyset(&sigAction.sa_mask);
     146    sigaction(SIGHUP, &sigAction, NULL);
     147    sigaction(SIGINT, &sigAction, NULL);
     148    sigaction(SIGQUIT, &sigAction, NULL);
     149    sigaction(SIGABRT, &sigAction, NULL);
     150    sigaction(SIGPIPE, &sigAction, NULL);
     151    sigaction(SIGALRM, &sigAction, NULL);
     152    sigaction(SIGTERM, &sigAction, NULL);
     153    sigaction(SIGUSR1, &sigAction, NULL);
     154    sigaction(SIGUSR2, &sigAction, NULL);
     155}
     156
     157/**
     158 * Print out a usage message and exit with success.
     159 */
     160void vboxClientUsage(const char *pcszFileName)
     161{
     162    /* printf is better for i18n than iostream. */
     163    printf("Usage: %s [-d|--nodaemon]\n", pcszFileName);
     164    printf("Start the VirtualBox X Window System guest services.\n\n");
     165    printf("Options:\n");
     166    printf("  -d, --nodaemon   do not lower privileges and continue running as a system\n");
     167    printf("                   service\n");
     168    exit(0);
     169}
     170
     171/**
     172 * The main loop for the VBoxClient daemon.
     173 */
    112174int main(int argc, char *argv[])
    113175{
    114176    int rcClipboard, rc = VINF_SUCCESS;
    115 #ifdef DYNAMIC_RESIZE
    116     VBoxGuestDisplayChangeMonitor displayChange;
    117 # ifdef SEAMLESS_GUEST
    118     /** Our instance of the seamless class.  This only makes sense if dynamic resizing
    119         is enabled. */
    120     VBoxGuestSeamless seamless;
    121 # endif /* SEAMLESS_GUEST defined */
    122 #endif /* DYNAMIC_RESIZE */
    123 
     177    const char *pszFileName = RTPathFilename(argv[0]);
     178    bool fDaemonise = true;
     179
     180    if (NULL == pszFileName)
     181        pszFileName = "VBoxClient";
     182
     183    TRACE;
    124184    /* Parse our option(s) */
    125 /** @todo r=bird: use RTGetOpt */
    126     while (1)
    127     {
    128         static struct option sOpts[] =
    129         {
    130             {"nodaemon", 0, 0, 'd'},
    131             {0, 0, 0, 0}
    132         };
    133         int cOpt = getopt_long(argc, argv, "", sOpts, 0);
    134         if (cOpt == -1)
    135         {
    136             if (optind < argc)
    137             {
    138                 std::cout << "Unrecognized command line argument: " << argv[argc] << std::endl;
    139                 exit(1);
    140             }
    141             break;
    142         }
    143         switch(cOpt)
    144         {
    145         case 'd':
    146             gbDaemonise = false;
    147             break;
    148         default:
    149             std::cout << "Unrecognized command line option: " << static_cast<char>(cOpt)
    150                       << std::endl;
    151         case '?':
     185    /** @todo Use RTGetOpt() if the arguments become more complex. */
     186    for (int i = 1; i < argc; ++i)
     187    {
     188        if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--nodaemon"))
     189            fDaemonise = false;
     190        else if (!strcmp(argv[i], "-h") || strcmp(argv[i], "--help"))
     191        {
     192            vboxClientUsage(pszFileName);
     193            exit(0);
     194        }
     195        else
     196        {
     197            /* printf is better than iostream for i18n. */
     198            printf("%s: unrecognized option `%s'\n", pszFileName, argv[i]);
     199            printf("Try `%s --help' for more information\n", pszFileName);
    152200            exit(1);
    153201        }
    154202    }
    155     if (gbDaemonise)
     203    TRACE;
     204    if (fDaemonise)
    156205    {
    157206        rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */);
     
    163212    }
    164213    /* Initialise our runtime before all else. */
     214    TRACE;
    165215    RTR3Init(false);
    166216    if (RT_FAILURE(VbglR3Init()))
     
    169219        return 1;
    170220    }
    171     if (RT_FAILURE(vboxClientDropPrivileges()))
     221    TRACE;
     222    if (fDaemonise && RT_FAILURE(vboxClientDropPrivileges()))
    172223        return 1;
    173224    LogRel(("VBoxClient: starting...\n"));
     
    182233    /* Set an X11 I/O error handler, so that we can shutdown properly on fatal errors. */
    183234    gpfnOldIOErrorHandler = XSetIOErrorHandler(vboxClientXLibIOErrorHandler);
     235    vboxClientSetSignalHandlers();
     236    try
     237    {
    184238#ifdef VBOX_X11_CLIPBOARD
    185     /* Connect to the host clipboard. */
    186     LogRel(("VBoxClient: starting clipboard Guest Additions...\n"));
    187     rcClipboard = vboxClipboardConnect();
    188     if (RT_FAILURE(rcClipboard))
    189     {
    190         LogRel(("VBoxClient: vboxClipboardConnect failed with rc = %Rrc\n", rc));
    191     }
     239        /* Connect to the host clipboard. */
     240        LogRel(("VBoxClient: starting clipboard Guest Additions...\n"));
     241        rcClipboard = gClipboard.init();
     242        if (RT_FAILURE(rcClipboard))
     243        {
     244            LogRel(("VBoxClient: vboxClipboardConnect failed with rc = %Rrc\n", rc));
     245        }
    192246#endif  /* VBOX_X11_CLIPBOARD defined */
    193     try
    194     {
    195247#ifdef DYNAMIC_RESIZE
    196248        LogRel(("VBoxClient: starting dynamic guest resizing...\n"));
    197         rc = displayChange.init();
     249        rc = gDisplayChange.init();
    198250        if (RT_FAILURE(rc))
    199251        {
     
    204256        {
    205257            LogRel(("VBoxClient: starting seamless Guest Additions...\n"));
    206             rc = seamless.init();
     258            rc = gSeamless.init();
    207259            if (RT_FAILURE(rc))
    208260            {
     
    215267    catch (std::exception e)
    216268    {
    217         LogRel(("VBoxClient: failed to initialise seamless Additions - caught exception: %s\n", e.what()));
     269        LogRel(("VBoxClient: failed to initialise Guest Additions - caught exception: %s\n", e.what()));
    218270        rc = VERR_UNRESOLVED_ERROR;
    219271    }
    220272    catch (...)
    221273    {
    222         LogRel(("VBoxClient: failed to initialise seamless Additions - caught unknown exception.\n"));
     274        LogRel(("VBoxClient: failed to initialise Guest Additions - caught unknown exception.\n"));
    223275        rc = VERR_UNRESOLVED_ERROR;
    224276    }
    225 #ifdef VBOX_X11_CLIPBOARD
    226     if (RT_SUCCESS(rcClipboard))
    227     {
    228         LogRel(("VBoxClient: connecting to the shared clipboard service.\n"));
    229         vboxClipboardMain();
    230         vboxClipboardDisconnect();
    231     }
    232 #else  /* VBOX_X11_CLIPBOARD not defined */
    233277    LogRel(("VBoxClient: sleeping...\n"));
    234278    pause();
    235279    LogRel(("VBoxClient: exiting...\n"));
    236 #endif  /* VBOX_X11_CLIPBOARD not defined */
    237280    try
    238281    {
    239282#ifdef DYNAMIC_RESIZE
    240         displayChange.uninit();
    241283# ifdef SEAMLESS_GUEST
    242         seamless.uninit();
     284        LogRel(("VBoxClient: shutting down seamless Guest Additions...\n"));
     285        gSeamless.uninit(2000);
    243286# endif /* SEAMLESS_GUEST defined */
     287        LogRel(("VBoxClient: shutting down dynamic guest resizing...\n"));
     288        gDisplayChange.uninit(2000);
    244289#endif /* DYNAMIC_RESIZE defined */
     290#ifdef VBOX_X11_CLIPBOARD
     291        /* Connect to the host clipboard. */
     292        LogRel(("VBoxClient: shutting down clipboard Guest Additions...\n"));
     293        gClipboard.uninit(2000);
     294#endif  /* VBOX_X11_CLIPBOARD defined */
    245295    }
    246296    catch (std::exception e)
    247297    {
    248         LogRel(("VBoxClient: error shutting down seamless Additions - caught exception: %s\n", e.what()));
     298        LogRel(("VBoxClient: failed to shut down Guest Additions - caught exception: %s\n", e.what()));
    249299        rc = VERR_UNRESOLVED_ERROR;
    250300    }
    251301    catch (...)
    252302    {
    253         LogRel(("VBoxClient: error shutting down seamless Additions - caught unknown exception.\n"));
     303        LogRel(("VBoxClient: failed to shut down Guest Additions - caught unknown exception.\n"));
    254304        rc = VERR_UNRESOLVED_ERROR;
    255305    }
  • trunk/src/VBox/Additions/x11/xclient/seamless.h

    r6959 r7264  
    168168    }
    169169
    170     void uninit(void)
     170    void uninit(unsigned cMillies = RT_INDEFINITE_WAIT)
    171171    {
    172172        if (isInitialised)
    173173        {
    174174            mHost.stop();
    175             mGuestThread.stop(RT_INDEFINITE_WAIT, 0);
     175            mGuestThread.stop(cMillies, 0);
    176176            mGuest.uninit();
    177177            isInitialised = false;
Note: See TracChangeset for help on using the changeset viewer.

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