1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=8:
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/. */
14 #include "RemoteUtils.h"
17 # define TO_LITTLE_ENDIAN32(x) \
18 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
19 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
21 # define TO_LITTLE_ENDIAN32(x) (x)
26 # define MAX_PATH PATH_MAX
28 # define MAX_PATH 1024
32 /* like strcpy, but return the char after the final null */
33 static char* estrcpy(const char* s
, char* d
) {
34 while (*s
) *d
++ = *s
++;
40 /* Construct a command line from given args and desktop startup ID.
41 * Returned buffer must be released by free().
43 char* ConstructCommandLine(int32_t argc
, const char** argv
,
44 const char* aStartupToken
, int* aCommandLineLength
) {
45 char cwdbuf
[MAX_PATH
];
46 if (!getcwd(cwdbuf
, MAX_PATH
)) return nullptr;
48 // the commandline property is constructed as an array of int32_t
49 // followed by a series of null-terminated strings:
51 // [argc][offsetargv0][offsetargv1...]<workingdir>\0<argv[0]>\0argv[1]...\0
52 // (offset is from the beginning of the buffer)
54 static char startupTokenPrefix
[] = " STARTUP_TOKEN=";
56 int32_t argvlen
= strlen(cwdbuf
);
57 for (int i
= 0; i
< argc
; ++i
) {
58 int32_t len
= strlen(argv
[i
]);
59 if (i
== 0 && aStartupToken
) {
60 len
+= sizeof(startupTokenPrefix
) - 1 + strlen(aStartupToken
);
66 (int32_t*)malloc(argvlen
+ argc
+ 1 + sizeof(int32_t) * (argc
+ 1));
67 if (!buffer
) return nullptr;
69 buffer
[0] = TO_LITTLE_ENDIAN32(argc
);
71 auto* bufend
= (char*)(buffer
+ argc
+ 1);
73 bufend
= estrcpy(cwdbuf
, bufend
);
75 for (int i
= 0; i
< argc
; ++i
) {
76 buffer
[i
+ 1] = TO_LITTLE_ENDIAN32(bufend
- ((char*)buffer
));
77 bufend
= estrcpy(argv
[i
], bufend
);
78 if (i
== 0 && aStartupToken
) {
79 bufend
= estrcpy(startupTokenPrefix
, bufend
- 1);
80 bufend
= estrcpy(aStartupToken
, bufend
- 1);
84 #ifdef DEBUG_command_line
85 int32_t debug_argc
= TO_LITTLE_ENDIAN32(*buffer
);
86 char* debug_workingdir
= (char*)(buffer
+ argc
+ 1);
89 "Sending command line:\n"
92 debug_workingdir
, debug_argc
);
94 int32_t* debug_offset
= buffer
+ 1;
95 for (int debug_i
= 0; debug_i
< debug_argc
; ++debug_i
)
96 printf(" argv[%i]:\t%s\n", debug_i
,
97 ((char*)buffer
) + TO_LITTLE_ENDIAN32(debug_offset
[debug_i
]));
100 *aCommandLineLength
= bufend
- reinterpret_cast<char*>(buffer
);
101 return reinterpret_cast<char*>(buffer
);