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/. */
15 #include "RemoteUtils.h"
18 # define TO_LITTLE_ENDIAN32(x) \
19 ((((x)&0xff000000) >> 24) | (((x)&0x00ff0000) >> 8) | \
20 (((x)&0x0000ff00) << 8) | (((x)&0x000000ff) << 24))
22 # define TO_LITTLE_ENDIAN32(x) (x)
27 # define MAX_PATH PATH_MAX
29 # define MAX_PATH 1024
33 /* like strcpy, but return the char after the final null */
34 static char* estrcpy(const char* s
, char* d
) {
35 while (*s
) *d
++ = *s
++;
41 /* Construct a command line from given args and desktop startup ID.
42 * Returned buffer must be released by free().
44 char* ConstructCommandLine(int32_t argc
, char** argv
,
45 const char* aDesktopStartupID
,
46 int* aCommandLineLength
) {
47 char cwdbuf
[MAX_PATH
];
48 if (!getcwd(cwdbuf
, MAX_PATH
)) return nullptr;
50 // the commandline property is constructed as an array of int32_t
51 // followed by a series of null-terminated strings:
53 // [argc][offsetargv0][offsetargv1...]<workingdir>\0<argv[0]>\0argv[1]...\0
54 // (offset is from the beginning of the buffer)
56 static char desktopStartupPrefix
[] = " DESKTOP_STARTUP_ID=";
58 int32_t argvlen
= strlen(cwdbuf
);
59 for (int i
= 0; i
< argc
; ++i
) {
60 int32_t len
= strlen(argv
[i
]);
61 if (i
== 0 && aDesktopStartupID
) {
62 len
+= sizeof(desktopStartupPrefix
) - 1 + strlen(aDesktopStartupID
);
68 (int32_t*)malloc(argvlen
+ argc
+ 1 + sizeof(int32_t) * (argc
+ 1));
69 if (!buffer
) return nullptr;
71 buffer
[0] = TO_LITTLE_ENDIAN32(argc
);
73 auto* bufend
= (char*)(buffer
+ argc
+ 1);
75 bufend
= estrcpy(cwdbuf
, bufend
);
77 for (int i
= 0; i
< argc
; ++i
) {
78 buffer
[i
+ 1] = TO_LITTLE_ENDIAN32(bufend
- ((char*)buffer
));
79 bufend
= estrcpy(argv
[i
], bufend
);
80 if (i
== 0 && aDesktopStartupID
) {
81 bufend
= estrcpy(desktopStartupPrefix
, bufend
- 1);
82 bufend
= estrcpy(aDesktopStartupID
, bufend
- 1);
86 #ifdef DEBUG_command_line
87 int32_t debug_argc
= TO_LITTLE_ENDIAN32(*buffer
);
88 char* debug_workingdir
= (char*)(buffer
+ argc
+ 1);
91 "Sending command line:\n"
94 debug_workingdir
, debug_argc
);
96 int32_t* debug_offset
= buffer
+ 1;
97 for (int debug_i
= 0; debug_i
< debug_argc
; ++debug_i
)
98 printf(" argv[%i]:\t%s\n", debug_i
,
99 ((char*)buffer
) + TO_LITTLE_ENDIAN32(debug_offset
[debug_i
]));
102 *aCommandLineLength
= bufend
- reinterpret_cast<char*>(buffer
);
103 return reinterpret_cast<char*>(buffer
);