1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/openenvcore/libc/src/spawn.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,549 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +//
1.19 +
1.20 +#include <e32std.h>
1.21 +#include "spawn_r.h"
1.22 +#include <spawn.h>
1.23 +#include <sys/syslimits.h>
1.24 +#include <errno.h>
1.25 +#include <wchar.h>
1.26 +#include <stdlib.h>
1.27 +#include <string.h>
1.28 +#include "sysreent.h"
1.29 +
1.30 +extern "C" {
1.31 +
1.32 +// -----------------------------------------------------------------------------
1.33 +// posix_spawn_file_actions_init
1.34 +// Initialize the file actions structure
1.35 +// -----------------------------------------------------------------------------
1.36 +EXPORT_C int posix_spawn_file_actions_init(posix_spawn_file_actions_t* file_actions)
1.37 + {
1.38 + file_actions->_fa = new file_actions_t;
1.39 + if (!file_actions->_fa)
1.40 + {
1.41 + return ENOMEM;
1.42 + }
1.43 + return 0;
1.44 + }
1.45 +
1.46 +// -----------------------------------------------------------------------------
1.47 +// posix_spawn_file_actions_addopen
1.48 +// Add an open action to the file actions structure
1.49 +// -----------------------------------------------------------------------------
1.50 +EXPORT_C int posix_spawn_file_actions_addopen(
1.51 + posix_spawn_file_actions_t* file_actions,
1.52 + int fid,
1.53 + const char* path,
1.54 + int oflag,
1.55 + mode_t mode)
1.56 + {
1.57 + if (fid < 0 || fid > OPEN_MAX)
1.58 + {
1.59 + return EBADF;
1.60 + }
1.61 +
1.62 + TFileAction* fa = new TFileAction;
1.63 + if (!fa)
1.64 + {
1.65 + return ENOMEM;
1.66 + }
1.67 +
1.68 + memset(fa, 0, sizeof(TFileAction));
1.69 + fa->iOp = EOpen;
1.70 + fa->iFid1 = fid;
1.71 + fa->iOFlag = oflag;
1.72 + fa->iMode = mode;
1.73 +
1.74 + int len = strlen(path)+1;
1.75 + wchar_t* wpath = new wchar_t[len];
1.76 + if (!wpath)
1.77 + {
1.78 + delete fa;
1.79 + return ENOMEM;
1.80 + }
1.81 +
1.82 + if (mbstowcs(wpath, path, len) == (size_t)-1)
1.83 + {
1.84 + delete fa;
1.85 + delete[] wpath;
1.86 + return EILSEQ;
1.87 + }
1.88 +
1.89 + fa->iPath = new TFileName;
1.90 + fa->iPath->Copy((TText16*)wpath, len);
1.91 + delete[] wpath;
1.92 +
1.93 + (file_actions->_fa->iActions).AddLast(*fa);
1.94 + if (file_actions->_fa->iIter == NULL)
1.95 + {
1.96 + (file_actions->_fa->iIter).SetToFirst();
1.97 + }
1.98 +
1.99 + return 0;
1.100 + }
1.101 +
1.102 +// -----------------------------------------------------------------------------
1.103 +// posix_spawn_file_actions_adddup2
1.104 +// Add a dup2 action to the file actions structure
1.105 +// -----------------------------------------------------------------------------
1.106 +EXPORT_C int posix_spawn_file_actions_adddup2(
1.107 + posix_spawn_file_actions_t* file_actions,
1.108 + int fid1,
1.109 + int fid2)
1.110 + {
1.111 + if (fid1 < 0 || fid2 < 0 || fid1 > OPEN_MAX || fid2 > OPEN_MAX)
1.112 + {
1.113 + return EBADF;
1.114 + }
1.115 +
1.116 + TFileAction* fa = new TFileAction;
1.117 + if (!fa)
1.118 + {
1.119 + return ENOMEM;
1.120 + }
1.121 +
1.122 + memset(fa, 0, sizeof(TFileAction));
1.123 + fa->iOp = EDup;
1.124 + fa->iFid1 = fid1;
1.125 + fa->iFid2 = fid2;
1.126 +
1.127 + (file_actions->_fa->iActions).AddLast(*fa);
1.128 + if (file_actions->_fa->iIter == NULL)
1.129 + {
1.130 + (file_actions->_fa->iIter).SetToFirst();
1.131 + }
1.132 +
1.133 + return 0;
1.134 + }
1.135 +
1.136 +// -----------------------------------------------------------------------------
1.137 +// posix_spawn_file_actions_addclose
1.138 +// Add a close action to the file actions structure
1.139 +// -----------------------------------------------------------------------------
1.140 +EXPORT_C int posix_spawn_file_actions_addclose(
1.141 + posix_spawn_file_actions_t* file_actions,
1.142 + int fid)
1.143 + {
1.144 + if (fid < 0 || fid > OPEN_MAX)
1.145 + {
1.146 + return EBADF;
1.147 + }
1.148 +
1.149 + TFileAction* fa = new TFileAction;
1.150 + if (!fa)
1.151 + {
1.152 + return ENOMEM;
1.153 + }
1.154 +
1.155 + memset(fa, 0, sizeof(TFileAction));
1.156 + fa->iOp = EClose;
1.157 + fa->iFid1 = fid;
1.158 + (file_actions->_fa->iActions).AddLast(*fa);
1.159 + if (file_actions->_fa->iIter == NULL)
1.160 + {
1.161 + (file_actions->_fa->iIter).SetToFirst();
1.162 + }
1.163 +
1.164 + return 0;
1.165 + }
1.166 +
1.167 +// -----------------------------------------------------------------------------
1.168 +// posix_spawn_file_actions_destroy
1.169 +// Empty and destroy the file actions structure
1.170 +// -----------------------------------------------------------------------------
1.171 +EXPORT_C int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* file_actions)
1.172 + {
1.173 + if (!file_actions || !file_actions->_fa)
1.174 + {
1.175 + return EINVAL;
1.176 + }
1.177 +
1.178 + if (file_actions->_fa->iActions.IsEmpty())
1.179 + {
1.180 + delete file_actions->_fa;
1.181 + return 0;
1.182 + }
1.183 +
1.184 + TFileAction* fa = (file_actions->_fa->iIter)++;
1.185 + while (fa)
1.186 + {
1.187 + if (fa->iPath)
1.188 + {
1.189 + delete fa->iPath;
1.190 + }
1.191 +
1.192 + delete fa;
1.193 + fa = (file_actions->_fa->iIter)++;
1.194 + }
1.195 +
1.196 + file_actions->_fa->iActions.Reset();
1.197 + delete file_actions->_fa;
1.198 + return 0;
1.199 + }
1.200 +
1.201 +// -----------------------------------------------------------------------------
1.202 +// posix_spawnattr_init
1.203 +// Initialize the spawn attributes structure
1.204 +// -----------------------------------------------------------------------------
1.205 +EXPORT_C int posix_spawnattr_init(posix_spawnattr_t* attrp)
1.206 + {
1.207 + // we don't support these flags. simply set all attribs to 0.
1.208 + if (!attrp)
1.209 + {
1.210 + return EINVAL;
1.211 + }
1.212 + memset(attrp, 0, sizeof(posix_spawnattr_t));
1.213 + return 0;
1.214 + }
1.215 +
1.216 +// -----------------------------------------------------------------------------
1.217 +// posix_spawnattr_getsigdefault
1.218 +// Returns the sigdefault attribute
1.219 +// -----------------------------------------------------------------------------
1.220 +EXPORT_C int posix_spawnattr_getsigdefault(
1.221 + const posix_spawnattr_t* attrp,
1.222 + sigset_t* sigdefault)
1.223 + {
1.224 + if (!attrp || !sigdefault)
1.225 + {
1.226 + return EINVAL;
1.227 + }
1.228 +
1.229 + *sigdefault = attrp->_sd;
1.230 + return 0;
1.231 + }
1.232 +
1.233 +// -----------------------------------------------------------------------------
1.234 +// posix_spawnattr_getflags
1.235 +// Return the flags attribute
1.236 +// -----------------------------------------------------------------------------
1.237 +EXPORT_C int posix_spawnattr_getflags(
1.238 + const posix_spawnattr_t* attrp,
1.239 + short* flags)
1.240 + {
1.241 + if (!attrp || !flags)
1.242 + {
1.243 + return EINVAL;
1.244 + }
1.245 +
1.246 + *flags = attrp->_flags;
1.247 + return 0;
1.248 + }
1.249 +
1.250 +// -----------------------------------------------------------------------------
1.251 +// posix_spawnattr_getpgroup
1.252 +// Return the process group attribute
1.253 +// -----------------------------------------------------------------------------
1.254 +EXPORT_C int posix_spawnattr_getpgroup(
1.255 + const posix_spawnattr_t* attrp,
1.256 + pid_t* pgroup)
1.257 + {
1.258 + if (!attrp || !pgroup)
1.259 + {
1.260 + return EINVAL;
1.261 + }
1.262 +
1.263 + *pgroup = attrp->_pgrp;
1.264 + return 0;
1.265 + }
1.266 +
1.267 +// -----------------------------------------------------------------------------
1.268 +// posix_spawnattr_getschedparam
1.269 +// Return scheduling parameters attribute
1.270 +// -----------------------------------------------------------------------------
1.271 +EXPORT_C int posix_spawnattr_getschedparam(
1.272 + const posix_spawnattr_t* attrp,
1.273 + struct sched_param* schedparam)
1.274 + {
1.275 + if (!attrp || !schedparam)
1.276 + {
1.277 + return EINVAL;
1.278 + }
1.279 +
1.280 + *schedparam = attrp->_sp;
1.281 + return 0;
1.282 + }
1.283 +
1.284 +// -----------------------------------------------------------------------------
1.285 +// posix_spawnattr_getschedpolicy
1.286 +// Return the scheduling policy attribute
1.287 +// -----------------------------------------------------------------------------
1.288 +EXPORT_C int posix_spawnattr_getschedpolicy(
1.289 + const posix_spawnattr_t* attrp,
1.290 + int* policy)
1.291 + {
1.292 + if (!attrp || !policy)
1.293 + {
1.294 + return EINVAL;
1.295 + }
1.296 +
1.297 + *policy = attrp->_policy;
1.298 + return 0;
1.299 + }
1.300 +
1.301 +// -----------------------------------------------------------------------------
1.302 +// posix_spawnattr_getsigmask
1.303 +// Return the signal mask attribute
1.304 +// -----------------------------------------------------------------------------
1.305 +EXPORT_C int posix_spawnattr_getsigmask(
1.306 + const posix_spawnattr_t* attrp,
1.307 + sigset_t* sigmask)
1.308 + {
1.309 + if (!attrp || !sigmask)
1.310 + {
1.311 + return EINVAL;
1.312 + }
1.313 +
1.314 + *sigmask = attrp->_sm;
1.315 + return 0;
1.316 + }
1.317 +
1.318 +// -----------------------------------------------------------------------------
1.319 +// posix_spawnattr_setsigdefault
1.320 +// Sets the sigdefault attribute
1.321 +// -----------------------------------------------------------------------------
1.322 +EXPORT_C int posix_spawnattr_setsigdefault(
1.323 + posix_spawnattr_t* attrp,
1.324 + const sigset_t* sigdefault)
1.325 + {
1.326 + if (!attrp || !sigdefault)
1.327 + {
1.328 + return EINVAL;
1.329 + }
1.330 +
1.331 + attrp->_sd = *sigdefault;
1.332 + return 0;
1.333 + }
1.334 +
1.335 +// -----------------------------------------------------------------------------
1.336 +// posix_spawnattr_setflags
1.337 +// Sets the flags attribute
1.338 +// -----------------------------------------------------------------------------
1.339 +EXPORT_C int posix_spawnattr_setflags(posix_spawnattr_t* attrp, short flags)
1.340 + {
1.341 + if (!attrp)
1.342 + {
1.343 + return EINVAL;
1.344 + }
1.345 +
1.346 + attrp->_flags = flags;
1.347 + return 0;
1.348 + }
1.349 +
1.350 +// -----------------------------------------------------------------------------
1.351 +// posix_spawnattr_setpgroup
1.352 +// Sets the process group attribute
1.353 +// -----------------------------------------------------------------------------
1.354 +EXPORT_C int posix_spawnattr_setpgroup(posix_spawnattr_t* attrp, pid_t pgroup)
1.355 + {
1.356 + if (!attrp)
1.357 + {
1.358 + return EINVAL;
1.359 + }
1.360 +
1.361 + attrp->_pgrp = pgroup;
1.362 + return 0;
1.363 + }
1.364 +
1.365 +// -----------------------------------------------------------------------------
1.366 +// posix_spawnattr_setschedparam
1.367 +// Sets the scheduling parameters attribute
1.368 +// -----------------------------------------------------------------------------
1.369 +EXPORT_C int posix_spawnattr_setschedparam(
1.370 + posix_spawnattr_t* attrp,
1.371 + const struct sched_param* schedparam)
1.372 + {
1.373 + if (!attrp || !schedparam)
1.374 + {
1.375 + return EINVAL;
1.376 + }
1.377 +
1.378 + attrp->_sp = *schedparam;
1.379 + return 0;
1.380 + }
1.381 +
1.382 +// -----------------------------------------------------------------------------
1.383 +// posix_spawnattr_setschedpolicy
1.384 +// Sets the scheduling policy attribute
1.385 +// -----------------------------------------------------------------------------
1.386 +EXPORT_C int posix_spawnattr_setschedpolicy(posix_spawnattr_t* attrp, int policy)
1.387 + {
1.388 + if (!attrp)
1.389 + {
1.390 + return EINVAL;
1.391 + }
1.392 +
1.393 + attrp->_policy = policy;
1.394 + return 0;
1.395 + }
1.396 +
1.397 +// -----------------------------------------------------------------------------
1.398 +// posix_spawnattr_setsigdefault
1.399 +// Sets the sigmask attribute
1.400 +// -----------------------------------------------------------------------------
1.401 +EXPORT_C int posix_spawnattr_setsigmask(
1.402 + posix_spawnattr_t* attrp,
1.403 + const sigset_t* sigmask)
1.404 + {
1.405 + if (!attrp || !sigmask)
1.406 + {
1.407 + return EINVAL;
1.408 + }
1.409 +
1.410 + attrp->_sm = *sigmask;
1.411 + return 0;
1.412 + }
1.413 +
1.414 +// -----------------------------------------------------------------------------
1.415 +// posix_spawnattr_setsigdefault
1.416 +// Empty and cleanup the spawn attributes structure
1.417 +// -----------------------------------------------------------------------------
1.418 +EXPORT_C int posix_spawnattr_destroy(posix_spawnattr_t* /*attrp*/)
1.419 + {
1.420 + // nothing to do
1.421 + return 0;
1.422 + }
1.423 +
1.424 +// -----------------------------------------------------------------------------
1.425 +// posix_spawn
1.426 +// Launch a child process specified by path and obtain its pid
1.427 +// This API allows the caller to specify command line arguments and envp for the child
1.428 +// In addition, one can also specify a set of file operations that will be performed
1.429 +// and a set of attributes that will be applied in the child before it enters its main.
1.430 +// -----------------------------------------------------------------------------
1.431 +EXPORT_C int posix_spawn(
1.432 + pid_t* pid,
1.433 + const char* path,
1.434 + const posix_spawn_file_actions_t* file_actions,
1.435 + const posix_spawnattr_t* attrp,
1.436 + char *const argv[],
1.437 + char *const envp[])
1.438 + {
1.439 + if(path == NULL || *path == '\0')
1.440 + {
1.441 + return ECHILD;
1.442 + }
1.443 +
1.444 + int len = strlen(path) + 1;
1.445 + wchar_t* wpath = new wchar_t[len];
1.446 + if (mbstowcs(wpath, path, len) == (size_t)-1)
1.447 + {
1.448 + delete[] wpath;
1.449 + return EILSEQ;
1.450 + }
1.451 +
1.452 + int ret = 0;
1.453 +
1.454 + wchar_t* wargs = NULL;
1.455 + wchar_t** wenvp = NULL;
1.456 +
1.457 + if (argv && argv[1])
1.458 + {
1.459 + TInt totlen = 0;
1.460 + // argv[0] is (or atleast should be) the exe name
1.461 + for (int i = 1; argv[i]; ++i)
1.462 + {
1.463 + totlen += strlen(argv[i]) + 1;
1.464 + }
1.465 +
1.466 + wargs = new wchar_t[totlen+1];
1.467 +
1.468 + if (!wargs)
1.469 + {
1.470 + ret = ENOMEM;
1.471 + goto bailout;
1.472 + }
1.473 +
1.474 + wchar_t* wp = wargs;
1.475 + // argv[0] is (or atleast should be) the exe name
1.476 + for (int i = 1; argv[i]; ++i)
1.477 + {
1.478 + int len = strlen(argv[i]);
1.479 + if (mbstowcs(wp, argv[i], len) == (size_t)-1)
1.480 + {
1.481 + ret = EILSEQ;
1.482 + goto bailout;
1.483 + }
1.484 + wp[len++] = L' ';
1.485 + wp += len;
1.486 + }
1.487 +
1.488 + // replace the last blank with a null character
1.489 + *(--wp) = 0;
1.490 + }
1.491 +
1.492 + if (envp)
1.493 + {
1.494 + TInt count = 0;
1.495 + for (; envp[count]; ++count) {}
1.496 +
1.497 + //coverity[alloc_fn]
1.498 +
1.499 + //coverity[assign]
1.500 +
1.501 + wenvp = new wchar_t*[count+1];
1.502 + if (!wenvp)
1.503 + {
1.504 + ret = ENOMEM;
1.505 + goto bailout;
1.506 + }
1.507 +
1.508 + for (int i = 0; i < count; ++i)
1.509 + {
1.510 + int len = strlen(envp[i]) + 1;
1.511 + wenvp[i] = new wchar_t[len];
1.512 + if (wenvp[i] == NULL)
1.513 + {
1.514 + ret = ENOMEM;
1.515 + goto bailout;
1.516 + }
1.517 +
1.518 + if (mbstowcs(wenvp[i], envp[i], len) == (size_t)-1)
1.519 + {
1.520 + ret = EILSEQ;
1.521 + wenvp[i+1] = NULL;
1.522 + goto bailout;
1.523 + }
1.524 + }
1.525 +
1.526 + wenvp[count] = 0;
1.527 + }
1.528 +
1.529 + //coverity[leave_without_push]
1.530 +
1.531 + ret = _posix_spawn_r(pid, wpath, file_actions, attrp, wargs, wenvp);
1.532 +
1.533 +bailout:
1.534 + delete[] wpath;
1.535 + if (wargs)
1.536 + {
1.537 + delete[] wargs;
1.538 + }
1.539 +
1.540 + if (wenvp)
1.541 + {
1.542 + for (int i = 0; wenvp[i]; ++i)
1.543 + {
1.544 + delete wenvp[i];
1.545 + }
1.546 + delete wenvp;
1.547 + }
1.548 +
1.549 + return ret;
1.550 + }
1.551 +
1.552 +} //extern "C"