forked from mirrors/gecko-dev
		
	 ef35fa7374
			
		
	
	
		ef35fa7374
		
	
	
	
	
		
			
			clang-format version 17.0.6 (taskcluster-QueHFUviQeyM8Y7r_d7MQQ) # ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D195397
		
			
				
	
	
		
			102 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim:expandtab:shiftwidth=2:tabstop=8:
 | |
|  */
 | |
| /* vim:set ts=8 sw=2 et cindent: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <unistd.h>
 | |
| #include <limits.h>
 | |
| 
 | |
| #include "RemoteUtils.h"
 | |
| 
 | |
| #ifdef IS_BIG_ENDIAN
 | |
| #  define TO_LITTLE_ENDIAN32(x)                               \
 | |
|     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
 | |
|      (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
 | |
| #else
 | |
| #  define TO_LITTLE_ENDIAN32(x) (x)
 | |
| #endif
 | |
| 
 | |
| #ifndef MAX_PATH
 | |
| #  ifdef PATH_MAX
 | |
| #    define MAX_PATH PATH_MAX
 | |
| #  else
 | |
| #    define MAX_PATH 1024
 | |
| #  endif
 | |
| #endif
 | |
| 
 | |
| /* like strcpy, but return the char after the final null */
 | |
| static char* estrcpy(const char* s, char* d) {
 | |
|   while (*s) *d++ = *s++;
 | |
| 
 | |
|   *d++ = '\0';
 | |
|   return d;
 | |
| }
 | |
| 
 | |
| /* Construct a command line from given args and desktop startup ID.
 | |
|  * Returned buffer must be released by free().
 | |
|  */
 | |
| char* ConstructCommandLine(int32_t argc, char** argv, const char* aStartupToken,
 | |
|                            int* aCommandLineLength) {
 | |
|   char cwdbuf[MAX_PATH];
 | |
|   if (!getcwd(cwdbuf, MAX_PATH)) return nullptr;
 | |
| 
 | |
|   // the commandline property is constructed as an array of int32_t
 | |
|   // followed by a series of null-terminated strings:
 | |
|   //
 | |
|   // [argc][offsetargv0][offsetargv1...]<workingdir>\0<argv[0]>\0argv[1]...\0
 | |
|   // (offset is from the beginning of the buffer)
 | |
| 
 | |
|   static char startupTokenPrefix[] = " STARTUP_TOKEN=";
 | |
| 
 | |
|   int32_t argvlen = strlen(cwdbuf);
 | |
|   for (int i = 0; i < argc; ++i) {
 | |
|     int32_t len = strlen(argv[i]);
 | |
|     if (i == 0 && aStartupToken) {
 | |
|       len += sizeof(startupTokenPrefix) - 1 + strlen(aStartupToken);
 | |
|     }
 | |
|     argvlen += len;
 | |
|   }
 | |
| 
 | |
|   auto* buffer =
 | |
|       (int32_t*)malloc(argvlen + argc + 1 + sizeof(int32_t) * (argc + 1));
 | |
|   if (!buffer) return nullptr;
 | |
| 
 | |
|   buffer[0] = TO_LITTLE_ENDIAN32(argc);
 | |
| 
 | |
|   auto* bufend = (char*)(buffer + argc + 1);
 | |
| 
 | |
|   bufend = estrcpy(cwdbuf, bufend);
 | |
| 
 | |
|   for (int i = 0; i < argc; ++i) {
 | |
|     buffer[i + 1] = TO_LITTLE_ENDIAN32(bufend - ((char*)buffer));
 | |
|     bufend = estrcpy(argv[i], bufend);
 | |
|     if (i == 0 && aStartupToken) {
 | |
|       bufend = estrcpy(startupTokenPrefix, bufend - 1);
 | |
|       bufend = estrcpy(aStartupToken, bufend - 1);
 | |
|     }
 | |
|   }
 | |
| 
 | |
| #ifdef DEBUG_command_line
 | |
|   int32_t debug_argc = TO_LITTLE_ENDIAN32(*buffer);
 | |
|   char* debug_workingdir = (char*)(buffer + argc + 1);
 | |
| 
 | |
|   printf(
 | |
|       "Sending command line:\n"
 | |
|       "  working dir: %s\n"
 | |
|       "  argc:\t%i",
 | |
|       debug_workingdir, debug_argc);
 | |
| 
 | |
|   int32_t* debug_offset = buffer + 1;
 | |
|   for (int debug_i = 0; debug_i < debug_argc; ++debug_i)
 | |
|     printf("  argv[%i]:\t%s\n", debug_i,
 | |
|            ((char*)buffer) + TO_LITTLE_ENDIAN32(debug_offset[debug_i]));
 | |
| #endif
 | |
| 
 | |
|   *aCommandLineLength = bufend - reinterpret_cast<char*>(buffer);
 | |
|   return reinterpret_cast<char*>(buffer);
 | |
| }
 |