Up to 16 separate pieces of information can be passed to a process on creation using Environment Slots. These include handles and binary data.
Handles and binary data can be passed to a process at process creation time using environment slots. This topic describes this concept, and explains how to use the process APIs for environment slots.
Handles and binary data, in the form of descriptors or integer values, can be passed to a process at process creation time, using what are called environment slots.
Up to 16 separate pieces of information can be passed to a process on creation. For this purpose, a process has 16 environment slots that can contain the information passed to it by the launching process.
Slot 0 is reserved and is never available for general purpose information passing.
The parent (launching) process can only pass information to the child (created) process after the child process has been created. However, it should be done before the child process is resumed; it is an error to try and set environment data in a child process that has been resumed.
A child process can only extract the information from its environment slots once. Extracting information from a slot causes that information to be deleted from the slot.
It is a matter of convention between the parent and child process as to the meaning to be applied to a slot, and the type of data that it is to contain.
To pass, a handle, a client server subsession, or binary data to a child process, the parent process calls RProcess::SetParameter(), where the RProcess object represents the newly created child process. There are five overloaded variants of SetParameter() used for passing:
To extract, a handle, or a client server subsession, a child process can use the Open() function called on the relevant RHandleBase derived type:
TInt RSemaphore ::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); TInt RBusLogicalChannel::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); TInt RMsgQueueBase::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); TInt RMutex::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); TInt RChunk::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); TInt RSessionBase::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess);
To extract descriptor data, or integer data, a child process can use the User class functions:
static TInt User::ParameterLength(TInt aSlot); static TInt User::GetTIntParameter(TInt aSlot, TInt& aData); static TInt User::GetDesParameter(TInt aSlot, TDes8& aDes); static TInt User::GetDesParameter(TInt aSlot, TDes16& aDes);
File server session handles and file handles can both be passed to a child process.
The child process adopts the file handle, and must not be closed by the parent. To use a file handle, the session handle must also be passed.
For security reasons, when sharing a file handle, the parent process should create a separate file server session for the specific purpose of sharing the file handle. If the parent process has other files open with this file server session, the child process can gain access to those files by iterating through all the possible values for the file handle and attempting to Adopt() each one. For the same reason, the child process should only use this session for sharing the file; it should not access other files through this session.
The following two code fragments show code in the parent process and corresponding code in the child process.
//Code in the parent (launching) process RProcess p; p.Create(KProcName, KNullDesC); //create “child” process RFile file; RFs session; session.Connect(); //connect to file server session.ShareProtected(); file.Create(iSession, KFileName, EFileStreamText|EFileWrite|EFileShareAny); file.Write(0, KTestData); p.SetParameter(5, session); //session handle passed in slot 5 p.SetParameter(6, file); //file handle passed in slot 6 Session.Close(); p.Resume();
KProcName is the full path name of the executable associated with the child process, and KFilename is the file name.
//Code in the child (launched) process RFs session; session.Open(5); //obtain session handle from slot 5 RFile file; TInt handle; ret = User::GetTIntParameter(8, handle);//get file handle from slot 8 file.Adopt(session, handle); //adopt the handle TBuf8<100> rbuf; //use the file ret = file.Read(0, rbuf); file.Close(); session.Close();
General handles derived from RHandleBase can be passed to a child process.
The handle is duplicated when it is stored in the child process’s environment. The parent can close the handle immediately after calling SetParameter(), or continue to use the handle and close it later.
The following two code fragments show code in the parent process and corresponding code in the child process.
//Code in the parent (launching) process, //passing handles to a mutex and a semaphore. RMutex mutex; RSemaphore sem; RProcess p; p.Create(KProcName, KNullDesC); mutex.CreateGlobal(KMutexName); //create the mutex sem.CreateGlobal(KSemName,0); //create the semaphore p.SetParameter(3, mutex); //put mutex handle into child process env' slot 3 p.SetParameter(4, sem); //put semaphore handle into child process env' slot 4 mutex.Close(); Sem.Close(); p.Resume(); //resume the child process
//Code in the child (launched) process retrieving the handles. RMutex mutex; mutex.Open(3, EOwnerThread); //get mutex handle RSemaphore sem; sem.Open(4, EOwnerThread); //get semaphore handle //use the semaphore and mutex mutex.Close(); sem.Close();
Both 8-bit and 16-bit descriptor data can be passed from a parent to a child process.
Internally, an HBuf descriptor is created containing the passed descriptor data, and a pointer to this descriptor is passed in the relevant slot.
The child process retrieves the descriptor data by calling User::GetDesParameter(). It can get the length of the data by calling User::ParameterLength().
The following two code fragments show code in the parent process and corresponding code in the child process.
//Code in the parent (launching) process, passing 8 and sixteen bit data RProcess p; p.Create(KProcName, KNullDesC); p.SetParameter(2, KSixteenBitDes); p.SetParameter(3, KEightBitDes); p.Resume();
where KSixteenBitDes is a 16-descriptor, and KEightBitDes is an 8-bit descriptor.
//Code in the child (launched) process retrieving 8 and sixteen bit data TInt len; TInt ret; TBuf16<40> buf; len = User::ParameterLength(2); //parameter length is the size in bytes ret = User::GetDesParameter(2, buf); //buf.Length() should have the value of len/2; TBuf8<40> buf8; len = User::ParameterLength(3); ret = User::GetDesParameter(3, buf8); //buf.Length() should be the same as len
Note that the descriptors, buf, and buf8 used in the child process must have sufficiently large maximum lengths to accomodate the data.
An integer can be passed from a parent to a child process.
The following two code fragments show code in the parent process and corresponding code in the child process.
//Code in the parent (launching) process RProcess p; TInt ret; ret = p.Create(KProcName, KNullDesC); p.SetParameter(12, 1234); // Using slot 12 p.Resume();
//Code in the child (launched) process, retrieving the integer. TInt val; TInt ret; ret = User::GetTIntParameter(12, val);
The parent process is panicked when calling SetParameter() with a handle if:
the parent process is not the creator of the child process
the slot number is out of range, i.e. is not in the range 0 to 15
the slot is in use
the handle is local.
The parent process is panicked when calling SetParameter() with a descriptor or integer if:
the parent process is not the creator of the child process
the slot number is out of range, i.e. is not in the range 0 to 15
the slot is in use
the length of the data is negative.
The child process is panicked if the slot number is out of range.
The API functions that extract data from the process environment return KErrArgument if a slot contains the incorrect data type, or the length is incorrect. They return KErrNotFound if a slot is empty.
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.