Adaptation/GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51" xml:lang="en"><title>Environment
       
    13 Slots</title><shortdesc>Up to 16 separate pieces of information can be passed to a process
       
    14 on creation using Environment Slots. These include handles and binary data.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <p>Handles and binary data can be passed to a process at process creation
       
    16 time using environment slots. This topic describes this concept, and explains
       
    17 how to use the process APIs for environment slots. </p>
       
    18 <ul>
       
    19 <li id="GUID-1D2A9BFD-FAE6-55F0-9A54-58BA4165B1F0"><p> <xref href="GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita#GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51/GUID-FCF8DC31-9D90-53C8-BE30-76D6CD0243BC">Overview</xref>  </p> </li>
       
    20 <li id="GUID-E2F77CE5-E856-582C-BF4F-0EF13E6A40D1"><p> <xref href="GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita#GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51/GUID-D84521B5-4C3B-538C-946A-88EAA3713A8D">The APIs</xref>  </p> </li>
       
    21 <li id="GUID-8C3631E9-D240-5C72-A6E0-EF255A3C8D17"><p> <xref href="GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita#GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51/GUID-7F6B118C-0911-5979-8420-475985DB884B">Passing a file handle and a subsession</xref>  </p> </li>
       
    22 <li id="GUID-3DDB166F-E949-5B0A-B4B9-FC6EE580ECCE"><p> <xref href="GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita#GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51/GUID-19964DED-E6AD-59B4-BEDB-2A40864FBD29">Passing a general handle, derived from RHandleBase</xref>  </p> </li>
       
    23 <li id="GUID-D6A9288F-5B22-56B8-8F8E-738F7B38BD1E"><p> <xref href="GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita#GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51/GUID-AAB81C64-A515-50E5-BF80-1D625AF1251C">Passing descriptor data</xref>  </p> </li>
       
    24 <li id="GUID-502C284C-3B56-5B6E-AEB5-F1E9DB513CA6"><p> <xref href="GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita#GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51/GUID-D2F661C6-21EB-50A6-A475-2A4A775A9F4D">Passing an integer</xref>  </p> </li>
       
    25 <li id="GUID-E5B29175-9647-5F88-961C-47CD20DF2238"><p> <xref href="GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita#GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51/GUID-02AD23DF-7D54-5178-AA5B-050333CD2609">Error handling issues</xref>  </p> </li>
       
    26 </ul>
       
    27 <section id="GUID-FCF8DC31-9D90-53C8-BE30-76D6CD0243BC"><title>Overview</title> <p>Handles
       
    28 and binary data, in the form of descriptors or integer values, can be passed
       
    29 to a process at process creation time, using what are called environment slots. </p> <p>Up
       
    30 to 16 separate pieces of information can be passed to a process on creation.
       
    31 For this purpose, a process has 16 environment slots that can contain the
       
    32 information passed to it by the launching process. </p> <p>Slot 0 is reserved
       
    33 and is never available for general purpose information passing. </p> <p>The
       
    34 parent (launching) process can only pass information to the child (created)
       
    35 process after the child process has been created. However, it should be done
       
    36 before the child process is resumed; it is an error to try and set environment
       
    37 data in a child process that has been resumed. </p> <p>A child process can
       
    38 only extract the information from its environment slots once. Extracting information
       
    39 from a slot causes that information to be deleted from the slot. </p> <p>It
       
    40 is a matter of convention between the parent and child process as to the meaning
       
    41 to be applied to a slot, and the type of data that it is to contain. </p> </section>
       
    42 <section id="GUID-D84521B5-4C3B-538C-946A-88EAA3713A8D"><title>The APIs</title> <p>To
       
    43 pass, a handle, a client server subsession, or binary data to a child process,
       
    44 the parent process calls <codeph>RProcess::SetParameter()</codeph>, where
       
    45 the <xref href="GUID-9DD1EA2B-DC59-315C-8E9C-CE6D9461B695.dita"><apiname>RProcess</apiname></xref> object represents the newly created child
       
    46 process. There are five overloaded variants of <codeph>SetParameter()</codeph> used
       
    47 for passing: </p> <table id="GUID-5BEA9FCB-68E8-56DD-BA60-71372984AA38">
       
    48 <tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
       
    49 <tbody>
       
    50 <row>
       
    51 <entry><p>handle: </p> </entry>
       
    52 <entry><codeblock id="GUID-EA9128DD-3694-5A2B-AB86-78BA81B43F5A" xml:space="preserve">TInt RProcess::SetParameter(TInt aSlot, RHandleBase aHandle);</codeblock> </entry>
       
    53 </row>
       
    54 <row>
       
    55 <entry><p>client server subsession: </p> </entry>
       
    56 <entry><codeblock id="GUID-D7FFAA04-44E4-5C4C-8B3B-4628AB965B58" xml:space="preserve">TInt RProcess::SetParameter(TInt aSlot, const RSubSessionBase&amp; aSession);</codeblock> </entry>
       
    57 </row>
       
    58 <row>
       
    59 <entry><p>8-bit descriptor: </p> </entry>
       
    60 <entry><codeblock id="GUID-32499AC5-3C9F-5927-A797-24A0367E22A7" xml:space="preserve">TInt RProcess::SetParameter(TInt aSlot, const TDesC8&amp; aDes);</codeblock> </entry>
       
    61 </row>
       
    62 <row>
       
    63 <entry><p>16-bit descriptor: </p> </entry>
       
    64 <entry><codeblock id="GUID-1997FC14-79C7-5DEC-9647-9FA14CB8EE84" xml:space="preserve">TInt RProcess::SetParameter(TInt aSlot, const TDesC16&amp; aDes);</codeblock> </entry>
       
    65 </row>
       
    66 <row>
       
    67 <entry><p>integer: </p> </entry>
       
    68 <entry><codeblock id="GUID-0F865FC0-C2D7-55A5-B90A-17F88958F6D9" xml:space="preserve">TInt RProcess::SetParameter(TInt aSlot, TInt aData);</codeblock> </entry>
       
    69 </row>
       
    70 </tbody>
       
    71 </tgroup>
       
    72 </table> <p>To extract, a handle, or a client server subsession, a child process
       
    73 can use the <codeph>Open()</codeph> function called on the relevant <xref href="GUID-727D2B62-09A9-3CBC-AB6F-591E52EC68EB.dita"><apiname>RHandleBase</apiname></xref> derived
       
    74 type: </p> <codeblock id="GUID-244AB92B-34FD-5B45-B0AA-1679D3DD9761" xml:space="preserve">TInt RSemaphore ::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess);
       
    75 TInt RBusLogicalChannel::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess);
       
    76 TInt RMsgQueueBase::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess);
       
    77 TInt RMutex::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess);
       
    78 TInt RChunk::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess);
       
    79 TInt RSessionBase::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess);
       
    80     </codeblock> <p>To extract descriptor data, or integer data, a child process
       
    81 can use the <xref href="GUID-C197C9A7-EA05-3F24-9854-542E984C612D.dita"><apiname>User</apiname></xref> class functions: </p> <codeblock id="GUID-CC129A19-0FF6-58C6-B11C-564D816BF845" xml:space="preserve">static TInt User::ParameterLength(TInt aSlot);
       
    82 static TInt User::GetTIntParameter(TInt aSlot, TInt&amp; aData);
       
    83 static TInt User::GetDesParameter(TInt aSlot, TDes8&amp; aDes);
       
    84 static TInt User::GetDesParameter(TInt aSlot, TDes16&amp; aDes);
       
    85     </codeblock> <fig id="GUID-D9CD78E1-6813-5F68-9883-F1F6DC04C92A">
       
    86 <title>Environment slots</title>
       
    87 <image href="GUID-ABE7BC1A-C51B-5ADD-8568-87A81423B648_d0e77808_href.png" placement="inline"/>
       
    88 </fig> </section>
       
    89 <section id="GUID-7F6B118C-0911-5979-8420-475985DB884B"><title> Passing a
       
    90 file handle and a subsession</title> <p>File server session handles and file
       
    91 handles can both be passed to a child process. </p> <p>The child process adopts
       
    92 the file handle, and must not be closed by the parent. To use a file handle,
       
    93 the session handle must also be passed. </p> <p>For <i>security reasons</i>,
       
    94 when sharing a file handle, the parent process should create a separate file
       
    95 server session for the specific purpose of sharing the file handle. If the
       
    96 parent process has other files open with this file server session, the child
       
    97 process can gain access to those files by iterating through all the possible
       
    98 values for the file handle and attempting to <codeph>Adopt()</codeph> each
       
    99 one. For the same reason, the child process should only use this session for
       
   100 sharing the file; it should not access other files through this session. </p> <p>The
       
   101 following two code fragments show code in the parent process and corresponding
       
   102 code in the child process. </p> <codeblock id="GUID-202421E4-5ADA-50A8-AE75-32F1071C64B0" xml:space="preserve">//Code in the parent (launching) process
       
   103 
       
   104     RProcess p;
       
   105     p.Create(KProcName, KNullDesC);    //create “child” process
       
   106     
       
   107     RFile file;
       
   108     RFs session;
       
   109     session.Connect();                //connect to file server
       
   110     session.ShareProtected();
       
   111     file.Create(iSession, KFileName, EFileStreamText|EFileWrite|EFileShareAny);
       
   112     file.Write(0, KTestData);
       
   113     
       
   114     p.SetParameter(5, session);        //session handle passed in slot 5
       
   115     p.SetParameter(6, file);        //file handle passed in slot 6
       
   116     Session.Close();
       
   117     p.Resume();
       
   118   </codeblock> <p> <codeph>KProcName</codeph> is the full path name of the
       
   119 executable associated with the child process, and <codeph>KFilename</codeph> is
       
   120 the file name. </p> <codeblock id="GUID-AE2354AA-D95A-5291-BFC4-1EDF470D65AE" xml:space="preserve">//Code in the child (launched) process
       
   121 
       
   122     RFs session;
       
   123     session.Open(5);            //obtain session handle from slot 5
       
   124     
       
   125     RFile file;
       
   126     TInt handle;
       
   127     ret = User::GetTIntParameter(8, handle);//get file handle from slot 8
       
   128     file.Adopt(session, handle);            //adopt the handle
       
   129     TBuf8&lt;100&gt; rbuf;                         //use the file
       
   130     ret = file.Read(0, rbuf);
       
   131     file.Close();
       
   132     session.Close();
       
   133   </codeblock> </section>
       
   134 <section id="GUID-19964DED-E6AD-59B4-BEDB-2A40864FBD29"><title> Passing a
       
   135 general handle, derived from RHandleBase</title> <p>General handles derived
       
   136 from <xref href="GUID-727D2B62-09A9-3CBC-AB6F-591E52EC68EB.dita"><apiname>RHandleBase</apiname></xref> can be passed to a child process. </p> <p>The
       
   137 handle is duplicated when it is stored in the child process’s environment.
       
   138 The parent can close the handle immediately after calling <codeph>SetParameter()</codeph>,
       
   139 or continue to use the handle and close it later. </p> <p>The following two
       
   140 code fragments show code in the parent process and corresponding code in the
       
   141 child process. </p> <codeblock id="GUID-591C111A-05B8-5247-84C1-411650AA1FB0" xml:space="preserve">//Code in the parent (launching) process,
       
   142 //passing handles to a mutex and a semaphore.
       
   143 
       
   144     RMutex mutex;
       
   145     RSemaphore sem; 
       
   146     
       
   147     RProcess p;
       
   148     p.Create(KProcName, KNullDesC);
       
   149     mutex.CreateGlobal(KMutexName);    //create the mutex
       
   150     sem.CreateGlobal(KSemName,0);    //create the semaphore
       
   151     p.SetParameter(3, mutex);    //put mutex handle into child process env' slot 3
       
   152     p.SetParameter(4, sem);        //put semaphore handle into child process env' slot 4
       
   153     mutex.Close();
       
   154     Sem.Close();
       
   155     p.Resume();            //resume the child process
       
   156     </codeblock> <codeblock id="GUID-78E31AB6-4900-5AE8-9755-8ACDD8265235" xml:space="preserve">//Code in the child (launched) process retrieving the handles.
       
   157     
       
   158     RMutex mutex;
       
   159     mutex.Open(3, EOwnerThread);    //get mutex handle
       
   160     RSemaphore sem;
       
   161     sem.Open(4, EOwnerThread);        //get semaphore handle
       
   162     
       
   163     //use the semaphore and mutex
       
   164     mutex.Close();
       
   165     sem.Close();
       
   166     </codeblock> </section>
       
   167 <section id="GUID-AAB81C64-A515-50E5-BF80-1D625AF1251C"><title> Passing descriptor
       
   168 data</title> <p>Both 8-bit and 16-bit descriptor data can be passed from a
       
   169 parent to a child process. </p> <p>Internally, an <xref href="GUID-5BEA9976-B969-3949-B855-E657FFF38EE2.dita"><apiname>HBuf</apiname></xref> descriptor
       
   170 is created containing the passed descriptor data, and a pointer to this descriptor
       
   171 is passed in the relevant slot. </p> <p>The child process retrieves the descriptor
       
   172 data by calling <xref href="GUID-C197C9A7-EA05-3F24-9854-542E984C612D.dita#GUID-C197C9A7-EA05-3F24-9854-542E984C612D/GUID-54C7406E-C498-3BE7-BB2C-1C5BA902A4D7"><apiname>User::GetDesParameter()</apiname></xref>. It can get the
       
   173 length of the data by calling <xref href="GUID-C197C9A7-EA05-3F24-9854-542E984C612D.dita#GUID-C197C9A7-EA05-3F24-9854-542E984C612D/GUID-ABD3F4AE-C226-3AF1-AD25-7A45B186385C"><apiname>User::ParameterLength()</apiname></xref>. </p> <p>The
       
   174 following two code fragments show code in the parent process and corresponding
       
   175 code in the child process. </p> <codeblock id="GUID-57FFCAC9-CA4E-50B7-843A-0523243F5B1E" xml:space="preserve">//Code in the parent (launching) process, passing 8 and sixteen bit data
       
   176 
       
   177     RProcess p;
       
   178     p.Create(KProcName, KNullDesC);
       
   179     p.SetParameter(2, KSixteenBitDes);
       
   180     p.SetParameter(3, KEightBitDes);
       
   181     p.Resume();
       
   182     </codeblock> <p>where <codeph>KSixteenBitDes</codeph> is a 16-descriptor,
       
   183 and <codeph>KEightBitDes</codeph> is an 8-bit descriptor. </p> <codeblock id="GUID-8B442CA2-0A6A-546C-805B-99C306891B40" xml:space="preserve">//Code in the child (launched) process retrieving 8 and sixteen bit data
       
   184     
       
   185     TInt len;
       
   186     TInt ret;
       
   187 
       
   188     TBuf16&lt;40&gt; buf;
       
   189     len = User::ParameterLength(2);        //parameter length is the size in bytes
       
   190     ret = User::GetDesParameter(2, buf);
       
   191     
       
   192     //buf.Length() should have the value of len/2;
       
   193 
       
   194 
       
   195     TBuf8&lt;40&gt; buf8;
       
   196     len = User::ParameterLength(3);
       
   197     ret = User::GetDesParameter(3, buf8);
       
   198     //buf.Length() should be the same as len
       
   199     </codeblock> <p>Note that the descriptors, <codeph>buf</codeph>, and <codeph>buf8</codeph> used
       
   200 in the child process must have sufficiently large maximum lengths to accomodate
       
   201 the data. </p> </section>
       
   202 <section id="GUID-D2F661C6-21EB-50A6-A475-2A4A775A9F4D"><title>Passing an
       
   203 integer</title> <p>An integer can be passed from a parent to a child process. </p> <p>The
       
   204 following two code fragments show code in the parent process and corresponding
       
   205 code in the child process. </p> <codeblock id="GUID-AA845210-E551-50B3-9E1F-CD6F8C37D13B" xml:space="preserve">//Code in the parent (launching) process
       
   206 
       
   207     RProcess p;
       
   208     TInt ret;
       
   209  
       
   210     ret = p.Create(KProcName, KNullDesC);
       
   211     p.SetParameter(12, 1234);  // Using slot 12
       
   212     p.Resume();
       
   213     </codeblock> <codeblock id="GUID-D5E4CFA8-15DA-543F-9616-7F075FBBCDC1" xml:space="preserve">//Code in the child (launched) process, retrieving the integer.
       
   214 
       
   215     TInt val;
       
   216     TInt ret;
       
   217 
       
   218     ret = User::GetTIntParameter(12, val);
       
   219 
       
   220     </codeblock> </section>
       
   221 <section id="GUID-02AD23DF-7D54-5178-AA5B-050333CD2609"><title>Error handling
       
   222 issues</title> <p>The parent process is panicked when calling <codeph>SetParameter()</codeph> with
       
   223 a handle if: </p> <ul>
       
   224 <li id="GUID-1BDFA3C0-0E69-5B0C-A27F-D2DEFC0B2C0F"><p>the parent process is
       
   225 not the creator of the child process </p> </li>
       
   226 <li id="GUID-1DF3C097-73AC-54B8-9654-435C6F163E95"><p>the slot number is out
       
   227 of range, i.e. is not in the range 0 to 15 </p> </li>
       
   228 <li id="GUID-B02324A1-D241-5103-A2EC-297474EF65E1"><p>the slot is in use </p> </li>
       
   229 <li id="GUID-6014D837-107F-536C-8947-74C5967D2264"><p>the handle is local. </p> </li>
       
   230 </ul> <p>The parent process is panicked when calling <codeph>SetParameter()</codeph> with
       
   231 a descriptor or integer if: </p> <ul>
       
   232 <li id="GUID-2FAF76CC-2569-5E2E-ADBA-AFA124F11C84"><p>the parent process is
       
   233 not the creator of the child process </p> </li>
       
   234 <li id="GUID-C23722B2-4EEB-5050-B82E-F58F450F088F"><p>the slot number is out
       
   235 of range, i.e. is not in the range 0 to 15 </p> </li>
       
   236 <li id="GUID-9ADA7D18-B084-509C-8F4A-66E885F61D0A"><p>the slot is in use </p> </li>
       
   237 <li id="GUID-32B64BAC-F13E-5029-93ED-642994E35886"><p>the length of the data
       
   238 is negative. </p> </li>
       
   239 </ul> <p>The child process is panicked if the slot number is out of range. </p> <p>The
       
   240 API functions that extract data from the process environment return <xref href="GUID-0BEA3647-7888-3612-A2D3-7E27AC405E29.dita"><apiname>KErrArgument</apiname></xref> if
       
   241 a slot contains the incorrect data type, or the length is incorrect. They
       
   242 return <xref href="GUID-5E653C17-372C-32E1-A1B2-9E69A9991C40.dita"><apiname>KErrNotFound</apiname></xref> if a slot is empty. </p> </section>
       
   243 </conbody></concept>