os/ossrv/genericopenlibs/openenvcore/libc/src/spawn.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// 
sl@0
    15
//
sl@0
    16
sl@0
    17
#include <e32std.h>
sl@0
    18
#include "spawn_r.h"
sl@0
    19
#include <spawn.h>
sl@0
    20
#include <sys/syslimits.h>
sl@0
    21
#include <errno.h>
sl@0
    22
#include <wchar.h>
sl@0
    23
#include <stdlib.h>
sl@0
    24
#include <string.h>
sl@0
    25
#include "sysreent.h"
sl@0
    26
sl@0
    27
extern "C" {
sl@0
    28
sl@0
    29
// -----------------------------------------------------------------------------
sl@0
    30
// posix_spawn_file_actions_init
sl@0
    31
// Initialize the file actions structure
sl@0
    32
// -----------------------------------------------------------------------------
sl@0
    33
EXPORT_C int posix_spawn_file_actions_init(posix_spawn_file_actions_t* file_actions)
sl@0
    34
	{
sl@0
    35
	file_actions->_fa = new file_actions_t;
sl@0
    36
	if (!file_actions->_fa)
sl@0
    37
		{
sl@0
    38
		return ENOMEM;
sl@0
    39
		}
sl@0
    40
	return 0;
sl@0
    41
	}
sl@0
    42
sl@0
    43
// -----------------------------------------------------------------------------
sl@0
    44
// posix_spawn_file_actions_addopen
sl@0
    45
// Add an open action to the file actions structure
sl@0
    46
// -----------------------------------------------------------------------------
sl@0
    47
EXPORT_C int posix_spawn_file_actions_addopen(
sl@0
    48
				posix_spawn_file_actions_t* file_actions, 
sl@0
    49
				int fid,
sl@0
    50
				const char* path, 
sl@0
    51
				int oflag, 
sl@0
    52
				mode_t mode)
sl@0
    53
	{
sl@0
    54
	if (fid < 0 || fid > OPEN_MAX)
sl@0
    55
		{
sl@0
    56
		return EBADF;
sl@0
    57
		}
sl@0
    58
		
sl@0
    59
	TFileAction* fa = new TFileAction;
sl@0
    60
	if (!fa)
sl@0
    61
		{
sl@0
    62
		return ENOMEM;
sl@0
    63
		}
sl@0
    64
	
sl@0
    65
	memset(fa, 0, sizeof(TFileAction));	
sl@0
    66
	fa->iOp = EOpen;
sl@0
    67
	fa->iFid1 = fid;
sl@0
    68
	fa->iOFlag = oflag;
sl@0
    69
	fa->iMode = mode;
sl@0
    70
	
sl@0
    71
	int len = strlen(path)+1;
sl@0
    72
	wchar_t* wpath = new wchar_t[len];
sl@0
    73
	if (!wpath)
sl@0
    74
		{
sl@0
    75
		delete fa;
sl@0
    76
		return ENOMEM;
sl@0
    77
		}
sl@0
    78
		
sl@0
    79
	if (mbstowcs(wpath, path, len) == (size_t)-1)
sl@0
    80
		{
sl@0
    81
		delete fa;
sl@0
    82
		delete[] wpath;
sl@0
    83
		return EILSEQ;
sl@0
    84
		}
sl@0
    85
	
sl@0
    86
	fa->iPath = new TFileName;
sl@0
    87
	fa->iPath->Copy((TText16*)wpath, len);
sl@0
    88
	delete[] wpath;
sl@0
    89
	
sl@0
    90
	(file_actions->_fa->iActions).AddLast(*fa);
sl@0
    91
	if (file_actions->_fa->iIter == NULL)
sl@0
    92
		{
sl@0
    93
		(file_actions->_fa->iIter).SetToFirst();
sl@0
    94
		}
sl@0
    95
	
sl@0
    96
	return 0;
sl@0
    97
	}
sl@0
    98
	
sl@0
    99
// -----------------------------------------------------------------------------
sl@0
   100
// posix_spawn_file_actions_adddup2
sl@0
   101
// Add a dup2 action to the file actions structure
sl@0
   102
// -----------------------------------------------------------------------------
sl@0
   103
EXPORT_C int posix_spawn_file_actions_adddup2(
sl@0
   104
				posix_spawn_file_actions_t* file_actions, 
sl@0
   105
				int fid1, 
sl@0
   106
				int fid2)
sl@0
   107
	{
sl@0
   108
	if (fid1 < 0 || fid2 < 0 || fid1 > OPEN_MAX || fid2 > OPEN_MAX)
sl@0
   109
		{
sl@0
   110
		return EBADF;
sl@0
   111
		}
sl@0
   112
		
sl@0
   113
	TFileAction* fa = new TFileAction;
sl@0
   114
	if (!fa)
sl@0
   115
		{
sl@0
   116
		return ENOMEM;
sl@0
   117
		}
sl@0
   118
sl@0
   119
	memset(fa, 0, sizeof(TFileAction));		
sl@0
   120
	fa->iOp = EDup;
sl@0
   121
	fa->iFid1 = fid1;
sl@0
   122
	fa->iFid2 = fid2;
sl@0
   123
	
sl@0
   124
	(file_actions->_fa->iActions).AddLast(*fa);
sl@0
   125
	if (file_actions->_fa->iIter == NULL)
sl@0
   126
		{
sl@0
   127
		(file_actions->_fa->iIter).SetToFirst();
sl@0
   128
		}
sl@0
   129
		
sl@0
   130
	return 0;
sl@0
   131
	}
sl@0
   132
sl@0
   133
// -----------------------------------------------------------------------------
sl@0
   134
// posix_spawn_file_actions_addclose
sl@0
   135
// Add a close action to the file actions structure
sl@0
   136
// -----------------------------------------------------------------------------
sl@0
   137
EXPORT_C int posix_spawn_file_actions_addclose(
sl@0
   138
				posix_spawn_file_actions_t* file_actions, 
sl@0
   139
				int fid)
sl@0
   140
	{
sl@0
   141
	if (fid < 0 || fid > OPEN_MAX)
sl@0
   142
		{
sl@0
   143
		return EBADF;
sl@0
   144
		}
sl@0
   145
		
sl@0
   146
	TFileAction* fa = new TFileAction;
sl@0
   147
	if (!fa)
sl@0
   148
		{
sl@0
   149
		return ENOMEM;
sl@0
   150
		}
sl@0
   151
	
sl@0
   152
	memset(fa, 0, sizeof(TFileAction));	
sl@0
   153
	fa->iOp = EClose;
sl@0
   154
	fa->iFid1 = fid;
sl@0
   155
	(file_actions->_fa->iActions).AddLast(*fa);
sl@0
   156
	if (file_actions->_fa->iIter == NULL)
sl@0
   157
		{
sl@0
   158
		(file_actions->_fa->iIter).SetToFirst();
sl@0
   159
		}
sl@0
   160
		
sl@0
   161
	return 0;
sl@0
   162
	}
sl@0
   163
sl@0
   164
// -----------------------------------------------------------------------------
sl@0
   165
// posix_spawn_file_actions_destroy
sl@0
   166
// Empty and destroy the file actions structure
sl@0
   167
// -----------------------------------------------------------------------------
sl@0
   168
EXPORT_C int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* file_actions)
sl@0
   169
	{
sl@0
   170
	if (!file_actions || !file_actions->_fa)
sl@0
   171
		{
sl@0
   172
		return EINVAL;
sl@0
   173
		}
sl@0
   174
		
sl@0
   175
	if (file_actions->_fa->iActions.IsEmpty())
sl@0
   176
		{
sl@0
   177
		delete file_actions->_fa;
sl@0
   178
		return 0;
sl@0
   179
		}
sl@0
   180
	
sl@0
   181
	TFileAction* fa = (file_actions->_fa->iIter)++;
sl@0
   182
	while (fa)
sl@0
   183
		{
sl@0
   184
		if (fa->iPath)
sl@0
   185
			{
sl@0
   186
			delete fa->iPath;
sl@0
   187
			}
sl@0
   188
			
sl@0
   189
		delete fa;
sl@0
   190
		fa = (file_actions->_fa->iIter)++;
sl@0
   191
		}
sl@0
   192
		
sl@0
   193
	file_actions->_fa->iActions.Reset();
sl@0
   194
	delete file_actions->_fa;
sl@0
   195
	return 0;
sl@0
   196
	}
