LCOV - code coverage report
Current view: directory - apps - gdalserver.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 142 83 58.5 %
Date: 2013-03-30 Functions: 4 3 75.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdalserver.c 25684 2013-02-25 15:40:26Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL
       5                 :  * Purpose:  Server application that is forked by libgdal
       6                 :  * Author:   Even Rouault, <even dot rouault at mines-paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2013, Even Rouault, <even dot rouault at mines-paris dot org>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "cpl_port.h"
      31                 : 
      32                 : #ifdef WIN32
      33                 :   #ifndef _WIN32_WINNT
      34                 :     #define _WIN32_WINNT 0x0501
      35                 :   #endif
      36                 :   #include <winsock2.h>
      37                 :   #include <ws2tcpip.h>
      38                 :   typedef SOCKET CPL_SOCKET;
      39                 :   #ifndef HAVE_GETADDRINFO
      40                 :     #define HAVE_GETADDRINFO 1
      41                 :   #endif
      42                 : #else
      43                 :   #include <sys/time.h>
      44                 :   #include <sys/types.h>
      45                 :   #include <sys/wait.h>
      46                 :   #include <sys/socket.h>
      47                 :   #include <sys/un.h>
      48                 :   #include <netinet/in.h>
      49                 :   #include <unistd.h>
      50                 :   #ifdef HAVE_GETADDRINFO
      51                 :     #include <netdb.h>
      52                 :   #endif
      53                 :   typedef int CPL_SOCKET;
      54                 :   #define INVALID_SOCKET -1
      55                 :   #define SOCKET_ERROR -1
      56                 :   #define SOCKADDR struct sockaddr
      57                 :   #define WSAGetLastError() errno
      58                 :   #define WSACleanup()
      59                 :   #define closesocket(s) close(s)
      60                 :   #ifndef SOMAXCONN
      61                 :   #define SOMAXCONN 128
      62                 :   #endif 
      63                 : #endif
      64                 : 
      65                 : 
      66                 : #include <gdal.h>
      67                 : #include "cpl_spawn.h"
      68                 : #include "cpl_string.h"
      69                 : 
      70                 : CPL_C_START
      71                 : int CPL_DLL GDALServerLoop(CPL_FILE_HANDLE fin, CPL_FILE_HANDLE fout);
      72                 : int CPL_DLL GDALServerLoopSocket(CPL_SOCKET nSocket);
      73                 : CPL_C_END
      74                 : 
      75                 : CPL_CVSID("$Id: gdalserver.c 25684 2013-02-25 15:40:26Z rouault $");
      76                 : 
      77                 : /************************************************************************/
      78                 : /*                               Usage()                                */
      79                 : /************************************************************************/
      80                 : 
      81               0 : void Usage(const char* pszErrorMsg)
      82                 : 
      83                 : {
      84                 : #ifdef WIN32
      85                 :     printf( "Usage: gdalserver [--help-general] [--help] [-tcpserver port | -stdinout]\n");
      86                 : #else
      87               0 :     printf( "Usage: gdalserver [--help-general] [--help] [-tcpserver port | -unixserver filename | -stdinout | [-pipe_in fdin,fdtoclose -pipe_out fdout,fdtoclose]]\n");
      88                 : #endif
      89               0 :     printf( "\n" );
      90               0 :     printf( "-tcpserver : Launch a TCP server on the specified port that can accept.\n");
      91               0 :     printf( "             connections from GDAL clients.\n");
      92               0 :     printf( "-stdinout  : This mode is not meant at being directly used by a user.\n");
      93               0 :     printf( "             It is a helper utility for the client/server working of GDAL.\n");
      94                 : #ifndef WIN32
      95               0 :     printf( "-pipe_in/out:This mode is not meant at being directly used by a user.\n");
      96               0 :     printf( "             It is a helper utility for the client/server working of GDAL.\n");
      97                 : #endif
      98                 : 
      99               0 :     if( pszErrorMsg != NULL )
     100               0 :         fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
     101                 : 
     102               0 :     exit( 1 );
     103                 : }
     104                 : 
     105                 : 
     106                 : /************************************************************************/
     107                 : /*                CreateSocketAndBindAndListen()                        */
     108                 : /************************************************************************/
     109                 : 
     110               2 : int CreateSocketAndBindAndListen(const char* pszService,
     111                 :                                  int *pnFamily,
     112                 :                                  int *pnSockType,
     113                 :                                  int *pnProtocol)
     114                 : {
     115               2 :     CPL_SOCKET nListenSocket = INVALID_SOCKET;
     116                 : 
     117                 : #ifdef HAVE_GETADDRINFO
     118                 :     int nRet;
     119                 :     struct addrinfo sHints;
     120               2 :     struct addrinfo* psResults = NULL, *psResultsIter;
     121               2 :     memset(&sHints, 0, sizeof(struct addrinfo));
     122               2 :     sHints.ai_family = AF_UNSPEC;
     123               2 :     sHints.ai_socktype = SOCK_STREAM;
     124               2 :     sHints.ai_flags = AI_PASSIVE;
     125               2 :     sHints.ai_protocol = IPPROTO_TCP;
     126                 : 
     127               2 :     nRet = getaddrinfo(NULL, pszService, &sHints, &psResults);
     128               2 :     if (nRet)
     129                 :     {
     130               0 :         fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(nRet));
     131               0 :         return INVALID_SOCKET;
     132                 :     }
     133                 : 
     134               6 :     for( psResultsIter = psResults;
     135                 :          psResultsIter != NULL;
     136               2 :          psResultsIter = psResultsIter->ai_next)
     137                 :     {
     138               3 :         nListenSocket = socket(psResultsIter->ai_family,
     139                 :                                psResultsIter->ai_socktype,
     140                 :                                psResultsIter->ai_protocol);
     141               3 :         if (nListenSocket == INVALID_SOCKET)
     142               0 :             continue;
     143                 : 
     144               3 :         if (bind(nListenSocket, psResultsIter->ai_addr,
     145                 :                  psResultsIter->ai_addrlen) != SOCKET_ERROR)
     146                 :         {
     147               1 :             if( pnFamily )   *pnFamily =   psResultsIter->ai_family;
     148               1 :             if( pnSockType ) *pnSockType = psResultsIter->ai_socktype;
     149               1 :             if( pnProtocol ) *pnProtocol = psResultsIter->ai_protocol;
     150                 : 
     151               1 :             break;
     152                 :         }
     153                 : 
     154               2 :         closesocket(nListenSocket);
     155                 :     }
     156                 : 
     157               2 :     freeaddrinfo(psResults);
     158                 : 
     159               2 :     if (psResultsIter == NULL)
     160                 :     {
     161               1 :         fprintf(stderr, "Could not bind()\n");
     162               1 :         return INVALID_SOCKET;
     163                 :     }
     164                 : 
     165                 : #else
     166                 : 
     167                 :     struct sockaddr_in sockAddrIn;
     168                 : 
     169                 :     if( pnFamily )   *pnFamily = AF_INET;
     170                 :     if( pnSockType ) *pnSockType = SOCK_STREAM;
     171                 :     if( pnProtocol ) *pnProtocol = IPPROTO_TCP;
     172                 : 
     173                 :     nListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     174                 :     if (nListenSocket == INVALID_SOCKET)
     175                 :     {
     176                 :         fprintf(stderr, "socket() failed with error: %d\n", WSAGetLastError());
     177                 :         return INVALID_SOCKET;
     178                 :     }
     179                 : 
     180                 :     sockAddrIn.sin_family = AF_INET;
     181                 :     sockAddrIn.sin_addr.s_addr = INADDR_ANY;
     182                 :     sockAddrIn.sin_port = htons(atoi(pszService));
     183                 : 
     184                 :     if (bind(nListenSocket, (SOCKADDR *)&sockAddrIn, sizeof (sockAddrIn)) == SOCKET_ERROR)
     185                 :     {
     186                 :         fprintf(stderr, "bind() function failed with error: %d\n", WSAGetLastError());
     187                 :         closesocket(nListenSocket);
     188                 :         return INVALID_SOCKET;
     189                 :     }
     190                 : 
     191                 : #endif
     192                 : 
     193               1 :     if (listen(nListenSocket, SOMAXCONN) == SOCKET_ERROR)
     194                 :     {
     195               0 :         fprintf(stderr, "listen() function failed with error: %d\n", WSAGetLastError());
     196               0 :         closesocket(nListenSocket);
     197               0 :         return INVALID_SOCKET;
     198                 :     }
     199                 : 
     200               1 :     return nListenSocket;
     201                 : }
     202                 : 
     203                 : #ifdef WIN32
     204                 : 
     205                 : /************************************************************************/
     206                 : /*                             RunServer()                              */
     207                 : /************************************************************************/
     208                 : 
     209                 : int RunServer(const char* pszApplication,
     210                 :               const char* pszService,
     211                 :               const char* unused_pszUnixSocketFilename)
     212                 : {
     213                 :     int nRet;
     214                 :     WSADATA wsaData;
     215                 :     SOCKET nListenSocket;
     216                 :     int nFamily, nSockType, nProtocol;
     217                 : 
     218                 :     nRet = WSAStartup(MAKEWORD(2, 2), &wsaData);
     219                 :     if (nRet != NO_ERROR)
     220                 :     {
     221                 :         fprintf(stderr, "WSAStartup() failed with error: %d\n", nRet);
     222                 :         return 1;
     223                 :     }
     224                 : 
     225                 :     nListenSocket = CreateSocketAndBindAndListen(pszService, &nFamily, &nSockType, &nProtocol);
     226                 :     if (nListenSocket == INVALID_SOCKET)
     227                 :     {
     228                 :         WSACleanup();
     229                 :         return 1;
     230                 :     }
     231                 : 
     232                 :     while(TRUE)
     233                 :     {
     234                 :         WSAPROTOCOL_INFO sSocketInfo;
     235                 :         struct sockaddr sockAddr;
     236                 :         socklen_t nLen = sizeof(sockAddr);
     237                 :         CPLSpawnedProcess* psProcess;
     238                 :         CPL_FILE_HANDLE fin, fout;
     239                 :         CPL_PID nPid;
     240                 :         SOCKET nConnSocket;
     241                 :         char szReady[5];
     242                 :         int bOK = TRUE;
     243                 :         const char* apszArgs[] = { NULL, "-newconnection", NULL };
     244                 : 
     245                 :         apszArgs[0] = pszApplication;
     246                 :         nConnSocket = accept(nListenSocket, &sockAddr, &nLen);
     247                 :         if( nConnSocket == SOCKET_ERROR )
     248                 :         {
     249                 :             fprintf(stderr, "accept() function failed with error: %d\n", WSAGetLastError());
     250                 :             closesocket(nListenSocket);
     251                 :             WSACleanup();
     252                 :             return 1;
     253                 :         }
     254                 : 
     255                 :         psProcess = CPLSpawnAsync( NULL,
     256                 :                                    apszArgs,
     257                 :                                    TRUE,
     258                 :                                    TRUE,
     259                 :                                    FALSE,
     260                 :                                    NULL);
     261                 :         if( psProcess == NULL )
     262                 :         {
     263                 :             fprintf(stderr, "CPLSpawnAsync() function failed.\n");
     264                 :             closesocket(nConnSocket);
     265                 :             closesocket(nListenSocket);
     266                 :             WSACleanup();
     267                 :             return 1;
     268                 :         }
     269                 : 
     270                 :         nPid = CPLSpawnAsyncGetChildProcessId(psProcess);
     271                 :         fin = CPLSpawnAsyncGetInputFileHandle(psProcess);
     272                 :         fout = CPLSpawnAsyncGetOutputFileHandle(psProcess);
     273                 : 
     274                 :         if( WSADuplicateSocket(nConnSocket, nPid, &sSocketInfo) != 0 )
     275                 :         {
     276                 :             fprintf(stderr, "WSADuplicateSocket() failed: %d\n", WSAGetLastError());
     277                 :             bOK = FALSE;
     278                 :         }
     279                 : 
     280                 :         /* Send socket parameters over the pipe */
     281                 :         if( bOK &&
     282                 :             (!CPLPipeWrite(fout, &sSocketInfo, sizeof(sSocketInfo)) ||
     283                 :              !CPLPipeWrite(fout, &nFamily, sizeof(nFamily)) ||
     284                 :              !CPLPipeWrite(fout, &nSockType, sizeof(nSockType)) ||
     285                 :              !CPLPipeWrite(fout, &nProtocol, sizeof(nProtocol))) )
     286                 :         {
     287                 :             fprintf(stderr, "CPLWritePipe() failed\n");
     288                 :             bOK = FALSE;
     289                 :         }
     290                 : 
     291                 :         /* Wait for child to be ready before closing the socket */
     292                 :         if( bOK && !CPLPipeRead(fin, szReady, sizeof(szReady)) )
     293                 :         {
     294                 :             fprintf(stderr, "CPLReadPipe() failed\n");
     295                 :             bOK = FALSE;
     296                 :         }
     297                 : 
     298                 :         if( !bOK )
     299                 :         {
     300                 :             CPLSpawnAsyncFinish(psProcess, FALSE, TRUE);
     301                 :             closesocket(nConnSocket);
     302                 :             closesocket(nListenSocket);
     303                 :             WSACleanup();
     304                 :             return 1;
     305                 :         }
     306                 : 
     307                 : 
     308                 :         closesocket(nConnSocket);
     309                 : 
     310                 :         CPLSpawnAsyncFinish(psProcess, FALSE, FALSE);
     311                 :     }
     312                 : 
     313                 :     // closesocket(nConnSocket);
     314                 :     // WSACleanup();
     315                 : }
     316                 : 
     317                 : /************************************************************************/
     318                 : /*                          RunNewConnection()                          */
     319                 : /************************************************************************/
     320                 : 
     321                 : int RunNewConnection()
     322                 : {
     323                 :     int nRet;
     324                 :     WSADATA wsaData;
     325                 :     WSAPROTOCOL_INFO sSocketInfo;
     326                 :     int nFamily, nSockType, nProtocol;
     327                 :     SOCKET nConnSocket;
     328                 :     CPL_FILE_HANDLE fin = GetStdHandle(STD_INPUT_HANDLE);
     329                 :     CPL_FILE_HANDLE fout = GetStdHandle(STD_OUTPUT_HANDLE);
     330                 : 
     331                 :     /* Get socket parameters from the pipe */
     332                 :     if (!CPLPipeRead(fin, &sSocketInfo, sizeof(sSocketInfo)) ||
     333                 :         !CPLPipeRead(fin, &nFamily, sizeof(nFamily)) ||
     334                 :         !CPLPipeRead(fin, &nSockType, sizeof(nSockType)) ||
     335                 :         !CPLPipeRead(fin, &nProtocol, sizeof(nProtocol)) )
     336                 :     {
     337                 :         fprintf(stderr, "CPLPipeRead() failed\n");
     338                 :         return 1;
     339                 :     }
     340                 : 
     341                 :     nRet = WSAStartup(MAKEWORD(2, 2), &wsaData);
     342                 :     if (nRet != NO_ERROR)
     343                 :     {
     344                 :         fprintf(stderr, "WSAStartup() failed with error: %d\n", nRet);
     345                 :         return 1;
     346                 :     }
     347                 : 
     348                 :     nConnSocket = WSASocket(nFamily, nSockType, nProtocol, &sSocketInfo, 0, WSA_FLAG_OVERLAPPED);
     349                 :     if (nConnSocket == INVALID_SOCKET)
     350                 :     {
     351                 :         fprintf(stderr, "ConnSocket() failed with error: %d\n", WSAGetLastError());
     352                 :         WSACleanup();
     353                 :         return 1;
     354                 :     }
     355                 : 
     356                 :     /* Warn the parent that we are now ready */
     357                 :     if (!CPLPipeWrite(fout, "ready", 5))
     358                 :     {
     359                 :         fprintf(stderr, "CPLPipeWrite() failed\n");
     360                 :         WSACleanup();
     361                 :         return 1;
     362                 :     }
     363                 :     CloseHandle(fout);
     364                 : 
     365                 : #ifdef _MSC_VER
     366                 :     __try {
     367                 : #endif
     368                 :     nRet = GDALServerLoopSocket(nConnSocket);
     369                 : #ifdef _MSC_VER
     370                 :     } __except(1) 
     371                 :     {
     372                 :         fprintf(stderr, "gdalserver exited with a fatal error.\n");
     373                 :         nRet = 1;
     374                 :     }
     375                 : #endif
     376                 : 
     377                 :     closesocket(nConnSocket);
     378                 :     WSACleanup();
     379                 : 
     380                 :     return nRet;
     381                 : }
     382                 : 
     383                 : #else
     384                 : 
     385                 : /************************************************************************/
     386                 : /*                             RunServer()                              */
     387                 : /************************************************************************/
     388                 : 
     389               3 : int RunServer(const char* pszApplication,
     390                 :               const char* pszService,
     391                 :               const char* pszUnixSocketFilename)
     392                 : {
     393                 :     int nListenSocket;
     394                 : 
     395               3 :     if( pszUnixSocketFilename != NULL )
     396                 :     {
     397                 :         struct sockaddr_un sockAddrUnix;
     398                 :         int len;
     399                 : 
     400               1 :         nListenSocket = socket(AF_UNIX, SOCK_STREAM, 0);
     401               1 :         if (nListenSocket < 0)
     402                 :         {
     403               0 :             perror("socket");
     404               0 :             return 1;
     405                 :         }
     406                 : 
     407               1 :         sockAddrUnix.sun_family = AF_UNIX;
     408               1 :         CPLStrlcpy(sockAddrUnix.sun_path, pszUnixSocketFilename, sizeof(sockAddrUnix.sun_path));
     409               1 :         unlink(sockAddrUnix.sun_path);
     410               1 :         len = strlen(sockAddrUnix.sun_path) + sizeof(sockAddrUnix.sun_family);
     411               1 :         if (bind(nListenSocket, (struct sockaddr *)&sockAddrUnix, len) == -1)
     412                 :         {
     413               0 :             perror("bind");
     414               0 :             closesocket(nListenSocket);
     415               0 :             return 1;
     416                 :         }
     417               1 :         if (listen(nListenSocket, SOMAXCONN) == SOCKET_ERROR)
     418                 :         {
     419               0 :             fprintf(stderr, "listen() function failed with error: %d\n", WSAGetLastError());
     420               0 :             closesocket(nListenSocket);
     421               0 :             return 1;
     422                 :         }
     423                 :     }
     424                 :     else
     425                 :     {
     426               2 :         nListenSocket = CreateSocketAndBindAndListen(pszService, NULL, NULL, NULL);
     427               2 :         if (nListenSocket < 0)
     428                 :         {
     429               1 :             return 1;
     430                 :         }
     431                 :     }
     432                 : 
     433                 :     while(TRUE)
     434                 :     {
     435                 :         struct sockaddr sockAddr;
     436               4 :         socklen_t nLen = sizeof(sockAddr);
     437                 :         int nConnSocket;
     438                 :         pid_t pid;
     439                 :         int nStatus;
     440                 :         struct timeval tv;
     441                 :         fd_set read_fds;
     442                 : 
     443                 :         /* Select on the listen socket, and rip zombie children every second */
     444                 :         do
     445                 :         {
     446               4 :             FD_ZERO(&read_fds);
     447               4 :             FD_SET(nListenSocket, &read_fds);
     448               4 :             tv.tv_sec = 1;
     449               4 :             tv.tv_usec = 0;
     450               4 :             waitpid(-1, &nStatus, WNOHANG);
     451                 :         }
     452               4 :         while( select(nListenSocket + 1, &read_fds, NULL, NULL, &tv) != 1 );
     453                 : 
     454               4 :         nConnSocket = accept(nListenSocket, &sockAddr, &nLen);
     455               4 :         if( nConnSocket < 0 )
     456                 :         {
     457               0 :             fprintf(stderr, "accept() function failed with error: %d\n", errno);
     458               0 :             close(nListenSocket);
     459               0 :             return 1;
     460                 :         }
     461                 : 
     462               4 :         pid = fork();
     463               6 :         if( pid < 0 )
     464                 :         {
     465               0 :             fprintf(stderr, "fork() failed: %d\n", errno);
     466               0 :             close(nListenSocket);
     467               0 :             close(nConnSocket);
     468               0 :             return 1;
     469                 :         }
     470               6 :         else if( pid == 0 )
     471                 :         {
     472                 :             int nRet;
     473               4 :             close(nListenSocket);
     474               4 :             nRet = GDALServerLoopSocket(nConnSocket);
     475               4 :             close(nConnSocket);
     476               4 :             return nRet;
     477                 :         }
     478                 :         else
     479                 :         {
     480               2 :             close(nConnSocket);
     481                 :         }
     482               2 :     }
     483                 : }
     484                 : 
     485                 : #endif
     486                 : 
     487                 : /************************************************************************/
     488                 : /*                                main()                                */
     489                 : /************************************************************************/
     490                 : 
     491                 : #define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg) \
     492                 :     do { if (i + nExtraArg >= argc) \
     493                 :         Usage(CPLSPrintf("%s option requires %d argument(s)", argv[i], nExtraArg)); } while(0)
     494                 : 
     495               4 : int main(int argc, char* argv[])
     496                 : {
     497               4 :     int i, nRet, bStdinout = FALSE, bPipeIn = FALSE, bPipeOut = FALSE, bNewConnection = FALSE;
     498               4 :     const char* pszService = NULL, *pszUnixSocketFilename = NULL;
     499                 : #ifndef WIN32
     500               4 :     int pipe_in = fileno(stdin);
     501               4 :     int pipe_out = fileno(stdout);
     502                 : #endif
     503                 :     /*for( i = 1; i < argc; i++ )
     504                 :     {
     505                 :         if( EQUAL(argv[i], "-daemonize") )
     506                 :         {
     507                 :             daemon(0, 0);
     508                 :             break;
     509                 :         }
     510                 :     }*/
     511                 : 
     512               4 :     GDALAllRegister();
     513                 : 
     514               4 :     argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
     515               4 :     if( argc < 1 )
     516               0 :         exit( -argc );
     517                 : 
     518               7 :     for( i = 1; i < argc; i++ )
     519                 :     {
     520               4 :         if( EQUAL(argv[i], "--utility_version") )
     521                 :         {
     522               1 :             printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
     523                 :                    argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
     524               1 :             return 0;
     525                 :         }
     526               3 :         else if( EQUAL(argv[i],"--help") )
     527               0 :             Usage(NULL);
     528               3 :         else if( EQUAL(argv[i],"-tcpserver") )
     529                 :         {
     530               2 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     531               2 :             i++;
     532               2 :             pszService = argv[i];
     533                 :         }
     534                 : #ifndef WIN32
     535               1 :         else if( EQUAL(argv[i],"-unixserver") )
     536                 :         {
     537               1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     538               1 :             i++;
     539               1 :             pszUnixSocketFilename = argv[i];
     540                 :         }
     541                 : #endif
     542                 : #ifdef WIN32
     543                 :         else if( EQUAL(argv[i],"-newconnection") )
     544                 :         {
     545                 :             bNewConnection = TRUE;
     546                 :         }
     547                 : #endif
     548               0 :         else if( EQUAL(argv[i],"-stdinout") )
     549               0 :             bStdinout = TRUE;
     550                 : #ifndef WIN32
     551               0 :         else if( EQUAL(argv[i],"-pipe_in") )
     552                 :         {
     553                 :             const char* pszComma;
     554               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     555               0 :             i++;
     556               0 :             pipe_in = atoi(argv[i]);
     557               0 :             bPipeIn = TRUE;
     558               0 :             pszComma = strchr(argv[i], ',');
     559               0 :             if( pszComma )
     560               0 :                 close(atoi(pszComma + 1));
     561                 :         }
     562               0 :         else if( EQUAL(argv[i],"-pipe_out") )
     563                 :         {
     564                 :             const char* pszComma;
     565               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     566               0 :             i++;
     567               0 :             pipe_out = atoi(argv[i]);
     568               0 :             bPipeOut = TRUE;
     569               0 :             pszComma = strchr(argv[i], ',');
     570               0 :             if( pszComma )
     571               0 :                 close(atoi(pszComma + 1));
     572                 :         }
     573                 : #endif
     574               0 :         else if( EQUAL(argv[i], "-daemonize") )
     575                 :             ;
     576               0 :         else if( argv[i][0] == '-' )
     577               0 :             Usage(CPLSPrintf("Unkown option name '%s'", argv[i]));
     578                 :         else
     579               0 :             Usage("Too many command options.");
     580                 :     }
     581               3 :     if( !bStdinout && !(bPipeIn && bPipeOut) &&
     582                 :         pszService == NULL && pszUnixSocketFilename == NULL && !bNewConnection )
     583               0 :         Usage(NULL);
     584                 : 
     585               8 :     if( pszService != NULL || pszUnixSocketFilename != NULL )
     586               3 :         nRet = RunServer(argv[0], pszService, pszUnixSocketFilename);
     587                 : #ifdef WIN32
     588                 :     else if( bNewConnection )
     589                 :         nRet = RunNewConnection();
     590                 : #endif
     591                 : 
     592                 :     else
     593                 :     {
     594                 : #ifdef WIN32
     595                 : #ifdef _MSC_VER
     596                 :     __try 
     597                 : #endif
     598                 :     { 
     599                 :         nRet = GDALServerLoop(GetStdHandle(STD_INPUT_HANDLE),
     600                 :                               GetStdHandle(STD_OUTPUT_HANDLE));
     601                 :     }
     602                 : #ifdef _MSC_VER
     603                 :     __except(1) 
     604                 :     {
     605                 :         fprintf(stderr, "gdalserver exited with a fatal error.\n");
     606                 :         nRet = 1;
     607                 :     }
     608                 : #endif
     609                 : #else
     610               0 :     nRet = GDALServerLoop(pipe_in, pipe_out);
     611                 : #endif
     612                 :     }
     613                 : 
     614               5 :     CSLDestroy(argv);
     615                 : 
     616               5 :     return nRet;
     617                 : }

Generated by: LCOV version 1.7