VirtualBox

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

Additions/x11: some cleaning up in the VBoxClient module

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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    }
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