|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "SYSIF.H" |
|
17 #include <estlib.h> |
|
18 #include "FDESC.H" |
|
19 #include "PIPEDESC.H" |
|
20 #include <stdlib.h> |
|
21 |
|
22 /** |
|
23 @internalComponent |
|
24 */ |
|
25 const TInt KCPosixMajorVersionNumber=2; |
|
26 const TInt KCPosixMinorVersionNumber=0; |
|
27 /** |
|
28 @internalComponent |
|
29 */ |
|
30 enum TPosixServerPanic |
|
31 { |
|
32 EPosix_BadWaitCompletion=1, |
|
33 EPosix_NoPendingIO=2, |
|
34 }; |
|
35 /** |
|
36 @internalComponent |
|
37 */ |
|
38 enum PosixMessage { |
|
39 // asynchronous operations which need SetActive/RunL |
|
40 PMread, PMwrite, PMfsync, |
|
41 PMsendto, PMrecvfrom, PMconnect, PMshutdown, PMaccept, |
|
42 //NOTIFY PROBLEM |
|
43 // PMioctl, |
|
44 PMioctl, PMioctlN, |
|
45 // asynchronous operations which just delay completion |
|
46 PMwaitpid, |
|
47 // synchronous operations |
|
48 PMdup, PMdup2, |
|
49 PMopen, PMclose, PMlseek, PMfstat, |
|
50 PMgetcwd, |
|
51 PMchdir, PMmkdir, PMrmdir, |
|
52 PMchmod, PMunlink, PMstat, PMrename, |
|
53 PMResolvePath, |
|
54 PMsocket, PMbind, PMlisten, PMsockname, PMgetsockopt, PMsetsockopt, |
|
55 PMioctlcomplete, PMcancel, |
|
56 PMTerminateProcess, |
|
57 PMgetenv, PMsetenv, PMunsetenv, |
|
58 PMpopen3, |
|
59 // inter-process operations |
|
60 PMAreYouMyMother, PMHelloMum, PMPipeWrite, PMPipeRead, PMPipeIoctl, PMPipeClose, PMPipeCancel |
|
61 }; |
|
62 /** |
|
63 @internalComponent |
|
64 */ |
|
65 struct PosixParams |
|
66 { |
|
67 int ret; |
|
68 int fid; |
|
69 int pint[3]; |
|
70 const char* cptr[2]; |
|
71 char* ptr[2]; |
|
72 const wchar_t* cwptr[2]; |
|
73 wchar_t* wptr[2]; |
|
74 wchar_t** eptr[1]; |
|
75 unsigned long len[1]; |
|
76 unsigned long* lenp[1]; |
|
77 TUSockAddr addr; |
|
78 }; |
|
79 |
|
80 /** |
|
81 Package which holds client's process Id. |
|
82 @internalComponent |
|
83 */ |
|
84 typedef TPckgBuf<TInt> TPosixIPCPid; |
|
85 |
|
86 /** |
|
87 Package used by server to pass data to client. |
|
88 @internalComponent |
|
89 */ |
|
90 struct PosixIPCReply |
|
91 { |
|
92 TUint iVarCount; |
|
93 TUint iEnvironmentSize; |
|
94 TUint iWorkingDirectorySize; |
|
95 TUint iPipeMask; |
|
96 }; |
|
97 /** |
|
98 @internalComponent |
|
99 */ |
|
100 typedef TPckgBuf<PosixIPCReply> TPosixIPCReply; |
|
101 |
|
102 |
|
103 // |
|
104 class RPosixSession : public RSessionBase |
|
105 /** |
|
106 @internalComponent |
|
107 */ |
|
108 { |
|
109 public: |
|
110 TInt Connect(); |
|
111 TInt Connect(TDesC& aServerName); |
|
112 |
|
113 // for specific posix functions |
|
114 int Request(TInt aFunction, int& anErrno, PosixParams& params) const; |
|
115 void Request(TInt aFunction, int& anErrno, PosixParams& params, TRequestStatus& aStatus) const; |
|
116 // for generic messages |
|
117 TInt Request(TInt aFunction, const TIpcArgs& aArg) const; |
|
118 void Request(TInt aFunction, const TIpcArgs& aArg, TRequestStatus &aStatus) const; |
|
119 |
|
120 static TVersion Version(); |
|
121 }; |
|
122 |
|
123 |
|
124 // |
|
125 class CPosixRequest; |
|
126 class CPosixServer; |
|
127 class CPosixIPCSession; |
|
128 NONSHARABLE_CLASS(CPosixProcess) : public CActive |
|
129 /** |
|
130 @internalComponent |
|
131 */ |
|
132 { |
|
133 public: |
|
134 CPosixProcess(CPosixServer& aServer); |
|
135 ~CPosixProcess(); |
|
136 void POpen3L(PosixParams* aParams); |
|
137 static CPosixProcess* Find(CPosixProcess* head, TInt pid); |
|
138 static void Release(CPosixProcess** aHead, CPosixProcess* aProc); |
|
139 void Sizes(TPosixIPCReply& aReply) const; |
|
140 void CopyToChildL(const RMessage2& aMessage); |
|
141 inline TInt IsAlive() const {return IsActive();} |
|
142 inline void Queue(CPosixRequest* aWaiter); |
|
143 protected: |
|
144 void RunL(); |
|
145 void DoCancel(); |
|
146 |
|
147 private: |
|
148 inline CEnvironment& Env() const; |
|
149 inline CFileTable& Fids() const; |
|
150 inline RFs& Fs() const; |
|
151 inline RCommServ& Cs() const; |
|
152 |
|
153 public: |
|
154 CPosixProcess* iNextProcess; |
|
155 TInt iPid; |
|
156 TInt iExitReason; |
|
157 private: |
|
158 CPosixServer& iServer; |
|
159 |
|
160 RProcess iChild; |
|
161 CPosixRequest* iWaiters; |
|
162 |
|
163 TUint iVarCount; |
|
164 HBufC16* iEnvironment; |
|
165 HBufC* iWorkingDirectory; |
|
166 CPipeDesc* iPipes[3]; |
|
167 }; |
|
168 // |
|
169 class CPosixRequest; |
|
170 |
|
171 /** |
|
172 @internalComponent |
|
173 */ |
|
174 NONSHARABLE_CLASS(CPosixServer) : public CServer2 |
|
175 { |
|
176 public: |
|
177 static TInt ThreadFunction(TAny* aPtr); |
|
178 static void InitL(TInt aPriority); |
|
179 RFs& Fs() { return iFs; } |
|
180 RCommServ& Cs() { return iCs; } |
|
181 CFileTable& Fids() { return iFids; } |
|
182 RSocketServ& Ss() { return iSs; } |
|
183 CEnvironment& Env() { return iEnv; } |
|
184 |
|
185 int POpen3(PosixParams* aParams, int& anErrno); |
|
186 CPosixProcess* Child(TInt pid) { return CPosixProcess::Find(iChildren, pid); } |
|
187 void Release(CPosixProcess* aChild) { CPosixProcess::Release(&iChildren, aChild); } |
|
188 inline void WaitForAnyChild(CPosixRequest* aWaiter); |
|
189 CPosixRequest* Waiters(); |
|
190 static void ServerPanic(TPosixServerPanic aPanic); |
|
191 |
|
192 protected: |
|
193 CPosixServer(TInt aPriority); |
|
194 CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const; |
|
195 void FindParentL(); |
|
196 void DefaultConsoleL(); |
|
197 private: |
|
198 RFs iFs; |
|
199 CFileTable iFids; |
|
200 RSocketServ iSs; |
|
201 RCommServ iCs; |
|
202 |
|
203 CEnvironment iEnv; |
|
204 RPosixSession iParent; |
|
205 CPosixProcess* iChildren; |
|
206 CPosixRequest* iWaitAnyQueue; |
|
207 }; |
|
208 |
|
209 // |
|
210 class CPosixSession; |
|
211 NONSHARABLE_CLASS(CPosixRequest) : public CActive |
|
212 /** |
|
213 @internalComponent |
|
214 */ |
|
215 { |
|
216 public: |
|
217 CPosixRequest(CPosixServer& aServer); |
|
218 ~CPosixRequest(); |
|
219 void Service(const RMessage2& aMessage); |
|
220 void EnList(CPosixRequest*& aHead); // simple single linked list |
|
221 void WaitCompleted(TInt aPid, TInt aReason); |
|
222 protected: |
|
223 void RunL(); |
|
224 void DoCancel(); |
|
225 private: |
|
226 RFs& Fs() const { return iServer.Fs(); } |
|
227 RCommServ& Cs() const { return iServer.Cs(); } |
|
228 CFileTable& Fids() const { return iServer.Fids(); } |
|
229 RSocketServ& Ss() const { return iServer.Ss(); } |
|
230 CEnvironment& Env() const { return iServer.Env(); } |
|
231 private: |
|
232 void QueueAsynch(const RMessage2& aMessage); |
|
233 void StartAsynch(); |
|
234 void EndAsynch(TInt aResult); |
|
235 |
|
236 CPosixServer& iServer; |
|
237 |
|
238 RMessage2 iMessage; |
|
239 |
|
240 CFileDescBase* iFile; |
|
241 CSocketDesc* iNewF; |
|
242 int iNewFid; |
|
243 TPtr8 iPtr; |
|
244 |
|
245 CPosixRequest* iNext; // for Enlist |
|
246 TSglQueLink iLink; |
|
247 enum CFileDescBase::IOQueues iQueue; |
|
248 |
|
249 friend class TPosixRequestQueue; |
|
250 friend class CFileDescBase; // friend functions AddLast & Remove perhaps? |
|
251 }; |
|
252 // |
|
253 inline CEnvironment& CPosixProcess::Env() const { return iServer.Env(); } |
|
254 inline CFileTable& CPosixProcess::Fids() const { return iServer.Fids(); } |
|
255 inline RFs& CPosixProcess::Fs() const { return iServer.Fs(); } |
|
256 inline RCommServ& CPosixProcess::Cs() const { return iServer.Cs(); } |
|
257 inline void CPosixProcess::Queue(CPosixRequest* aWaiter) { aWaiter->EnList(iWaiters); } |
|
258 inline void CPosixServer::WaitForAnyChild(CPosixRequest* aWaiter) { aWaiter->EnList(iWaitAnyQueue); } |
|
259 |
|
260 // |
|
261 /** |
|
262 @internalComponent |
|
263 */ |
|
264 NONSHARABLE_CLASS(CPosixSession) : public CSession2 |
|
265 { |
|
266 public: |
|
267 CPosixSession(CPosixServer& aServer); |
|
268 virtual void ServiceL(const RMessage2& aMessage); |
|
269 protected: |
|
270 CPosixRequest iActive; |
|
271 }; |
|
272 |
|
273 NONSHARABLE_CLASS(CPosixIPCSession) : public CPosixSession |
|
274 /** |
|
275 @internalComponent |
|
276 */ |
|
277 { |
|
278 public: |
|
279 inline CPosixIPCSession(CPosixServer& aServer) |
|
280 : CPosixSession(aServer) {} |
|
281 virtual void ServiceL(const RMessage2& aMessage); // override the local ServiceL |
|
282 void SetPipes(CPipeDesc* aPipes[3]); |
|
283 ~CPosixIPCSession(); |
|
284 |
|
285 private: |
|
286 TInt AreYouMyMotherL(const RMessage2& aMessage); |
|
287 TInt HelloMumL(const RMessage2& aMessage); |
|
288 void PipeRead(const RMessage2& aMessage); |
|
289 void PipeWrite(const RMessage2& aMessage); |
|
290 void PipeIoctl(const RMessage2& aMessage); |
|
291 void PipeClose(const RMessage2& aMessage); |
|
292 void PipeCancel(const RMessage2& aMessage); |
|
293 |
|
294 CPipeDesc* iPipes[3]; |
|
295 }; |
|
296 // |
|
297 NONSHARABLE_CLASS(CProcessSystemInterface) : public MSystemInterface, public CBase |
|
298 /** |
|
299 @internalComponent |
|
300 */ |
|
301 { |
|
302 public: |
|
303 CProcessSystemInterface(); |
|
304 ~CProcessSystemInterface(); |
|
305 |
|
306 TInt Connect(); |
|
307 virtual MSystemInterface& Clone(); |
|
308 virtual void Release(); |
|
309 virtual void TerminateProcess(int status); |
|
310 |
|
311 virtual int dup (int fid, int& anErrno); |
|
312 virtual int dup2 (int fid, int fid2, int& anErrno); |
|
313 virtual int open (const wchar_t* name, int mode, int perms, int& anErrno); |
|
314 virtual int read (int fid, char* buf, unsigned long len, int& anErrno); |
|
315 virtual int write (int fid, const char* buf, unsigned long len, int& anErrno); |
|
316 virtual int fsync (int fid, int& anErrno); |
|
317 virtual int close (int fid, int& anErrno); |
|
318 virtual int lseek (int fid, int offset, int whence, int& anErrno); |
|
319 virtual int fstat (int fid, struct stat *st, int& anErrno); |
|
320 virtual int ioctl (int fid, int cmd, void* param, int& anErrno); |
|
321 virtual int ioctl (int fid, int cmd, void* param, TRequestStatus& aStatus, int& anErrno); |
|
322 virtual int ioctl_complete (int fid, int cmd, void* param, TRequestStatus& aStatus, int& anErrno); |
|
323 virtual int ioctl_cancel (int fid, int& anErrno); |
|
324 |
|
325 virtual wchar_t * getcwd (wchar_t * buf, unsigned long len, int& anErrno); |
|
326 |
|
327 virtual int chdir (const wchar_t* path, int& anErrno); |
|
328 virtual int mkdir (const wchar_t* path, int perms, int& anErrno); |
|
329 virtual int rmdir (const wchar_t* path, int& anErrno); |
|
330 virtual int chmod (const wchar_t* path, int perms, int& anErrno); |
|
331 virtual int unlink (const wchar_t* path, int& anErrno); |
|
332 virtual int stat (const wchar_t* name, struct stat *st, int& anErrno); |
|
333 virtual int rename (const wchar_t* oldname, const wchar_t* newname, int& anErrno); |
|
334 |
|
335 virtual TInt ResolvePath (TParse& aResult, const wchar_t* path, TDes* aFilename); |
|
336 |
|
337 virtual int socket (int family, int style, int protocol, int& anErrno); |
|
338 virtual int recvfrom (int fd, char* buf, unsigned long cnt, int flags, struct sockaddr* from, unsigned long* fromsize, int& anErrno); |
|
339 virtual int sendto (int fd, const char* buf, unsigned long cnt, int flags, struct sockaddr* to, unsigned long tosize, int& anErrno); |
|
340 virtual int shutdown (int fd, int how, int& anErrno); |
|
341 virtual int listen (int fd, int n, int& anErrno); |
|
342 virtual int accept (int fd, int& anErrno); |
|
343 virtual int bind (int fd, struct sockaddr* addr, unsigned long size, int& anErrno); |
|
344 virtual int connect (int fd, struct sockaddr* addr, unsigned long size, int& anErrno); |
|
345 virtual int sockname (int fd, struct sockaddr* addr, unsigned long* size, int anEnd, int& anErrno); |
|
346 virtual int getsockopt (int fd, int level, int opt, void* buf, unsigned long* len, int& anErrno); |
|
347 virtual int setsockopt (int fd, int level, int opt, void* buf, unsigned long len, int& anErrno); |
|
348 |
|
349 virtual wchar_t* getenv (const wchar_t* name); |
|
350 virtual void unsetenv (const wchar_t* name); |
|
351 virtual int setenv (const wchar_t* name, const wchar_t* value, int rewrite, int& anErrno); |
|
352 |
|
353 virtual int popen3 (const wchar_t *file, const wchar_t *cmd, const wchar_t *mode, wchar_t** envp, int fids[3], int& anErrno); |
|
354 virtual int waitpid (int pid, int* status, int options, int& anErrno); |
|
355 |
|
356 private: |
|
357 int Request(TInt aFunction, int& anErrno); |
|
358 void Request(TInt aFunction, int& anErrno, TRequestStatus& aStatus); |
|
359 RPosixSession iSession; |
|
360 PosixParams iParams; |
|
361 }; |