|
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& 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& 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& 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& aData); |
|
83 static TInt User::GetDesParameter(TInt aSlot, TDes8& aDes); |
|
84 static TInt User::GetDesParameter(TInt aSlot, TDes16& 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<100> 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<40> 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<40> 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> |