sl@0
   197
sl@0
   198
// -----------------------------------------------------------------------------
sl@0
   199
// posix_spawnattr_init
sl@0
   200
// Initialize the spawn attributes structure
sl@0
   201
// -----------------------------------------------------------------------------
sl@0
   202
EXPORT_C int posix_spawnattr_init(posix_spawnattr_t* attrp)
sl@0
   203
	{
sl@0
   204
	// we don't support these flags. simply set all attribs to 0.
sl@0
   205
	if (!attrp)
sl@0
   206
		{
sl@0
   207
		return EINVAL;
sl@0
   208
		}
sl@0
   209
	memset(attrp, 0, sizeof(posix_spawnattr_t));
sl@0
   210
	return 0;
sl@0
   211
	}
sl@0
   212
sl@0
   213
// -----------------------------------------------------------------------------
sl@0
   214
// posix_spawnattr_getsigdefault
sl@0
   215
// Returns the sigdefault attribute
sl@0
   216
// -----------------------------------------------------------------------------
sl@0
   217
EXPORT_C int posix_spawnattr_getsigdefault(
sl@0
   218
				const posix_spawnattr_t* attrp, 
sl@0
   219
				sigset_t* sigdefault)
sl@0
   220
	{
sl@0
   221
	if (!attrp || !sigdefault)
sl@0
   222
		{
sl@0
   223
		return EINVAL;
sl@0
   224
		}
sl@0
   225
	
sl@0
   226
	*sigdefault = attrp->_sd;
sl@0
   227
	return 0;
sl@0
   228
	}
sl@0
   229
sl@0
   230
// -----------------------------------------------------------------------------
sl@0
   231
// posix_spawnattr_getflags
sl@0
   232
// Return the flags attribute
sl@0
   233
// -----------------------------------------------------------------------------
sl@0
   234
EXPORT_C int posix_spawnattr_getflags(
sl@0
   235
				const posix_spawnattr_t* attrp,
sl@0
   236
				short* flags)
sl@0
   237
	{
sl@0
   238
	if (!attrp || !flags)
sl@0
   239
		{
sl@0
   240
		return EINVAL;
sl@0
   241
		}
sl@0
   242
	
sl@0
   243
	*flags = attrp->_flags;
sl@0
   244
	return 0;
sl@0
   245
	}
sl@0
   246
sl@0
   247
// -----------------------------------------------------------------------------
sl@0
   248
// posix_spawnattr_getpgroup
sl@0
   249
// Return the process group attribute
sl@0
   250
// -----------------------------------------------------------------------------
sl@0
   251
EXPORT_C int posix_spawnattr_getpgroup(
sl@0
   252
				const posix_spawnattr_t* attrp, 
sl@0
   253
				pid_t* pgroup)
sl@0
   254
	{
sl@0
   255
	if (!attrp || !pgroup)
sl@0
   256
		{
sl@0
   257
		return EINVAL;
sl@0
   258
		}
sl@0
   259
	
sl@0
   260
	*pgroup = attrp->_pgrp;
sl@0
   261
	return 0;
sl@0
   262
	}
sl@0
   263
sl@0
   264
// -----------------------------------------------------------------------------
sl@0
   265
// posix_spawnattr_getschedparam
sl@0
   266
// Return scheduling parameters attribute
sl@0
   267
// -----------------------------------------------------------------------------
sl@0
   268
EXPORT_C int posix_spawnattr_getschedparam(
sl@0
   269
				const posix_spawnattr_t* attrp,
sl@0
   270
          		struct sched_param* schedparam)
sl@0
   271
	{
sl@0
   272
	if (!attrp || !schedparam)
sl@0
   273
		{
sl@0
   274
		return EINVAL;
sl@0
   275
		}
sl@0
   276
	
sl@0
   277
	*schedparam = attrp->_sp;
sl@0
   278
	return 0;
sl@0
   279
	}
