Fix a potential null pointer deref & a potential memory leak,
also reformat to conform to the usual lldb coding conventions a little better. clang static analyzer fixit. llvm-svn: 219893
This commit is contained in:
parent
3206b1e077
commit
4ecbc44f79
|
|
@ -23,7 +23,8 @@
|
|||
int _validate_authorization(xpc_object_t message);
|
||||
|
||||
// Returns 0 if successful.
|
||||
int _setup_posixspawn_attributes_file_actions(xpc_object_t message, posix_spawnattr_t *attr, posix_spawn_file_actions_t *file_actions)
|
||||
int
|
||||
_setup_posixspawn_attributes_file_actions(xpc_object_t message, posix_spawnattr_t *attr, posix_spawn_file_actions_t *file_actions)
|
||||
{
|
||||
*attr = 0;
|
||||
|
||||
|
|
@ -32,7 +33,8 @@ int _setup_posixspawn_attributes_file_actions(xpc_object_t message, posix_spawna
|
|||
return errorCode;
|
||||
|
||||
cpu_type_t cpuType = (cpu_type_t)xpc_dictionary_get_int64(message, LauncherXPCServiceCPUTypeKey);
|
||||
if (cpuType == -2) {
|
||||
if (cpuType == -2)
|
||||
{
|
||||
cpuType= CPU_TYPE_ANY;
|
||||
}
|
||||
size_t realCount;
|
||||
|
|
@ -94,23 +96,27 @@ int _setup_posixspawn_attributes_file_actions(xpc_object_t message, posix_spawna
|
|||
return errorCode;
|
||||
}
|
||||
|
||||
bool extract_args(xpc_object_t message, const char *prefix, const char ***argsOut)
|
||||
bool
|
||||
extract_args(xpc_object_t message, const char *prefix, const char ***argsOut)
|
||||
{
|
||||
char buf[50]; // long enough for 'argXXX'
|
||||
memset(buf, 0, 50);
|
||||
sprintf(buf, "%sCount", prefix);
|
||||
int argsCount = (int)xpc_dictionary_get_int64(message, buf);
|
||||
if (argsCount == 0) {
|
||||
if (argsCount == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const char **argsp = NULL;
|
||||
argsp = (const char **)malloc((argsCount+1) * sizeof(argsp[0]));
|
||||
if (argsp == NULL) {
|
||||
if (argsp == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i=0; i<argsCount; i++) {
|
||||
for (int i=0; i<argsCount; i++)
|
||||
{
|
||||
memset(buf, 0, 50);
|
||||
sprintf(buf, "%s%i", prefix, i);
|
||||
const char *arg = xpc_dictionary_get_string(message, buf);
|
||||
|
|
@ -123,21 +129,28 @@ bool extract_args(xpc_object_t message, const char *prefix, const char ***argsOu
|
|||
}
|
||||
|
||||
// Returns 0 if successful.
|
||||
int get_args(xpc_object_t message, const char **path, const char ***argsOut, const char ***envOut)
|
||||
int
|
||||
get_args(xpc_object_t message, const char **path, const char ***argsOut, const char ***envOut)
|
||||
{
|
||||
if (!extract_args(message, LauncherXPCServiceArgPrefxKey, argsOut)) {
|
||||
if (!extract_args(message, LauncherXPCServiceArgPrefxKey, argsOut))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
*path = (*argsOut)[0];
|
||||
if (path && *path && argsOut && *argsOut)
|
||||
{
|
||||
*path = (*argsOut)[0];
|
||||
}
|
||||
|
||||
if (!extract_args(message, LauncherXPCServiceEnvPrefxKey, envOut)) {
|
||||
if (!extract_args(message, LauncherXPCServiceEnvPrefxKey, envOut))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _wait_for_child_exit(pid_t childPID)
|
||||
void
|
||||
_wait_for_child_exit(pid_t childPID)
|
||||
{
|
||||
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, childPID, DISPATCH_PROC_EXIT, queue);
|
||||
|
|
@ -153,7 +166,8 @@ void _wait_for_child_exit(pid_t childPID)
|
|||
dispatch_source_cancel(source);
|
||||
|
||||
int status, ret;
|
||||
do {
|
||||
do
|
||||
{
|
||||
ret = waitpid(childPID, &status, 0);
|
||||
} while (ret < 0 && errno == EINTR);
|
||||
|
||||
|
|
@ -162,20 +176,27 @@ void _wait_for_child_exit(pid_t childPID)
|
|||
}
|
||||
}
|
||||
|
||||
static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t event)
|
||||
static void
|
||||
launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t event)
|
||||
{
|
||||
xpc_type_t type = xpc_get_type(event);
|
||||
if (type == XPC_TYPE_ERROR) {
|
||||
if (event == XPC_ERROR_CONNECTION_INVALID) {
|
||||
if (type == XPC_TYPE_ERROR)
|
||||
{
|
||||
if (event == XPC_ERROR_CONNECTION_INVALID)
|
||||
{
|
||||
// The client process on the other end of the connection has either
|
||||
// crashed or cancelled the connection. After receiving this error,
|
||||
// the connection is in an invalid state, and you do not need to
|
||||
// call xpc_connection_cancel(). Just tear down any associated state
|
||||
// here.
|
||||
} else if (event == XPC_ERROR_TERMINATION_IMMINENT) {
|
||||
}
|
||||
else if (event == XPC_ERROR_TERMINATION_IMMINENT)
|
||||
{
|
||||
// Handle per-connection termination cleanup.
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(type == XPC_TYPE_DICTIONARY);
|
||||
// Handle the message.
|
||||
|
||||
|
|
@ -192,7 +213,8 @@ static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t e
|
|||
*/
|
||||
int errorType = 100;
|
||||
int errorCode = _validate_authorization(event);
|
||||
if (!errorCode) {
|
||||
if (!errorCode)
|
||||
{
|
||||
errorType = 101;
|
||||
errorCode = _setup_posixspawn_attributes_file_actions(event, &attributes, &file_actions);
|
||||
if (!errorCode) {
|
||||
|
|
@ -201,24 +223,28 @@ static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t e
|
|||
const char **envp = NULL;
|
||||
errorType = 102;
|
||||
errorCode = get_args(event, &path, &argvp, &envp);
|
||||
if (!errorCode) {
|
||||
if (!errorCode)
|
||||
{
|
||||
errorType = 103;
|
||||
errorCode = posix_spawn(&childPID, path, &file_actions, &attributes, (char * const *)argvp, (char * const *)envp);
|
||||
|
||||
if (argvp) free(argvp);
|
||||
if (envp) free(envp);
|
||||
|
||||
if (errorCode == 0) {
|
||||
if (errorCode == 0)
|
||||
{
|
||||
_wait_for_child_exit(childPID);
|
||||
}
|
||||
}
|
||||
if (argvp)
|
||||
free(argvp);
|
||||
if (envp)
|
||||
free(envp);
|
||||
}
|
||||
}
|
||||
|
||||
xpc_object_t reply = xpc_dictionary_create_reply(event);
|
||||
|
||||
xpc_dictionary_set_int64(reply, LauncherXPCServiceChildPIDKey, childPID);
|
||||
if (!childPID) {
|
||||
if (!childPID)
|
||||
{
|
||||
xpc_dictionary_set_int64(reply, LauncherXPCServiceErrorTypeKey, errorType);
|
||||
xpc_dictionary_set_int64(reply, LauncherXPCServiceCodeTypeKey, errorCode);
|
||||
}
|
||||
|
|
@ -228,7 +254,8 @@ static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t e
|
|||
}
|
||||
}
|
||||
|
||||
static void launcherXPC_event_handler(xpc_connection_t peer)
|
||||
static void
|
||||
launcherXPC_event_handler(xpc_connection_t peer)
|
||||
{
|
||||
// By defaults, new connections will target the default dispatch
|
||||
// concurrent queue.
|
||||
|
|
@ -242,7 +269,8 @@ static void launcherXPC_event_handler(xpc_connection_t peer)
|
|||
xpc_connection_resume(peer);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
int
|
||||
main(int argc, const char *argv[])
|
||||
{
|
||||
xpc_main(launcherXPC_event_handler);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue