/src/mozilla-central/widget/xremoteclient/RemoteUtils.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim:expandtab:shiftwidth=2:tabstop=8: |
3 | | */ |
4 | | /* vim:set ts=8 sw=2 et cindent: */ |
5 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
8 | | |
9 | | #include <stdlib.h> |
10 | | #include <string.h> |
11 | | #include <strings.h> |
12 | | #include <unistd.h> |
13 | | #include <limits.h> |
14 | | |
15 | | #include "RemoteUtils.h" |
16 | | |
17 | | #ifdef IS_BIG_ENDIAN |
18 | | #define TO_LITTLE_ENDIAN32(x) \ |
19 | | ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ |
20 | | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) |
21 | | #else |
22 | 0 | #define TO_LITTLE_ENDIAN32(x) (x) |
23 | | #endif |
24 | | |
25 | | #ifndef MAX_PATH |
26 | | #ifdef PATH_MAX |
27 | 0 | #define MAX_PATH PATH_MAX |
28 | | #else |
29 | | #define MAX_PATH 1024 |
30 | | #endif |
31 | | #endif |
32 | | |
33 | | /* like strcpy, but return the char after the final null */ |
34 | | static char* |
35 | | estrcpy(const char* s, char* d) |
36 | 0 | { |
37 | 0 | while (*s) |
38 | 0 | *d++ = *s++; |
39 | 0 |
|
40 | 0 | *d++ = '\0'; |
41 | 0 | return d; |
42 | 0 | } |
43 | | |
44 | | /* Construct a command line from given args and desktop startup ID. |
45 | | * Returned buffer must be released by free(). |
46 | | */ |
47 | | char* |
48 | | ConstructCommandLine(int32_t argc, char **argv, |
49 | | const char* aDesktopStartupID, |
50 | | int *aCommandLineLength) |
51 | 0 | { |
52 | 0 | char cwdbuf[MAX_PATH]; |
53 | 0 | if (!getcwd(cwdbuf, MAX_PATH)) |
54 | 0 | return nullptr; |
55 | 0 | |
56 | 0 | // the commandline property is constructed as an array of int32_t |
57 | 0 | // followed by a series of null-terminated strings: |
58 | 0 | // |
59 | 0 | // [argc][offsetargv0][offsetargv1...]<workingdir>\0<argv[0]>\0argv[1]...\0 |
60 | 0 | // (offset is from the beginning of the buffer) |
61 | 0 | |
62 | 0 | static char desktopStartupPrefix[] = " DESKTOP_STARTUP_ID="; |
63 | 0 |
|
64 | 0 | int32_t argvlen = strlen(cwdbuf); |
65 | 0 | for (int i = 0; i < argc; ++i) { |
66 | 0 | int32_t len = strlen(argv[i]); |
67 | 0 | if (i == 0 && aDesktopStartupID) { |
68 | 0 | len += sizeof(desktopStartupPrefix) - 1 + strlen(aDesktopStartupID); |
69 | 0 | } |
70 | 0 | argvlen += len; |
71 | 0 | } |
72 | 0 |
|
73 | 0 | auto* buffer = (int32_t*) malloc(argvlen + argc + 1 + |
74 | 0 | sizeof(int32_t) * (argc + 1)); |
75 | 0 | if (!buffer) |
76 | 0 | return nullptr; |
77 | 0 | |
78 | 0 | buffer[0] = TO_LITTLE_ENDIAN32(argc); |
79 | 0 |
|
80 | 0 | auto *bufend = (char*) (buffer + argc + 1); |
81 | 0 |
|
82 | 0 | bufend = estrcpy(cwdbuf, bufend); |
83 | 0 |
|
84 | 0 | for (int i = 0; i < argc; ++i) { |
85 | 0 | buffer[i + 1] = TO_LITTLE_ENDIAN32(bufend - ((char*) buffer)); |
86 | 0 | bufend = estrcpy(argv[i], bufend); |
87 | 0 | if (i == 0 && aDesktopStartupID) { |
88 | 0 | bufend = estrcpy(desktopStartupPrefix, bufend - 1); |
89 | 0 | bufend = estrcpy(aDesktopStartupID, bufend - 1); |
90 | 0 | } |
91 | 0 | } |
92 | 0 |
|
93 | | #ifdef DEBUG_command_line |
94 | | int32_t debug_argc = TO_LITTLE_ENDIAN32(*buffer); |
95 | | char *debug_workingdir = (char*) (buffer + argc + 1); |
96 | | |
97 | | printf("Sending command line:\n" |
98 | | " working dir: %s\n" |
99 | | " argc:\t%i", |
100 | | debug_workingdir, |
101 | | debug_argc); |
102 | | |
103 | | int32_t *debug_offset = buffer + 1; |
104 | | for (int debug_i = 0; debug_i < debug_argc; ++debug_i) |
105 | | printf(" argv[%i]:\t%s\n", debug_i, |
106 | | ((char*) buffer) + TO_LITTLE_ENDIAN32(debug_offset[debug_i])); |
107 | | #endif |
108 | |
|
109 | 0 | *aCommandLineLength = bufend - reinterpret_cast<char *>(buffer); |
110 | 0 | return reinterpret_cast<char *>(buffer); |
111 | 0 | } |