sl@0
   280
sl@0
   281
// -----------------------------------------------------------------------------
sl@0
   282
// posix_spawnattr_getschedpolicy
sl@0
   283
// Return the scheduling policy attribute
sl@0
   284
// -----------------------------------------------------------------------------
sl@0
   285
EXPORT_C int posix_spawnattr_getschedpolicy(
sl@0
   286
				const posix_spawnattr_t* attrp, 
sl@0
   287
				int* policy)
sl@0
   288
	{
sl@0
   289
	if (!attrp || !policy)
sl@0
   290
		{
sl@0
   291
		return EINVAL;
sl@0
   292
		}
sl@0
   293
	
sl@0
   294
	*policy = attrp->_policy;
sl@0
   295
	return 0;
sl@0
   296
	}
sl@0
   297
sl@0
   298
// -----------------------------------------------------------------------------
sl@0
   299
// posix_spawnattr_getsigmask
sl@0
   300
// Return the signal mask attribute
sl@0
   301
// -----------------------------------------------------------------------------
sl@0
   302
EXPORT_C int posix_spawnattr_getsigmask(
sl@0
   303
				const posix_spawnattr_t* attrp, 
sl@0
   304
				sigset_t* sigmask)
sl@0
   305
	{
sl@0
   306
	if (!attrp || !sigmask)
sl@0
   307
		{
sl@0
   308
		return EINVAL;
sl@0
   309
		}
sl@0
   310
	
sl@0
   311
	*sigmask = attrp->_sm;
sl@0
   312
	return 0;
sl@0
   313
	}
sl@0
   314
sl@0
   315
// -----------------------------------------------------------------------------
sl@0
   316
// posix_spawnattr_setsigdefault
sl@0
   317
// Sets the sigdefault attribute
sl@0
   318
// -----------------------------------------------------------------------------
sl@0
   319
EXPORT_C int posix_spawnattr_setsigdefault(
sl@0
   320
				posix_spawnattr_t* attrp,
sl@0
   321
				const sigset_t* sigdefault)
sl@0
   322
	{
sl@0
   323
	if (!attrp || !sigdefault)
sl@0
   324
		{
sl@0
   325
		return EINVAL;
sl@0
   326
		}
sl@0
   327
	
sl@0
   328
	attrp->_sd = *sigdefault;
sl@0
   329
	return 0;
sl@0
   330
	}
sl@0
   331
sl@0
   332
// -----------------------------------------------------------------------------
sl@0
   333
// posix_spawnattr_setflags
sl@0
   334
// Sets the flags attribute
sl@0
   335
// -----------------------------------------------------------------------------
sl@0
   336
EXPORT_C int posix_spawnattr_setflags(posix_spawnattr_t* attrp, short flags)
sl@0
   337
	{
sl@0
   338
	if (!attrp)
sl@0
   339
		{
sl@0
   340
		return EINVAL;
sl@0
   341
		}
sl@0
   342
	
sl@0
   343
	attrp->_flags = flags;
sl@0
   344
	return 0;
sl@0
   345
	}
sl@0
   346
sl@0
   347
// -----------------------------------------------------------------------------
sl@0
   348
// posix_spawnattr_setpgroup
sl@0
   349
// Sets the process group attribute
sl@0
   350
// -----------------------------------------------------------------------------
sl@0
   351
EXPORT_C int posix_spawnattr_setpgroup(posix_spawnattr_t* attrp, pid_t pgroup)
sl@0
   352
	{
sl@0
   353
	if (!attrp)
sl@0
   354
		{
sl@0
   355
		return EINVAL;
sl@0
   356
		}
sl@0
   357
	
sl@0
   358
	attrp->_pgrp = pgroup;
sl@0
   359
	return 0;
sl@0
   360
	}
sl@0
   361
sl@0
   362
// -----------------------------------------------------------------------------
sl@0
   363
// posix_spawnattr_setschedparam
sl@0
   364
// Sets the scheduling parameters attribute
sl@0
   365
// -----------------------------------------------------------------------------
sl@0
   366
EXPORT_C int posix_spawnattr_setschedparam(
sl@0
   367
				posix_spawnattr_t* attrp,
sl@0
   368
				const struct sched_param* schedparam)
sl@0
   369
	{
sl@0
   370
	if (!attrp || !schedparam)
sl@0
   371
		{
sl@0
   372
		return EINVAL;
sl@0
   373
		}
sl@0
   374
	
sl@0
   375
	attrp->_sp = *schedparam;
sl@0
   376
	return 0;
sl@0
   377
	}
sl@0
   378
sl@0
   379
// -----------------------------------------------------------------------------
sl@0
   380
// posix_spawnattr_setschedpolicy
sl@0
   381
// Sets the scheduling policy attribute
sl@0
   382
// -----------------------------------------------------------------------------
sl@0
   383
EXPORT_C int posix_spawnattr_setschedpolicy(posix_spawnattr_t* attrp, int policy)
sl@0
   384
	{
sl@0
   385
	if (!attrp)
sl@0
   386
		{
sl@0
   387
		return EINVAL;
sl@0
   388
		}
sl@0
   389
	
sl@0
   390
	attrp->_policy = policy;
sl@0
   391
	return 0;
sl@0
   392
	}
sl@0
   393
sl@0
   394
// -----------------------------------------------------------------------------
sl@0
   395
// posix_spawnattr_setsigdefault
sl@0
   396
// Sets the sigmask attribute
sl@0
   397
// -----------------------------------------------------------------------------
sl@0
   398
EXPORT_C int posix_spawnattr_setsigmask(
sl@0
   399
				posix_spawnattr_t* attrp, 
sl@0
   400
				const sigset_t* sigmask)
sl@0
   401
	{
sl@0
   402
	if (!attrp || !sigmask)
sl@0
   403
		{
sl@0
   404
		return EINVAL;
sl@0
   405
		}
sl@0
   406
	
sl@0
   407
	attrp->_sm = *sigmask;
sl@0
   408
	return 0;
sl@0
   409
	}
sl@0
   410
sl@0
   411
// -----------------------------------------------------------------------------
sl@0
   412
// posix_spawnattr_setsigdefault
sl@0
   413
// Empty and cleanup the spawn attributes structure
sl@0
   414
// -----------------------------------------------------------------------------
sl@0
   415
EXPORT_C int posix_spawnattr_destroy(posix_spawnattr_t* /*attrp*/)
sl@0
   416
	{
sl@0
   417
	// nothing to do
sl@0
   418
	return 0;
sl@0
   419
	}
sl@0
   420
sl@0
   421
// -----------------------------------------------------------------------------
sl@0
   422
// posix_spawn
sl@0
   423
// Launch a child process specified by path and obtain its pid
sl@0
   424
// This API allows the caller to specify command line arguments and envp for the child
sl@0
   425
// In addition, one can also specify a set of file operations that will be performed
sl@0
   426
// and a set of attributes that will be applied in the child before it enters its main.
sl@0
   427
// -----------------------------------------------------------------------------
sl@0
   428
EXPORT_C int posix_spawn(
sl@0
   429
				pid_t* pid, 
sl@0
   430
				const char* path,
sl@0
   431
				const posix_spawn_file_actions_t* file_actions,
sl@0
   432
				const posix_spawnattr_t* attrp, 
sl@0
   433
				char *const argv[],
sl@0
   434
				char *const envp[])
