File: RemoteUtils.cpp

package info (click to toggle)
firefox 142.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,591,884 kB
  • sloc: cpp: 7,451,570; javascript: 6,392,463; ansic: 3,712,584; python: 1,388,569; xml: 629,223; asm: 426,919; java: 184,857; sh: 63,439; makefile: 19,150; objc: 13,059; perl: 12,983; yacc: 4,583; cs: 3,846; pascal: 3,352; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (104 lines) | stat: -rw-r--r-- 3,254 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* -*- 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 "mozilla/UniquePtr.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 is managed by mozilla::UniquePtr<char[]>.
 */
mozilla::UniquePtr<char[]> ConstructCommandLine(int32_t argc, const 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;
  }

  mozilla::UniquePtr<char[]> buffer = mozilla::MakeUnique<char[]>(
      argvlen + argc + 1 + sizeof(int32_t) * (argc + 1));

  int32_t* bufferInt = reinterpret_cast<int32_t*>(buffer.get());
  bufferInt[0] = TO_LITTLE_ENDIAN32(argc);

  char* bufend = reinterpret_cast<char*>(bufferInt + argc + 1);

  bufend = estrcpy(cwdbuf, bufend);

  for (int i = 0; i < argc; ++i) {
    bufferInt[i + 1] = TO_LITTLE_ENDIAN32(bufend - buffer.get());
    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(*bufferInt);
  char* debug_workingdir = reinterpret_cast<char*>(bufferInt + argc + 1);

  printf(
      "Sending command line:\n"
      "  working dir: %s\n"
      "  argc:\t%i",
      debug_workingdir, debug_argc);

  int32_t* debug_offset = bufferInt + 1;
  for (int debug_i = 0; debug_i < debug_argc; ++debug_i)
    printf("  argv[%i]:\t%s\n", debug_i,
           buffer.get() + TO_LITTLE_ENDIAN32(debug_offset[debug_i]));
#endif

  *aCommandLineLength = static_cast<int>(bufend - buffer.get());
  return buffer;
}