sl@0
   435
	{
sl@0
   436
	if(path == NULL || *path == '\0')
sl@0
   437
		{
sl@0
   438
		return ECHILD;
sl@0
   439
		}
sl@0
   440
		
sl@0
   441
	int len = strlen(path) + 1;
sl@0
   442
	wchar_t* wpath = new wchar_t[len];
sl@0
   443
	if (mbstowcs(wpath, path, len) == (size_t)-1)
sl@0
   444
		{
sl@0
   445
		delete[] wpath;
sl@0
   446
		return EILSEQ;
sl@0
   447
		}
sl@0
   448
	
sl@0
   449
	int ret = 0;
sl@0
   450
	
sl@0
   451
	wchar_t* wargs = NULL;
sl@0
   452
	wchar_t** wenvp = NULL;
sl@0
   453
	
sl@0
   454
	if (argv && argv[1])
sl@0
   455
		{
sl@0
   456
		TInt totlen = 0;
sl@0
   457
		// argv[0] is (or atleast should be) the exe name
sl@0
   458
		for (int i = 1; argv[i]; ++i)
sl@0
   459
			{
sl@0
   460
			totlen += strlen(argv[i]) + 1;
sl@0
   461
			}
sl@0
   462
			
sl@0
   463
		wargs = new wchar_t[totlen+1];
sl@0
   464
		
sl@0
   465
		if (!wargs)
sl@0
   466
			{
sl@0
   467
			ret = ENOMEM;
sl@0
   468
			goto bailout;
sl@0
   469
			}
sl@0
   470
sl@0
   471
		wchar_t* wp = wargs;
sl@0
   472
		// argv[0] is (or atleast should be) the exe name
sl@0
   473
		for (int i = 1; argv[i]; ++i)
sl@0
   474
			{
sl@0
   475
			int len = strlen(argv[i]);
sl@0
   476
			if (mbstowcs(wp, argv[i], len) == (size_t)-1)
sl@0
   477
				{
sl@0
   478
				ret = EILSEQ;
sl@0
   479
				goto bailout;
sl@0
   480
				}
sl@0
   481
			wp[len++] = L' ';
sl@0
   482
			wp += len;
sl@0
   483
			}
sl@0
   484
		
sl@0
   485
		// replace the last blank with a null character
sl@0
   486
		*(--wp) = 0;
sl@0
   487
		}
sl@0
   488
	
sl@0
   489
	if (envp)
sl@0
   490
		{
sl@0
   491
		TInt count = 0;
sl@0
   492
		for (; envp[count]; ++count) {}
sl@0
   493
sl@0
   494
		//coverity[alloc_fn]
sl@0
   495
sl@0
   496
		//coverity[assign]
sl@0
   497
	
sl@0
   498
		wenvp = new wchar_t*[count+1];
sl@0
   499
		if (!wenvp)
sl@0
   500
			{
sl@0
   501
			ret = ENOMEM;
sl@0
   502
			goto bailout;
sl@0
   503
			}
sl@0
   504
			
sl@0
   505
		for (int i = 0; i < count; ++i)
sl@0
   506
			{
sl@0
   507
			int len = strlen(envp[i]) + 1;
sl@0
   508
			wenvp[i] = new wchar_t[len];
sl@0
   509
			if (wenvp[i] == NULL)
sl@0
   510
				{
sl@0
   511
				ret = ENOMEM;
sl@0
   512
				goto bailout;
sl@0
   513
				}
sl@0
   514
			
sl@0
   515
			if (mbstowcs(wenvp[i], envp[i], len) == (size_t)-1)
sl@0
   516
				{
sl@0
   517
				ret = EILSEQ;
sl@0
   518
				wenvp[i+1] = NULL;
sl@0
   519
				goto bailout;
sl@0
   520
				}
sl@0
   521
			}
sl@0
   522
				
sl@0
   523
		wenvp[count] = 0;
sl@0
   524
		}
sl@0
   525
sl@0
   526
	//coverity[leave_without_push]
sl@0
   527
sl@0
   528
	ret = _posix_spawn_r(pid, wpath, file_actions, attrp, wargs, wenvp);
sl@0
   529
sl@0
   530
bailout:
sl@0
   531
	delete[] wpath;
sl@0
   532
	if (wargs)
sl@0
   533
		{
sl@0
   534
		delete[] wargs;
sl@0
   535
		}
sl@0
   536
		
sl@0
   537
	if (wenvp)
sl@0
   538
		{
sl@0
   539
		for (int i = 0; wenvp[i]; ++i)
sl@0
   540
			{
sl@0
   541
			delete wenvp[i];
sl@0
   542
			}
sl@0
   543
		delete wenvp;
sl@0
   544
		}
sl@0
   545
sl@0
   546
	return ret;
sl@0
   547
	}
sl@0
   548
sl@0
   549
}  //extern "C"