|
1 // commands.cpp |
|
2 // |
|
3 // Copyright (c) 2006 - 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "Eclipse Public License v1.0" |
|
6 // which accompanies this distribution, and is available |
|
7 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 // |
|
9 // Initial Contributors: |
|
10 // Accenture - Initial contribution |
|
11 // |
|
12 |
|
13 #include <e32debug.h> |
|
14 #include <e32rom.h> |
|
15 #include <f32dbg.h> |
|
16 #include <f32image.h> |
|
17 #include <hal.h> |
|
18 #include <fshell/common.mmh> |
|
19 #include <fshell/ltkutils.h> |
|
20 #include <fshell/descriptorutils.h> |
|
21 #include <fshell/heaputils.h> |
|
22 using LtkUtils::RAllocatorHelper; |
|
23 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
24 #include <fshell/memoryaccess.h> |
|
25 #endif |
|
26 #include "fshell.h" |
|
27 #include "commands.h" |
|
28 #include "command_factory.h" |
|
29 #include "string_utils.h" |
|
30 |
|
31 |
|
32 // |
|
33 // Constants. |
|
34 // |
|
35 |
|
36 _LIT(KOptVerbose, "verbose"); |
|
37 _LIT(KOptHuman, "human"); |
|
38 |
|
39 _LIT(KNewLine, "\r\n"); |
|
40 _LIT(KTab, "\t"); |
|
41 _LIT(KRepeatCount, "REPEAT_COUNT"); |
|
42 const TInt KBlockSize = 512; |
|
43 |
|
44 _LIT(KMatchAll, "*"); |
|
45 |
|
46 |
|
47 // |
|
48 // CCmdHelp. |
|
49 // |
|
50 |
|
51 CCommandBase* CCmdHelp::NewLC() |
|
52 { |
|
53 CCmdHelp* self = new(ELeave) CCmdHelp(); |
|
54 CleanupStack::PushL(self); |
|
55 self->BaseConstructL(); |
|
56 return self; |
|
57 } |
|
58 |
|
59 CCmdHelp::~CCmdHelp() |
|
60 { |
|
61 delete iFormatter; |
|
62 } |
|
63 |
|
64 CCmdHelp::CCmdHelp() : CCommandBase(ECompleteOnRunL) |
|
65 { |
|
66 } |
|
67 |
|
68 const TDesC& CCmdHelp::Name() const |
|
69 { |
|
70 _LIT(KCmdHelpName, "help"); |
|
71 return KCmdHelpName; |
|
72 } |
|
73 |
|
74 void CCmdHelp::DoRunL() |
|
75 { |
|
76 if (iOptions.IsPresent(&iCount)) |
|
77 { |
|
78 const TInt count = gShell->CommandFactory().CountUniqueCommandsL(); |
|
79 Complete(_L("%d\r\n"), count); |
|
80 } |
|
81 else |
|
82 { |
|
83 RArray<TPtrC> commands; |
|
84 CleanupClosePushL(commands); |
|
85 gShell->CommandFactory().ListCommandsL(commands); |
|
86 iFormatter = CTextFormatter::NewL(Stdout()); |
|
87 iFormatter->ColumnizeL(0, 2, commands.Array()); |
|
88 CleanupStack::PopAndDestroy(&commands); |
|
89 Stdout().Write(iFormatter->Descriptor(), iStatus); |
|
90 SetActive(); |
|
91 } |
|
92 } |
|
93 |
|
94 void CCmdHelp::OptionsL(RCommandOptionList& aOptions) |
|
95 { |
|
96 _LIT(KOptCount, "count"); |
|
97 aOptions.AppendBoolL(iCount, KOptCount); |
|
98 } |
|
99 |
|
100 |
|
101 // |
|
102 // CCmdExit. |
|
103 // |
|
104 |
|
105 CCommandBase* CCmdExit::NewLC() |
|
106 { |
|
107 CCmdExit* self = new(ELeave) CCmdExit(); |
|
108 CleanupStack::PushL(self); |
|
109 self->BaseConstructL(); |
|
110 return self; |
|
111 } |
|
112 |
|
113 CCmdExit::~CCmdExit() |
|
114 { |
|
115 } |
|
116 |
|
117 CCmdExit::CCmdExit() |
|
118 { |
|
119 } |
|
120 |
|
121 const TDesC& CCmdExit::Name() const |
|
122 { |
|
123 _LIT(KCmdExitName, "exit"); |
|
124 return KCmdExitName; |
|
125 } |
|
126 |
|
127 void CCmdExit::DoRunL() |
|
128 { |
|
129 // Note, this command should never execute as 'exit' has handled explicitly by CParser. |
|
130 // It exists so that 'exit' appears in fshell's help list and also to support 'exit --help'. |
|
131 LeaveIfErr(KErrGeneral, _L("Invalid context for 'exit' command (must be run as a bare command, not in a pipe-line)")); |
|
132 } |
|
133 |
|
134 |
|
135 // |
|
136 // CCmdLs. |
|
137 // |
|
138 |
|
139 CCommandBase* CCmdLs::NewLC() |
|
140 { |
|
141 CCmdLs* self = new(ELeave) CCmdLs(); |
|
142 CleanupStack::PushL(self); |
|
143 self->ConstructL(); |
|
144 return self; |
|
145 } |
|
146 |
|
147 CCmdLs::~CCmdLs() |
|
148 { |
|
149 delete iFormatter; |
|
150 } |
|
151 |
|
152 CCmdLs::CCmdLs() |
|
153 { |
|
154 } |
|
155 |
|
156 void CCmdLs::ConstructL() |
|
157 { |
|
158 BaseConstructL(); |
|
159 } |
|
160 |
|
161 void CCmdLs::PrintDirContentL(RDir& aDir) |
|
162 { |
|
163 TInt err = KErrNone; |
|
164 TEntry entry; |
|
165 while (err == KErrNone) |
|
166 { |
|
167 err = aDir.Read(entry); |
|
168 if (err == KErrNone) |
|
169 { |
|
170 FormatEntryL(entry); |
|
171 Write(iFormatter->Descriptor()); |
|
172 iFormatter->Zero(); |
|
173 |
|
174 if (iOptRecurse && entry.IsDir()) |
|
175 { |
|
176 RecursiveScanDirL(entry.iName); |
|
177 } |
|
178 } |
|
179 } |
|
180 if (err == KErrEof) |
|
181 { |
|
182 err = KErrNone; |
|
183 } |
|
184 User::LeaveIfError(err); |
|
185 } |
|
186 |
|
187 void CCmdLs::PrintDirContentL(const CDir& aDir) |
|
188 { |
|
189 IoUtils::CTextBuffer* buf = IoUtils::CTextBuffer::NewLC(0x100); |
|
190 |
|
191 const TInt numEntries = aDir.Count(); |
|
192 for (TInt i = 0; i < numEntries; ++i) |
|
193 { |
|
194 const TEntry& entry = aDir[i]; |
|
195 buf->AppendL(entry.iName); |
|
196 buf->AppendL(_L("\t")); |
|
197 } |
|
198 |
|
199 iFormatter->ColumnizeL(0, 2, buf->Descriptor()); |
|
200 Write(iFormatter->Descriptor()); |
|
201 CleanupStack::PopAndDestroy(buf); |
|
202 } |
|
203 |
|
204 void CCmdLs::FormatEntryL(const TEntry& aEntry) |
|
205 { |
|
206 if (iOptLong) |
|
207 { |
|
208 iFormatter->AppendFormatL(_L("%c%c%c%c%c "), aEntry.IsDir() ? 'd' : '-', aEntry.IsReadOnly() ? 'r' : '-', aEntry.IsHidden() ? 'h' : '-', aEntry.IsSystem() ? 's' : '-', aEntry.IsArchive() ? 'a' : '-'); |
|
209 if (iOptHuman) |
|
210 { |
|
211 iFormatter->AppendHumanReadableSizeL(aEntry.iSize); |
|
212 iFormatter->AppendL(_L(" ")); |
|
213 } |
|
214 else |
|
215 { |
|
216 iFormatter->AppendFormatL(_L("%+ 10d "), aEntry.iSize); |
|
217 } |
|
218 aEntry.iModified.FormatL(iTempBuf, _L("%1%/1%2%/2%3 %H%:1%T%:2%S ")); |
|
219 TPtrC pathRelativeToBaseDir = iFileName.Mid(iBaseDir.Length()); |
|
220 iFormatter->AppendFormatL(_L("%S%S%S\r\n"), &iTempBuf, &pathRelativeToBaseDir, &aEntry.iName); |
|
221 } |
|
222 else |
|
223 { |
|
224 TPtrC pathRelativeToBaseDir = iFileName.Mid(iBaseDir.Length()); |
|
225 iFormatter->AppendFormatL(_L("%S%S\r\n"), &pathRelativeToBaseDir, &aEntry.iName); |
|
226 } |
|
227 } |
|
228 |
|
229 const TDesC& CCmdLs::Name() const |
|
230 { |
|
231 _LIT(KCmdLsName, "ls"); |
|
232 return KCmdLsName; |
|
233 } |
|
234 |
|
235 void CCmdLs::DoRunL() |
|
236 { |
|
237 if (iFileName.Length() == 0) |
|
238 { |
|
239 iFileName = Env().Pwd(); |
|
240 } |
|
241 |
|
242 if (!iFileName.IsWild() && !iFileName.IsDriveRoot()) |
|
243 { |
|
244 LeaveIfFileNotFound(iFileName); |
|
245 if (iFileName.IsDirL(FsL())) |
|
246 { |
|
247 iFileName.SetIsDirectoryL(); |
|
248 } |
|
249 } |
|
250 |
|
251 if (iOptRecurse || iOptLong || !Stdout().AttachedToConsole()) |
|
252 { |
|
253 iOptOnePerLine = ETrue; |
|
254 } |
|
255 |
|
256 iFormatter = CTextFormatter::NewL(Stdout()); |
|
257 iBaseDir.Set(TParsePtrC(iFileName).DriveAndPath()); |
|
258 |
|
259 if (iOptOnePerLine) |
|
260 { |
|
261 DoScanDirL(); |
|
262 } |
|
263 else |
|
264 { |
|
265 CDir* files; |
|
266 LeaveIfErr(FsL().GetDir(iFileName, iOptAll ? KEntryAttMaskSupported : KEntryAttNormal | KEntryAttDir, ESortByName, files), _L("Couldn't read whole directory into memory - try using -1")); |
|
267 CleanupStack::PushL(files); |
|
268 PrintDirContentL(*files); |
|
269 CleanupStack::PopAndDestroy(files); |
|
270 } |
|
271 } |
|
272 |
|
273 void CCmdLs::OptionsL(RCommandOptionList& aOptions) |
|
274 { |
|
275 _LIT(KCmdLsOptAll, "all"); |
|
276 _LIT(KCmdLsOptLong, "long"); |
|
277 _LIT(KCmdLsOptHuman, "human"); |
|
278 _LIT(KCmdLsOptOnePerLine, "one"); |
|
279 _LIT(KCmdLsOpRecurse, "recurse"); |
|
280 |
|
281 aOptions.AppendBoolL(iOptAll, KCmdLsOptAll); |
|
282 aOptions.AppendBoolL(iOptLong, KCmdLsOptLong); |
|
283 aOptions.AppendBoolL(iOptHuman, KCmdLsOptHuman); |
|
284 aOptions.AppendBoolL(iOptOnePerLine, KCmdLsOptOnePerLine); |
|
285 aOptions.AppendBoolL(iOptRecurse, KCmdLsOpRecurse); |
|
286 } |
|
287 |
|
288 void CCmdLs::ArgumentsL(RCommandArgumentList& aArguments) |
|
289 { |
|
290 _LIT(KCmdLsArg, "dir_name"); |
|
291 aArguments.AppendFileNameL(iFileName, KCmdLsArg); |
|
292 } |
|
293 |
|
294 void CCmdLs::RecursiveScanDirL(const TDesC& aName) |
|
295 { |
|
296 TInt currentDirectoryLen = iFileName.Length(); |
|
297 iFileName.AppendComponentL(aName, TFileName2::EDirectory); |
|
298 DoScanDirL(); |
|
299 iFileName.SetLength(currentDirectoryLen); // Since this is called recursively, restore iTempName to what it was previously |
|
300 } |
|
301 |
|
302 void CCmdLs::DoScanDirL() |
|
303 { |
|
304 RDir dir; |
|
305 User::LeaveIfError(dir.Open(FsL(), iFileName, iOptAll ? KEntryAttMaskSupported : KEntryAttNormal | KEntryAttDir)); |
|
306 CleanupClosePushL(dir); |
|
307 iFileName.SetLength(TParsePtrC(iFileName).DriveAndPath().Length()); // Remove any possible wildcard or name from the end of iFileName before recursing |
|
308 PrintDirContentL(dir); |
|
309 CleanupStack::PopAndDestroy(&dir); |
|
310 } |
|
311 |
|
312 // |
|
313 // CCmdCd. |
|
314 // |
|
315 |
|
316 CCommandBase* CCmdCd::NewLC() |
|
317 { |
|
318 CCmdCd* self = new(ELeave) CCmdCd(); |
|
319 CleanupStack::PushL(self); |
|
320 self->BaseConstructL(); |
|
321 return self; |
|
322 } |
|
323 |
|
324 CCmdCd::~CCmdCd() |
|
325 { |
|
326 } |
|
327 |
|
328 CCmdCd::CCmdCd() |
|
329 : iDir(TFileName2::EDirectory) |
|
330 { |
|
331 } |
|
332 |
|
333 const TDesC& CCmdCd::Name() const |
|
334 { |
|
335 _LIT(KCmdCdName, "cd"); |
|
336 return KCmdCdName; |
|
337 } |
|
338 |
|
339 void CCmdCd::DoRunL() |
|
340 { |
|
341 if (iDir.IsDriveRoot()) // For some reason best known to the designers of F32, it's not possible to retrieve a TEntry object for the root of a drive (fails with KErrBadName). |
|
342 { |
|
343 TDriveList driveList; |
|
344 LeaveIfErr(FsL().DriveList(driveList), _L("Couldn't get drive list")); |
|
345 TInt driveNum = TChar(iDir[0]).GetUpperCase() - 'A'; |
|
346 if (driveNum >= KMaxDrives) |
|
347 { |
|
348 Complete(KErrArgument, _L("Invalid drive letter")); |
|
349 return; |
|
350 } |
|
351 if (!driveList[driveNum]) |
|
352 { |
|
353 Complete(KErrNotReady, _L("Drive not present")); |
|
354 return; |
|
355 } |
|
356 } |
|
357 else |
|
358 { |
|
359 LeaveIfFileNotFound(iDir); |
|
360 if (!iDir.IsDirL(FsL())) |
|
361 { |
|
362 Complete(KErrBadName, _L("%S is not a directory"), &iDir); |
|
363 return; |
|
364 } |
|
365 } |
|
366 |
|
367 Env().SetPwdL(iDir); |
|
368 } |
|
369 |
|
370 void CCmdCd::ArgumentsL(RCommandArgumentList& aArguments) |
|
371 { |
|
372 _LIT(KCmdCdArg, "directory"); |
|
373 aArguments.AppendFileNameL(iDir, KCmdCdArg); |
|
374 } |
|
375 |
|
376 |
|
377 // |
|
378 // CCmdClear. |
|
379 // |
|
380 |
|
381 CCommandBase* CCmdClear::NewLC() |
|
382 { |
|
383 CCmdClear* self = new(ELeave) CCmdClear(); |
|
384 CleanupStack::PushL(self); |
|
385 self->BaseConstructL(); |
|
386 return self; |
|
387 } |
|
388 |
|
389 CCmdClear::~CCmdClear() |
|
390 { |
|
391 } |
|
392 |
|
393 CCmdClear::CCmdClear() |
|
394 { |
|
395 } |
|
396 |
|
397 const TDesC& CCmdClear::Name() const |
|
398 { |
|
399 _LIT(KCmdClearName, "clear"); |
|
400 return KCmdClearName; |
|
401 } |
|
402 |
|
403 void CCmdClear::DoRunL() |
|
404 { |
|
405 if (iFormFeed) |
|
406 { |
|
407 TInt consoleHeight = Stdout().GetScreenSizeL().iHeight; |
|
408 Stdout().SetCursorPosAbsL(TPoint(0, consoleHeight-1)); |
|
409 RBuf buf; |
|
410 buf.CreateL(consoleHeight * 2); |
|
411 while (consoleHeight--) buf.Append(KNewLine); |
|
412 Stdout().Write(buf); |
|
413 buf.Close(); |
|
414 Stdout().SetCursorPosAbsL(TPoint(0,0)); |
|
415 } |
|
416 else |
|
417 { |
|
418 Stdout().ClearScreenL(); |
|
419 Stdin().SetMode(RIoReadWriteHandle::EText); |
|
420 Stdout().SetMode(RIoReadWriteHandle::EText); |
|
421 Stderr().SetMode(RIoReadWriteHandle::EText); |
|
422 } |
|
423 } |
|
424 |
|
425 void CCmdClear::OptionsL(RCommandOptionList& aOptions) |
|
426 { |
|
427 _LIT(KOptFormFeed, "formfeed"); |
|
428 aOptions.AppendBoolL(iFormFeed, KOptFormFeed); |
|
429 } |
|
430 |
|
431 // |
|
432 // CForegroundAdjuster |
|
433 // |
|
434 |
|
435 class CForegroundAdjuster : public CActive |
|
436 { |
|
437 public: |
|
438 static CForegroundAdjuster* NewL(CCommandBase& aCommand, TInt aJobId, TBool aToForeground); |
|
439 ~CForegroundAdjuster(); |
|
440 private: // From CActive. |
|
441 virtual void RunL(); |
|
442 virtual void DoCancel(); |
|
443 virtual TInt RunError(TInt aError); |
|
444 private: |
|
445 CForegroundAdjuster(CCommandBase& aCommand, TInt aJobId, TBool aToForeground); |
|
446 private: |
|
447 CCommandBase& iCommand; |
|
448 TInt iJobId; |
|
449 TBool iToForeground; |
|
450 }; |
|
451 |
|
452 CForegroundAdjuster* CForegroundAdjuster::NewL(CCommandBase& aCommand, TInt aJobId, TBool aToForeground) |
|
453 { |
|
454 return new(ELeave) CForegroundAdjuster(aCommand, aJobId, aToForeground); |
|
455 } |
|
456 |
|
457 void CForegroundAdjuster::RunL() |
|
458 { |
|
459 gShell->ClaimJobsLockLC(); |
|
460 |
|
461 if (iToForeground) |
|
462 { |
|
463 gShell->BringJobToForeground(iJobId); |
|
464 } |
|
465 else |
|
466 { |
|
467 gShell->SendJobToBackground(iJobId); |
|
468 } |
|
469 |
|
470 CleanupStack::PopAndDestroy(); // jobs lock. |
|
471 iCommand.Complete(); |
|
472 } |
|
473 |
|
474 void CForegroundAdjuster::DoCancel() |
|
475 { |
|
476 } |
|
477 |
|
478 TInt CForegroundAdjuster::RunError(TInt aError) |
|
479 { |
|
480 iCommand.Complete(aError); |
|
481 return KErrNone; |
|
482 } |
|
483 |
|
484 CForegroundAdjuster::CForegroundAdjuster(CCommandBase& aCommand, TInt aJobId, TBool aToForeground) |
|
485 : CActive(CActive::EPriorityStandard), iCommand(aCommand), iJobId(aJobId), iToForeground(aToForeground) |
|
486 { |
|
487 CActiveScheduler::Add(this); |
|
488 TRequestStatus* status = &iStatus; |
|
489 User::RequestComplete(status, KErrNone); |
|
490 SetActive(); |
|
491 } |
|
492 |
|
493 CForegroundAdjuster::~CForegroundAdjuster() |
|
494 { |
|
495 } |
|
496 |
|
497 |
|
498 // |
|
499 // CCmdFg. |
|
500 // |
|
501 |
|
502 void ParseJobSpecL(const TDesC& aString, TInt& aJobId) |
|
503 { |
|
504 TLex lex(aString); |
|
505 lex.SkipSpace(); |
|
506 if (lex.Peek() == '%') |
|
507 { |
|
508 lex.Get(); |
|
509 } |
|
510 User::LeaveIfError(lex.Val(aJobId)); |
|
511 } |
|
512 |
|
513 CCommandBase* CCmdFg::NewLC() |
|
514 { |
|
515 CCmdFg* self = new(ELeave) CCmdFg(); |
|
516 CleanupStack::PushL(self); |
|
517 self->BaseConstructL(); |
|
518 return self; |
|
519 } |
|
520 |
|
521 CCmdFg::~CCmdFg() |
|
522 { |
|
523 delete iJobSpec; |
|
524 delete iForegroundAdjuster; |
|
525 } |
|
526 |
|
527 CCmdFg::CCmdFg() : CCommandBase(EManualComplete) |
|
528 { |
|
529 } |
|
530 |
|
531 const TDesC& CCmdFg::Name() const |
|
532 { |
|
533 _LIT(KCmdFgName, "fg"); |
|
534 return KCmdFgName; |
|
535 } |
|
536 |
|
537 void CCmdFg::DoRunL() |
|
538 { |
|
539 TInt jobId = -1; |
|
540 if (iJobSpec) |
|
541 { |
|
542 ParseJobSpecL(*iJobSpec, jobId); |
|
543 } |
|
544 else |
|
545 { |
|
546 gShell->ClaimJobsLockLC(); |
|
547 const RPointerArray<CJob>& jobs = gShell->Jobs(); |
|
548 const TInt numJobs = jobs.Count(); |
|
549 if (numJobs >= 2) |
|
550 { |
|
551 jobId = jobs[numJobs - 2]->Id(); // Note, the most recent job (jobs[numJobs - 1]) will be this command. |
|
552 } |
|
553 CleanupStack::PopAndDestroy(); // jobs lock. |
|
554 } |
|
555 if (jobId >= 0) |
|
556 { |
|
557 iForegroundAdjuster = CForegroundAdjuster::NewL(*this, jobId, ETrue); |
|
558 } |
|
559 else |
|
560 { |
|
561 Complete(); |
|
562 } |
|
563 } |
|
564 |
|
565 void CCmdFg::ArgumentsL(RCommandArgumentList& aArguments) |
|
566 { |
|
567 _LIT(KCmdFgArg, "job_spec"); |
|
568 aArguments.AppendStringL(iJobSpec, KCmdFgArg); |
|
569 } |
|
570 |
|
571 |
|
572 // |
|
573 // CCmdBg. |
|
574 // |
|
575 |
|
576 CCommandBase* CCmdBg::NewLC() |
|
577 { |
|
578 CCmdBg* self = new(ELeave) CCmdBg(); |
|
579 CleanupStack::PushL(self); |
|
580 self->BaseConstructL(); |
|
581 return self; |
|
582 } |
|
583 |
|
584 CCmdBg::~CCmdBg() |
|
585 { |
|
586 delete iJobSpec; |
|
587 delete iForegroundAdjuster; |
|
588 } |
|
589 |
|
590 CCmdBg::CCmdBg() : CCommandBase(EManualComplete) |
|
591 { |
|
592 } |
|
593 |
|
594 const TDesC& CCmdBg::Name() const |
|
595 { |
|
596 _LIT(KCmdBgName, "bg"); |
|
597 return KCmdBgName; |
|
598 } |
|
599 |
|
600 void CCmdBg::DoRunL() |
|
601 { |
|
602 TInt jobId = -1; |
|
603 if (iJobSpec) |
|
604 { |
|
605 ParseJobSpecL(*iJobSpec, jobId); |
|
606 } |
|
607 else |
|
608 { |
|
609 gShell->ClaimJobsLockLC(); |
|
610 const RPointerArray<CJob>& jobs = gShell->Jobs(); |
|
611 const TInt numJobs = jobs.Count(); |
|
612 if (numJobs >= 2) |
|
613 { |
|
614 jobId = jobs[numJobs - 2]->Id(); // Note, the most recent job (jobs[numJobs - 1]) will be this command. |
|
615 } |
|
616 CleanupStack::PopAndDestroy(); // jobs lock. |
|
617 } |
|
618 if (jobId >= 0) |
|
619 { |
|
620 iForegroundAdjuster = CForegroundAdjuster::NewL(*this, jobId, EFalse); |
|
621 } |
|
622 } |
|
623 |
|
624 void CCmdBg::ArgumentsL(RCommandArgumentList& aArguments) |
|
625 { |
|
626 _LIT(KCmdBgArg, "job_spec"); |
|
627 aArguments.AppendStringL(iJobSpec, KCmdBgArg); |
|
628 } |
|
629 |
|
630 |
|
631 // |
|
632 // CCmdJobs. |
|
633 // |
|
634 |
|
635 CCommandBase* CCmdJobs::NewLC() |
|
636 { |
|
637 CCmdJobs* self = new(ELeave) CCmdJobs(); |
|
638 CleanupStack::PushL(self); |
|
639 self->BaseConstructL(); |
|
640 return self; |
|
641 } |
|
642 |
|
643 CCmdJobs::~CCmdJobs() |
|
644 { |
|
645 delete iFormatter; |
|
646 } |
|
647 |
|
648 CCmdJobs::CCmdJobs() : CCommandBase(ECompleteOnRunL) |
|
649 { |
|
650 } |
|
651 |
|
652 const TDesC& CCmdJobs::Name() const |
|
653 { |
|
654 _LIT(KCmgJobsName, "jobs"); |
|
655 return KCmgJobsName; |
|
656 } |
|
657 |
|
658 void CCmdJobs::DoRunL() |
|
659 { |
|
660 iFormatter = CTextFormatter::NewL(Stdout()); |
|
661 gShell->ClaimJobsLockLC(); |
|
662 const RPointerArray<CJob>& jobs = gShell->Jobs(); |
|
663 const TInt numJobs = (jobs.Count() - 1); |
|
664 if (numJobs > 0) |
|
665 { |
|
666 IoUtils::CTextBuffer* buf = IoUtils::CTextBuffer::NewLC(0x100); |
|
667 for (TInt i = 0; i < numJobs; ++i) |
|
668 { |
|
669 const CJob& job = *(jobs[i]); |
|
670 buf->AppendFormatL(_L("[%d]\t%S\t%S\r\n"), job.Id(), ShStringify::JobStatus(job.Status()), job.Name()); |
|
671 } |
|
672 iFormatter->TabulateL(0, 2, buf->Descriptor()); |
|
673 CleanupStack::PopAndDestroy(2); // buf, jobs lock. |
|
674 Stdout().Write(iFormatter->Descriptor(), iStatus); |
|
675 SetActive(); |
|
676 } |
|
677 else |
|
678 { |
|
679 CleanupStack::PopAndDestroy(); // jobs lock. |
|
680 Complete(); |
|
681 } |
|
682 } |
|
683 |
|
684 |
|
685 // |
|
686 // CCmdRm. |
|
687 // |
|
688 |
|
689 CCommandBase* CCmdRm::NewLC() |
|
690 { |
|
691 CCmdRm* self = new(ELeave) CCmdRm(); |
|
692 CleanupStack::PushL(self); |
|
693 self->BaseConstructL(); |
|
694 return self; |
|
695 } |
|
696 |
|
697 CCmdRm::~CCmdRm() |
|
698 { |
|
699 delete iFileMan; |
|
700 iFileNames.Close(); |
|
701 } |
|
702 |
|
703 CCmdRm::CCmdRm() |
|
704 { |
|
705 } |
|
706 |
|
707 const TDesC& CCmdRm::Name() const |
|
708 { |
|
709 _LIT(KCmdRmName, "rm"); |
|
710 return KCmdRmName; |
|
711 } |
|
712 |
|
713 void CCmdRm::DoRunL() |
|
714 { |
|
715 iFileMan = CFileMan::NewL(FsL()); |
|
716 |
|
717 const TInt numFiles = iFileNames.Count(); |
|
718 for (TInt i = 0; i < numFiles; ++i) |
|
719 { |
|
720 TFileName2& fileName = iFileNames[i]; |
|
721 LeaveIfFileNotFound(fileName); |
|
722 if (iRecurse) |
|
723 { |
|
724 if (fileName.IsDirL(FsL())) |
|
725 { |
|
726 fileName.SetTypeL(TFileName2::EDirectory); |
|
727 } |
|
728 else |
|
729 { |
|
730 PrintError(KErrArgument, _L("Invalid use of \"-r\" option - \"%S\" is not a directory."), &fileName); |
|
731 User::Leave(KErrArgument); |
|
732 } |
|
733 } |
|
734 else if (fileName.IsDirL(FsL())) |
|
735 { |
|
736 PrintError(KErrArgument, _L("Couldn't remove \"%S\" because it is a directory - use \"rm -r\" or \"rmdir\" instead."), &fileName); |
|
737 User::Leave(KErrArgument); |
|
738 } |
|
739 |
|
740 TInt err = DoDelete(fileName); |
|
741 if (err == KErrAccessDenied && iForce) |
|
742 { |
|
743 // Try removing read-only attribute from file and try again |
|
744 err = Fs().SetAtt(fileName, 0, KEntryAttReadOnly); |
|
745 if (!err) |
|
746 { |
|
747 iForce = EFalse; // Otherwise we'll end up here again (could happen if iFileName is a directory and cannot be deleted because it contains read-only files |
|
748 err = DoDelete(fileName); |
|
749 } |
|
750 } |
|
751 User::LeaveIfError(err); |
|
752 } |
|
753 } |
|
754 |
|
755 TInt CCmdRm::DoDelete(const TDesC& aFileName) |
|
756 { |
|
757 TInt err; |
|
758 if (iRecurse) |
|
759 { |
|
760 err = iFileMan->RmDir(aFileName); |
|
761 } |
|
762 else |
|
763 { |
|
764 err = iFileMan->Delete(aFileName); |
|
765 } |
|
766 return err; |
|
767 } |
|
768 |
|
769 void CCmdRm::OptionsL(RCommandOptionList& aOptions) |
|
770 { |
|
771 _LIT(KCmdRmOptRecurse, "recurse"); |
|
772 _LIT(KCmdRmOptForce, "force"); |
|
773 aOptions.AppendBoolL(iRecurse, KCmdRmOptRecurse); |
|
774 aOptions.AppendBoolL(iForce, KCmdRmOptForce); |
|
775 } |
|
776 |
|
777 void CCmdRm::ArgumentsL(RCommandArgumentList& aArguments) |
|
778 { |
|
779 _LIT(KCmdRmArg, "file_name"); |
|
780 aArguments.AppendFileNameL(iFileNames, KCmdRmArg); |
|
781 } |
|
782 |
|
783 |
|
784 // |
|
785 // CCmdCp. |
|
786 // |
|
787 |
|
788 CCommandBase* CCmdCp::NewLC() |
|
789 { |
|
790 CCmdCp* self = new(ELeave) CCmdCp(); |
|
791 CleanupStack::PushL(self); |
|
792 self->BaseConstructL(); |
|
793 return self; |
|
794 } |
|
795 |
|
796 CCmdCp::~CCmdCp() |
|
797 { |
|
798 delete iFileMan; |
|
799 } |
|
800 |
|
801 CCmdCp::CCmdCp() |
|
802 { |
|
803 } |
|
804 |
|
805 const TDesC& CCmdCp::Name() const |
|
806 { |
|
807 _LIT(KCmdCpName, "cp"); |
|
808 return KCmdCpName; |
|
809 } |
|
810 |
|
811 void CCmdCp::ForciblyCopyFileL(const TDesC& aSourceFileName, const TDesC& aDestFileName) |
|
812 { |
|
813 RFs& fs = FsL(); |
|
814 TInt err = fs.MkDirAll(aDestFileName); |
|
815 if (err != KErrNone && err != KErrAlreadyExists) |
|
816 { |
|
817 User::Leave(err); |
|
818 } |
|
819 TInt numRetries = 3; |
|
820 retry: |
|
821 TEntry startEntry; |
|
822 User::LeaveIfError(fs.Entry(aSourceFileName, startEntry)); |
|
823 RFile destFile; |
|
824 if (iOverwrite) |
|
825 { |
|
826 User::LeaveIfError(destFile.Replace(fs, aDestFileName, EFileShareExclusive | EFileStream | EFileWrite)); |
|
827 } |
|
828 else |
|
829 { |
|
830 User::LeaveIfError(destFile.Create(fs, aDestFileName, EFileShareExclusive | EFileStream | EFileWrite)); |
|
831 } |
|
832 CleanupClosePushL(destFile); |
|
833 |
|
834 HBufC8* blockBuf = HBufC8::NewLC(KBlockSize); |
|
835 TPtr8 blockPtr(blockBuf->Des()); |
|
836 TInt pos = 0; |
|
837 while (pos < startEntry.iSize) |
|
838 { |
|
839 User::LeaveIfError(fs.ReadFileSection(aSourceFileName, pos, blockPtr, KBlockSize)); |
|
840 if (blockPtr.Length() == 0) |
|
841 { |
|
842 Printf(_L("\r\nReadFileSection returned zero length descriptor, aborting\r\n")); |
|
843 pos = startEntry.iSize; |
|
844 } |
|
845 else |
|
846 { |
|
847 pos += blockPtr.Length(); |
|
848 User::LeaveIfError(destFile.Write(*blockBuf)); |
|
849 } |
|
850 } |
|
851 Printf(KNewLine); |
|
852 |
|
853 CleanupStack::PopAndDestroy(2, &destFile); // blockBuf, destFile. |
|
854 |
|
855 TEntry endEntry; |
|
856 User::LeaveIfError(fs.Entry(aSourceFileName, endEntry)); |
|
857 if (startEntry.iModified != endEntry.iModified) |
|
858 { |
|
859 --numRetries; |
|
860 if (numRetries > 0) |
|
861 { |
|
862 Printf(_L("Modification while copying - retrying...\r\n")); |
|
863 fs.Delete(aDestFileName); // Ignore error. |
|
864 goto retry; |
|
865 } |
|
866 else |
|
867 { |
|
868 Printf(_L("Modification while copying - failed 3 times, aborting...\r\n")); |
|
869 } |
|
870 } |
|
871 } |
|
872 |
|
873 void CCmdCp::DoRunL() |
|
874 { |
|
875 if (iRecurse && iForce) |
|
876 { |
|
877 PrintWarning(_L("--recurse and --force options can't be used together")); |
|
878 User::Leave(KErrArgument); |
|
879 } |
|
880 |
|
881 if (iForce) |
|
882 { |
|
883 ForciblyCopyFileL(iFrom, iTo); |
|
884 } |
|
885 else |
|
886 { |
|
887 iFileMan = CFileMan::NewL(FsL()); |
|
888 TUint flags = 0; |
|
889 if (iRecurse) flags |= CFileMan::ERecurse; |
|
890 if (iOverwrite) flags |= CFileMan::EOverWrite; |
|
891 |
|
892 if (iRecurse && iFrom.Exists(FsL()) && iFrom.IsDirL(FsL())) |
|
893 { |
|
894 // CFileMan behaves markedly differently to standard posix cp, in the case of copying a directory. |
|
895 // POSIX cp does different things depending on whether the destination exists or not: |
|
896 // 1) "cp -r dirname existingdir" will produce the tree "./existingdir/dirname/<files>" |
|
897 // 2) "cp -r dirname nonexistingdir" will produce the tree "./nonexistingdir/<files>" |
|
898 // |
|
899 // CFileMan differs in case (1) and puts the contents of dirname straight into the destination dir. |
|
900 // Therefore to behave sensibly like posix cp in case (1) we add the source name to the destination |
|
901 if (iTo.Exists(FsL())) |
|
902 { |
|
903 iTo.AppendComponentL(iFrom.Name(), TFileName2::EDirectory); |
|
904 } |
|
905 } |
|
906 User::LeaveIfError(iFileMan->Copy(iFrom, iTo, flags)); |
|
907 } |
|
908 } |
|
909 |
|
910 void CCmdCp::OptionsL(RCommandOptionList& aOptions) |
|
911 { |
|
912 _LIT(KCmdCpOptRecurse, "recurse"); |
|
913 _LIT(KCmdCpOptOverwrite, "overwrite"); |
|
914 _LIT(KCmdCpOptForce, "force"); |
|
915 aOptions.AppendBoolL(iRecurse, KCmdCpOptRecurse); |
|
916 aOptions.AppendBoolL(iOverwrite, KCmdCpOptOverwrite); |
|
917 aOptions.AppendBoolL(iForce, KCmdCpOptForce); |
|
918 } |
|
919 |
|
920 void CCmdCp::ArgumentsL(RCommandArgumentList& aArguments) |
|
921 { |
|
922 _LIT(KCmdCpArg1, "source"); |
|
923 _LIT(KCmdCpArg2, "destination"); |
|
924 aArguments.AppendFileNameL(iFrom, KCmdCpArg1); |
|
925 aArguments.AppendFileNameL(iTo, KCmdCpArg2); |
|
926 } |
|
927 |
|
928 |
|
929 // |
|
930 // CCmdMv. |
|
931 // |
|
932 |
|
933 CCommandBase* CCmdMv::NewLC() |
|
934 { |
|
935 CCmdMv* self = new(ELeave) CCmdMv(); |
|
936 CleanupStack::PushL(self); |
|
937 self->BaseConstructL(); |
|
938 return self; |
|
939 } |
|
940 |
|
941 CCmdMv::~CCmdMv() |
|
942 { |
|
943 delete iFileMan; |
|
944 } |
|
945 |
|
946 CCmdMv::CCmdMv() |
|
947 { |
|
948 } |
|
949 |
|
950 const TDesC& CCmdMv::Name() const |
|
951 { |
|
952 _LIT(KCmdMvName, "mv"); |
|
953 return KCmdMvName; |
|
954 } |
|
955 |
|
956 void CCmdMv::DoRunL() |
|
957 { |
|
958 if (iTo.Exists(FsL()) && iTo.IsDirL(FsL())) |
|
959 { |
|
960 iTo.SetTypeL(TFileName2::EDirectory); |
|
961 } |
|
962 iFileMan = CFileMan::NewL(FsL()); |
|
963 User::LeaveIfError(iFileMan->Move(iFrom, iTo, 0)); |
|
964 } |
|
965 |
|
966 void CCmdMv::ArgumentsL(RCommandArgumentList& aArguments) |
|
967 { |
|
968 _LIT(KCmdMvArg1, "source_file"); |
|
969 _LIT(KCmdMvArg2, "destination_file"); |
|
970 aArguments.AppendFileNameL(iFrom, KCmdMvArg1); |
|
971 aArguments.AppendFileNameL(iTo, KCmdMvArg2); |
|
972 } |
|
973 |
|
974 |
|
975 // |
|
976 // CCmdMkDir. |
|
977 // |
|
978 |
|
979 CCommandBase* CCmdMkDir::NewLC() |
|
980 { |
|
981 CCmdMkDir* self = new(ELeave) CCmdMkDir(); |
|
982 CleanupStack::PushL(self); |
|
983 self->BaseConstructL(); |
|
984 return self; |
|
985 } |
|
986 |
|
987 CCmdMkDir::~CCmdMkDir() |
|
988 { |
|
989 } |
|
990 |
|
991 CCmdMkDir::CCmdMkDir() |
|
992 : iDir(TFileName2::EDirectory) |
|
993 { |
|
994 } |
|
995 |
|
996 const TDesC& CCmdMkDir::Name() const |
|
997 { |
|
998 _LIT(KCmdMkDirName, "mkdir"); |
|
999 return KCmdMkDirName; |
|
1000 } |
|
1001 |
|
1002 void CCmdMkDir::DoRunL() |
|
1003 { |
|
1004 TInt err = FsL().MkDirAll(iDir); |
|
1005 if (iAllowExists && (err == KErrAlreadyExists)) |
|
1006 { |
|
1007 err = KErrNone; |
|
1008 } |
|
1009 User::LeaveIfError(err); |
|
1010 } |
|
1011 |
|
1012 void CCmdMkDir::OptionsL(RCommandOptionList& aOptions) |
|
1013 { |
|
1014 _LIT(KCmdMkDirOptAllowExists, "allow_exists"); |
|
1015 aOptions.AppendBoolL(iAllowExists, KCmdMkDirOptAllowExists); |
|
1016 } |
|
1017 |
|
1018 void CCmdMkDir::ArgumentsL(RCommandArgumentList& aArguments) |
|
1019 { |
|
1020 _LIT(KCmdMkDirArg, "dir_name"); |
|
1021 aArguments.AppendFileNameL(iDir, KCmdMkDirArg); |
|
1022 } |
|
1023 |
|
1024 |
|
1025 // |
|
1026 // CCmdRmDir. |
|
1027 // |
|
1028 |
|
1029 CCommandBase* CCmdRmDir::NewLC() |
|
1030 { |
|
1031 CCmdRmDir* self = new(ELeave) CCmdRmDir(); |
|
1032 CleanupStack::PushL(self); |
|
1033 self->BaseConstructL(); |
|
1034 return self; |
|
1035 } |
|
1036 |
|
1037 CCmdRmDir::~CCmdRmDir() |
|
1038 { |
|
1039 delete iFileMan; |
|
1040 iDirs.Close(); |
|
1041 } |
|
1042 |
|
1043 CCmdRmDir::CCmdRmDir() |
|
1044 { |
|
1045 } |
|
1046 |
|
1047 const TDesC& CCmdRmDir::Name() const |
|
1048 { |
|
1049 _LIT(KCmdRmDirName, "rmdir"); |
|
1050 return KCmdRmDirName; |
|
1051 } |
|
1052 |
|
1053 void CCmdRmDir::DoRunL() |
|
1054 { |
|
1055 const TInt numDirs = iDirs.Count(); |
|
1056 for (TInt i = 0; i < numDirs; ++i) |
|
1057 { |
|
1058 TFileName2& dir = iDirs[i]; |
|
1059 if (dir.IsDirL(FsL())) |
|
1060 { |
|
1061 dir.SetTypeL(TFileName2::EDirectory); |
|
1062 } |
|
1063 else |
|
1064 { |
|
1065 PrintError(KErrArgument, _L("\"%S\" is not a directory."), &dir); |
|
1066 User::Leave(KErrArgument); |
|
1067 } |
|
1068 |
|
1069 LeaveIfFileNotFound(dir); |
|
1070 |
|
1071 if (iRecurse) |
|
1072 { |
|
1073 if (iFileMan == NULL) |
|
1074 { |
|
1075 iFileMan = CFileMan::NewL(FsL()); |
|
1076 } |
|
1077 User::LeaveIfError(iFileMan->RmDir(dir)); |
|
1078 } |
|
1079 else |
|
1080 { |
|
1081 User::LeaveIfError(FsL().RmDir(dir)); |
|
1082 } |
|
1083 } |
|
1084 } |
|
1085 |
|
1086 void CCmdRmDir::OptionsL(RCommandOptionList& aOptions) |
|
1087 { |
|
1088 _LIT(KCmdRmDirOptRecurse, "recurse"); |
|
1089 aOptions.AppendBoolL(iRecurse, KCmdRmDirOptRecurse); |
|
1090 } |
|
1091 |
|
1092 void CCmdRmDir::ArgumentsL(RCommandArgumentList& aArguments) |
|
1093 { |
|
1094 _LIT(KCmdRmDirArg, "dir_name"); |
|
1095 aArguments.AppendFileNameL(iDirs, KCmdRmDirArg); |
|
1096 } |
|
1097 |
|
1098 |
|
1099 // |
|
1100 // CCmdMatch. |
|
1101 // |
|
1102 |
|
1103 CCommandBase* CCmdMatch::NewLC() |
|
1104 { |
|
1105 CCmdMatch* self = new(ELeave) CCmdMatch(); |
|
1106 CleanupStack::PushL(self); |
|
1107 self->BaseConstructL(); |
|
1108 return self; |
|
1109 } |
|
1110 |
|
1111 CCmdMatch::~CCmdMatch() |
|
1112 { |
|
1113 delete iToMatch; |
|
1114 } |
|
1115 |
|
1116 CCmdMatch::CCmdMatch() |
|
1117 { |
|
1118 } |
|
1119 |
|
1120 const TDesC& CCmdMatch::Name() const |
|
1121 { |
|
1122 _LIT(KCmdMatchName, "match"); |
|
1123 return KCmdMatchName; |
|
1124 } |
|
1125 |
|
1126 void CCmdMatch::DoRunL() |
|
1127 { |
|
1128 Stdin().SetReadMode(RIoReadHandle::ELine); |
|
1129 TBuf<0x100> line; |
|
1130 TInt count = 0; |
|
1131 while (Stdin().Read(line) == KErrNone) |
|
1132 { |
|
1133 TBool matches; |
|
1134 if (iIgnoreCase) |
|
1135 { |
|
1136 matches = (line.MatchF(*iToMatch) != KErrNotFound); |
|
1137 } |
|
1138 else |
|
1139 { |
|
1140 matches = (line.Match(*iToMatch) != KErrNotFound); |
|
1141 } |
|
1142 if (iInvertMatch) |
|
1143 { |
|
1144 matches = !matches; |
|
1145 } |
|
1146 if (matches) |
|
1147 { |
|
1148 if (iCount) |
|
1149 { |
|
1150 count++; |
|
1151 } |
|
1152 else |
|
1153 { |
|
1154 Write(line); |
|
1155 } |
|
1156 } |
|
1157 } |
|
1158 |
|
1159 if (iCount) |
|
1160 { |
|
1161 Printf(_L("Count = %d"), count); |
|
1162 } |
|
1163 } |
|
1164 |
|
1165 void CCmdMatch::OptionsL(RCommandOptionList& aOptions) |
|
1166 { |
|
1167 _LIT(KCmdMatchOptIgnoreCase, "ignore-case"); |
|
1168 _LIT(KCmdMatchOptInvertMatch, "invert-match"); |
|
1169 _LIT(KCmdMatchOptCount, "count"); |
|
1170 aOptions.AppendBoolL(iIgnoreCase, KCmdMatchOptIgnoreCase); |
|
1171 aOptions.AppendBoolL(iInvertMatch, KCmdMatchOptInvertMatch); |
|
1172 aOptions.AppendBoolL(iCount, KCmdMatchOptCount); |
|
1173 } |
|
1174 |
|
1175 void CCmdMatch::ArgumentsL(RCommandArgumentList& aArguments) |
|
1176 { |
|
1177 _LIT(KCmdMatchArg1, "pattern"); |
|
1178 aArguments.AppendStringL(iToMatch, KCmdMatchArg1); |
|
1179 } |
|
1180 |
|
1181 |
|
1182 // |
|
1183 // CCmdEcho. |
|
1184 // |
|
1185 |
|
1186 CCommandBase* CCmdEcho::NewLC() |
|
1187 { |
|
1188 CCmdEcho* self = new(ELeave) CCmdEcho(); |
|
1189 CleanupStack::PushL(self); |
|
1190 self->BaseConstructL(); |
|
1191 return self; |
|
1192 } |
|
1193 |
|
1194 CCmdEcho::~CCmdEcho() |
|
1195 { |
|
1196 delete iToEcho; |
|
1197 iAttributes.Close(); |
|
1198 } |
|
1199 |
|
1200 CCmdEcho::CCmdEcho() |
|
1201 : iForegroundColor(ConsoleAttributes::EUnchanged), iBackgroundColor(ConsoleAttributes::EUnchanged) |
|
1202 { |
|
1203 } |
|
1204 |
|
1205 void CCmdEcho::DoWriteL(const TDesC& aDes) |
|
1206 { |
|
1207 if (iToStderr) |
|
1208 { |
|
1209 Stderr().Write(aDes); |
|
1210 } |
|
1211 else |
|
1212 { |
|
1213 Stdout().Write(aDes); |
|
1214 } |
|
1215 } |
|
1216 |
|
1217 const TDesC& CCmdEcho::Name() const |
|
1218 { |
|
1219 _LIT(KCmdEchoName, "echo"); |
|
1220 return KCmdEchoName; |
|
1221 } |
|
1222 |
|
1223 void CCmdEcho::DoRunL() |
|
1224 { |
|
1225 RIoConsoleWriteHandle& out = iToStderr ? Stderr() : Stdout(); |
|
1226 |
|
1227 if (iBinaryMode) |
|
1228 { |
|
1229 LeaveIfErr(out.SetMode(RIoReadWriteHandle::EBinary), _L("Unable to set write handle to binary mode")); |
|
1230 } |
|
1231 |
|
1232 CTextFormatter* formatter = CTextFormatter::NewLC(out); |
|
1233 |
|
1234 TUint attributes = 0; |
|
1235 const TInt numAttributes = iAttributes.Count(); |
|
1236 for (TInt i = 0; i < numAttributes; ++i) |
|
1237 { |
|
1238 switch ((TAttr)iAttributes[i]) |
|
1239 { |
|
1240 case EBold: |
|
1241 attributes |= ConsoleAttributes::EBold; |
|
1242 break; |
|
1243 case EUnderscore: |
|
1244 attributes |= ConsoleAttributes::EUnderscore; |
|
1245 break; |
|
1246 case EBlink: |
|
1247 attributes |= ConsoleAttributes::EBlink; |
|
1248 break; |
|
1249 case EInverse: |
|
1250 attributes |= ConsoleAttributes::EInverse; |
|
1251 break; |
|
1252 case EConceal: |
|
1253 attributes |= ConsoleAttributes::EConceal; |
|
1254 break; |
|
1255 } |
|
1256 } |
|
1257 |
|
1258 formatter->SetAttributesL(attributes, iForegroundColor, iBackgroundColor); |
|
1259 |
|
1260 if (iToEcho) |
|
1261 { |
|
1262 if (iWrap) |
|
1263 { |
|
1264 formatter->WrapL(iIndent, *iToEcho); |
|
1265 } |
|
1266 else |
|
1267 { |
|
1268 formatter->AppendL(*iToEcho); |
|
1269 } |
|
1270 // Add a newline if it doesn't already end in one (and --no-newline isn't specified) |
|
1271 if (!iNoNewline && iToEcho->Right(KNewLine().Length()) != KNewLine) |
|
1272 { |
|
1273 formatter->AppendL(KNewLine); |
|
1274 } |
|
1275 } |
|
1276 else |
|
1277 { |
|
1278 TBuf<0x100> buf; |
|
1279 TInt err = KErrNone; |
|
1280 do |
|
1281 { |
|
1282 err = Stdin().Read(buf); |
|
1283 if (err == KErrNone) |
|
1284 { |
|
1285 if (iWrap) |
|
1286 { |
|
1287 formatter->WrapL(iIndent, buf); |
|
1288 } |
|
1289 else |
|
1290 { |
|
1291 formatter->AppendL(buf); |
|
1292 } |
|
1293 } |
|
1294 } |
|
1295 while (err == KErrNone); |
|
1296 } |
|
1297 |
|
1298 formatter->Write(); |
|
1299 CleanupStack::PopAndDestroy(formatter); |
|
1300 } |
|
1301 |
|
1302 void CCmdEcho::OptionsL(RCommandOptionList& aOptions) |
|
1303 { |
|
1304 _LIT(KCmdEchoOptToStderr, "stderr"); |
|
1305 _LIT(KCmdEchoOptWrap, "wrap"); |
|
1306 _LIT(KCmdEchoOptIndent, "indent"); |
|
1307 _LIT(KCmdEchoOptAttributes, "attributes"); |
|
1308 _LIT(KCmdEchoOptForground, "foreground-color"); |
|
1309 _LIT(KCmdEchoOptBackground, "background-color"); |
|
1310 _LIT(KCmdEchoOptBinaryMode, "binary"); |
|
1311 _LIT(KCmdEchoOptNoNewline, "no-newline"); |
|
1312 |
|
1313 aOptions.AppendBoolL(iToStderr, KCmdEchoOptToStderr); |
|
1314 aOptions.AppendBoolL(iWrap, KCmdEchoOptWrap); |
|
1315 aOptions.AppendUintL(iIndent, KCmdEchoOptIndent); |
|
1316 aOptions.AppendEnumL(iAttributes, KCmdEchoOptAttributes); |
|
1317 aOptions.AppendEnumL((TInt&)iForegroundColor, KCmdEchoOptForground); |
|
1318 aOptions.AppendEnumL((TInt&)iBackgroundColor, KCmdEchoOptBackground); |
|
1319 aOptions.AppendBoolL(iBinaryMode, KCmdEchoOptBinaryMode); |
|
1320 aOptions.AppendBoolL(iNoNewline, KCmdEchoOptNoNewline); |
|
1321 } |
|
1322 |
|
1323 void CCmdEcho::ArgumentsL(RCommandArgumentList& aArguments) |
|
1324 { |
|
1325 _LIT(KCmdEchoArg1, "string"); |
|
1326 aArguments.AppendStringL(iToEcho, KCmdEchoArg1); |
|
1327 } |
|
1328 |
|
1329 |
|
1330 // |
|
1331 // CCmdMore. |
|
1332 // |
|
1333 |
|
1334 CCommandBase* CCmdMore::NewLC() |
|
1335 { |
|
1336 CCmdMore* self = new(ELeave) CCmdMore(); |
|
1337 CleanupStack::PushL(self); |
|
1338 self->BaseConstructL(); |
|
1339 return self; |
|
1340 } |
|
1341 |
|
1342 CCmdMore::~CCmdMore() |
|
1343 { |
|
1344 } |
|
1345 |
|
1346 CCmdMore::CCmdMore() |
|
1347 { |
|
1348 } |
|
1349 |
|
1350 const TDesC& CCmdMore::Name() const |
|
1351 { |
|
1352 _LIT(KCmdMoreName, "more"); |
|
1353 return KCmdMoreName; |
|
1354 } |
|
1355 |
|
1356 void CCmdMore::ArgumentsL(RCommandArgumentList& aArguments) |
|
1357 { |
|
1358 _LIT(KMoreArg1, "file_name"); |
|
1359 aArguments.AppendFileNameL(iFile, KMoreArg1); |
|
1360 } |
|
1361 |
|
1362 void CCmdMore::DoRunL() |
|
1363 { |
|
1364 RIoReadHandle input; |
|
1365 input.CreateL(IoSession()); |
|
1366 CleanupClosePushL(input); |
|
1367 |
|
1368 RIoFile file; |
|
1369 CleanupClosePushL(file); |
|
1370 |
|
1371 if (iArguments.IsPresent(0)) |
|
1372 { |
|
1373 file.CreateL(IoSession(), iFile, RIoFile::ERead); |
|
1374 IoSession().SetObjectNameL(file.SubSessionHandle(), iFile); |
|
1375 _LIT(KReaderSuffix, "_more_reader"); |
|
1376 iFile.SetLength(Min(iFile.Length(), iFile.MaxLength() - KReaderSuffix().Length())); |
|
1377 iFile.Append(KReaderSuffix); |
|
1378 IoSession().SetObjectNameL(input.SubSessionHandle(), iFile); |
|
1379 file.AttachL(input, RIoEndPoint::EForeground); |
|
1380 } |
|
1381 else |
|
1382 { |
|
1383 input.DuplicateL(Stdin()); |
|
1384 input.SetToForegroundL(); |
|
1385 } |
|
1386 |
|
1387 PageL(input); |
|
1388 |
|
1389 CleanupStack::PopAndDestroy(2, &input); |
|
1390 } |
|
1391 |
|
1392 |
|
1393 // |
|
1394 // CCmdTrace. |
|
1395 // |
|
1396 |
|
1397 CCommandBase* CCmdTrace::NewLC() |
|
1398 { |
|
1399 CCmdTrace* self = new(ELeave) CCmdTrace(); |
|
1400 CleanupStack::PushL(self); |
|
1401 self->BaseConstructL(); |
|
1402 return self; |
|
1403 } |
|
1404 |
|
1405 CCmdTrace::~CCmdTrace() |
|
1406 { |
|
1407 iEnable.ResetAndDestroy(); |
|
1408 iDisable.ResetAndDestroy(); |
|
1409 } |
|
1410 |
|
1411 CCmdTrace::CCmdTrace() |
|
1412 { |
|
1413 } |
|
1414 |
|
1415 const TDesC& CCmdTrace::Name() const |
|
1416 { |
|
1417 _LIT(KCmdTraceName, "trace"); |
|
1418 return KCmdTraceName; |
|
1419 } |
|
1420 |
|
1421 const LtkUtils::SLitC8 KTraceBitNames[] = |
|
1422 { |
|
1423 DESC8("khardware"), |
|
1424 DESC8("kboot"), |
|
1425 DESC8("kserver"), |
|
1426 DESC8("kmmu"), |
|
1427 DESC8("ksemaphore"), |
|
1428 DESC8("ksched"), |
|
1429 DESC8("kproc"), |
|
1430 DESC8("kexec"), |
|
1431 DESC8("kdebugger"), |
|
1432 DESC8("kthread"), |
|
1433 DESC8("kdll"), |
|
1434 DESC8("kipc"), |
|
1435 DESC8("kpbus1"), |
|
1436 DESC8("kpbus"), |
|
1437 DESC8("kpbusdrv"), |
|
1438 DESC8("kpower"), |
|
1439 DESC8("ktiming"), |
|
1440 DESC8("kevent"), |
|
1441 DESC8("kobject"), |
|
1442 DESC8("kdfc"), |
|
1443 DESC8("kextension"), |
|
1444 DESC8("ksched2"), |
|
1445 DESC8("klocdrv"), |
|
1446 DESC8("kfail"), |
|
1447 DESC8("kthread2"), |
|
1448 DESC8("kdevice"), |
|
1449 DESC8("kmemtrace"), |
|
1450 DESC8("kdma"), |
|
1451 DESC8("kmmu2"), |
|
1452 DESC8("knkern"), |
|
1453 DESC8("kscratch"), |
|
1454 DESC8("kpanic"), |
|
1455 // Word 1 |
|
1456 DESC8("kusb"), |
|
1457 DESC8("kusbpsl"), |
|
1458 DESC8("knetwork1"), |
|
1459 DESC8("knetwork2"), |
|
1460 DESC8("ksound1"), |
|
1461 DESC8("kusbhost"), |
|
1462 DESC8("kusbotg"), |
|
1463 DESC8("kusbjournal"), |
|
1464 DESC8("kusbho"), |
|
1465 DESC8("kresmanager"), |
|
1466 DESC8("kiic"), |
|
1467 DESC8("khcr"), |
|
1468 DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), |
|
1469 DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), |
|
1470 DESC8("kpipe"), |
|
1471 DESC8("kpci"), |
|
1472 DESC8("kdatapagewarn"), |
|
1473 DESC8("klocdpaging"), |
|
1474 DESC8("kpaging"), |
|
1475 DESC8("krealtime"), |
|
1476 // Word 2 |
|
1477 DESC8("kallthreadssystem"), |
|
1478 DESC8("ktestfast"), |
|
1479 DESC8("ktestlatency"), |
|
1480 DESC8("kdebugmonitordisable"), |
|
1481 DESC8("kcrashmonitordisable"), |
|
1482 DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), |
|
1483 DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), |
|
1484 DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), DESC8(""), |
|
1485 DESC8(""), DESC8(""), DESC8(""), |
|
1486 // Word 3 |
|
1487 DESC8("kuserheaptrace"), |
|
1488 }; |
|
1489 const TInt KTraceBitCount = sizeof(KTraceBitNames) / sizeof(LtkUtils::SLitC); |
|
1490 |
|
1491 #ifndef KCOMPFS // Not defined on 9.1 |
|
1492 #define KCOMPFS 0x0400 |
|
1493 #endif |
|
1494 |
|
1495 void CCmdTrace::DoRunL() |
|
1496 { |
|
1497 TInt debugVal = 0; |
|
1498 if (iOptF32) |
|
1499 debugVal|=KFSERV; |
|
1500 if (iOptLoader) |
|
1501 debugVal|=KFLDR; |
|
1502 if (iOptFat) |
|
1503 debugVal|=KFSYS; |
|
1504 if (iOptLffs) |
|
1505 debugVal|=KLFFS; |
|
1506 #ifdef EKA2 |
|
1507 if (iOptIso9660) |
|
1508 debugVal|=KISO9660; |
|
1509 if (iOptNtfs) |
|
1510 debugVal|=KNTFS; |
|
1511 if (iOptMultiThread) |
|
1512 debugVal|=KTHRD; |
|
1513 if (iOptRofs) |
|
1514 debugVal|=KROFS; |
|
1515 if (iOptCompfs) |
|
1516 debugVal|=KCOMPFS; |
|
1517 #endif |
|
1518 TInt err = FsL().SetDebugRegister(debugVal); |
|
1519 if (err && debugVal != 0) |
|
1520 { |
|
1521 // Don't bother printing a warning if none of the FS-related options were actually specified |
|
1522 PrintWarning(_L("Unable to configure file server traces: %d"), err); |
|
1523 } |
|
1524 |
|
1525 if (iArguments.IsPresent(0)) |
|
1526 { |
|
1527 #ifdef EKA2 |
|
1528 User::SetDebugMask(iMask, iIndex); |
|
1529 #else |
|
1530 User::SetDebugMask(iMask); |
|
1531 #endif |
|
1532 } |
|
1533 else if (debugVal == 0) |
|
1534 { |
|
1535 if (iEnable.Count() || iDisable.Count()) |
|
1536 { |
|
1537 for (TInt i = 0; i < iEnable.Count(); i++) |
|
1538 { |
|
1539 TInt err = SetFlag(*iEnable[i], ETrue); |
|
1540 if (err) PrintWarning(_L("Flag '%S' not understood"), iEnable[i]); |
|
1541 } |
|
1542 for (TInt i = 0; i < iDisable.Count(); i++) |
|
1543 { |
|
1544 TInt err = SetFlag(*iDisable[i], EFalse); |
|
1545 if (err) PrintWarning(_L("Flag '%S' not understood"), iEnable[i]); |
|
1546 } |
|
1547 } |
|
1548 else |
|
1549 { |
|
1550 PrintConfig(); |
|
1551 } |
|
1552 } |
|
1553 } |
|
1554 |
|
1555 void CCmdTrace::PrintConfig() |
|
1556 { |
|
1557 #ifdef EKA2 |
|
1558 for (TInt i = 0; i < 8; ++i) |
|
1559 { |
|
1560 TBool seen = EFalse; |
|
1561 TUint32 mask = UserSvr::DebugMask(i); |
|
1562 Printf(_L("DebugMask(%d) = 0x%08X"), i, mask); |
|
1563 for (TInt bit = 0; bit < 32; bit++) |
|
1564 { |
|
1565 if (mask & (1 << bit)) |
|
1566 { |
|
1567 if (seen) |
|
1568 { |
|
1569 Write(_L("|")); |
|
1570 } |
|
1571 else |
|
1572 { |
|
1573 Write(_L(" (")); |
|
1574 } |
|
1575 seen = ETrue; |
|
1576 TInt idx = i*32 + bit; |
|
1577 if (idx < KTraceBitCount && KTraceBitNames[idx]().Length()) |
|
1578 { |
|
1579 Printf(KTraceBitNames[idx]()); |
|
1580 } |
|
1581 else |
|
1582 { |
|
1583 Write(_L("?")); |
|
1584 } |
|
1585 } |
|
1586 } |
|
1587 if (seen) Write(_L(")")); |
|
1588 Write(KNewLine); |
|
1589 } |
|
1590 #else |
|
1591 Printf(_L("DebugMask = 0x%08X\r\n"), UserSvr::DebugMask()); |
|
1592 #endif |
|
1593 } |
|
1594 |
|
1595 TInt CCmdTrace::SetFlag(const TDesC& aFlagName, TBool aSet) |
|
1596 { |
|
1597 // Find aFlagName in KTraceBitNames |
|
1598 TBuf8<64> flagname; |
|
1599 for (TInt i = 0; i < KTraceBitCount; i++) |
|
1600 { |
|
1601 flagname.Copy(aFlagName); |
|
1602 flagname.LowerCase(); |
|
1603 if (flagname.Compare(KTraceBitNames[i]) == 0) |
|
1604 { |
|
1605 TInt word = i / 32; |
|
1606 TInt idx = i % 32; |
|
1607 TUint32 mask = UserSvr::DebugMask(word); |
|
1608 if (aSet) |
|
1609 { |
|
1610 mask |= 1 << idx; |
|
1611 } |
|
1612 else |
|
1613 { |
|
1614 mask &= ~(1 << idx); |
|
1615 } |
|
1616 User::SetDebugMask(mask, word); |
|
1617 return KErrNone; |
|
1618 } |
|
1619 } |
|
1620 return KErrNotFound; |
|
1621 } |
|
1622 |
|
1623 void CCmdTrace::OptionsL(RCommandOptionList& aOptions) |
|
1624 { |
|
1625 _LIT(KCmdTraceOptS, "f32"); |
|
1626 _LIT(KCmdTraceOptM, "multi-thread"); |
|
1627 _LIT(KCmdTraceOptL, "loader"); |
|
1628 _LIT(KCmdTraceOptF, "fat"); |
|
1629 _LIT(KCmdTraceOptT, "lffs"); |
|
1630 _LIT(KCmdTraceOptI, "iso9660"); |
|
1631 _LIT(KCmdTraceOptN, "ntfs"); |
|
1632 _LIT(KCmdTraceOptO, "rofs"); |
|
1633 _LIT(KCmdTraceOptC, "compfs"); |
|
1634 |
|
1635 aOptions.AppendBoolL(iOptF32, KCmdTraceOptS); |
|
1636 aOptions.AppendBoolL(iOptMultiThread, KCmdTraceOptM); |
|
1637 aOptions.AppendBoolL(iOptLoader, KCmdTraceOptL); |
|
1638 aOptions.AppendBoolL(iOptFat, KCmdTraceOptF); |
|
1639 aOptions.AppendBoolL(iOptLffs, KCmdTraceOptT); |
|
1640 #ifdef EKA2 |
|
1641 aOptions.AppendBoolL(iOptIso9660, KCmdTraceOptI); |
|
1642 aOptions.AppendBoolL(iOptNtfs, KCmdTraceOptN); |
|
1643 aOptions.AppendBoolL(iOptRofs, KCmdTraceOptO); |
|
1644 aOptions.AppendBoolL(iOptCompfs, KCmdTraceOptC); |
|
1645 #endif |
|
1646 |
|
1647 _LIT(KEnable, "enable"); |
|
1648 aOptions.AppendStringL(iEnable, KEnable); |
|
1649 _LIT(KDisable, "disable"); |
|
1650 aOptions.AppendStringL(iDisable, KDisable); |
|
1651 } |
|
1652 |
|
1653 void CCmdTrace::ArgumentsL(RCommandArgumentList& aArguments) |
|
1654 { |
|
1655 _LIT(KCmdTraceArg1, "debug_mask"); |
|
1656 aArguments.AppendUintL(iMask, KCmdTraceArg1); |
|
1657 #ifdef EKA2 |
|
1658 _LIT(KCmdTraceArg2, "index"); |
|
1659 aArguments.AppendUintL(iIndex, KCmdTraceArg2); |
|
1660 #endif |
|
1661 } |
|
1662 |
|
1663 |
|
1664 // |
|
1665 // CCmdMemInfo. |
|
1666 // |
|
1667 |
|
1668 CCommandBase* CCmdMemInfo::NewLC() |
|
1669 { |
|
1670 CCmdMemInfo* self = new(ELeave) CCmdMemInfo(); |
|
1671 CleanupStack::PushL(self); |
|
1672 self->BaseConstructL(); |
|
1673 return self; |
|
1674 } |
|
1675 |
|
1676 CCmdMemInfo::~CCmdMemInfo() |
|
1677 { |
|
1678 } |
|
1679 |
|
1680 CCmdMemInfo::CCmdMemInfo() |
|
1681 { |
|
1682 } |
|
1683 |
|
1684 const TDesC& CCmdMemInfo::Name() const |
|
1685 { |
|
1686 _LIT(KCmdMemInfoName, "meminfo"); |
|
1687 return KCmdMemInfoName; |
|
1688 } |
|
1689 |
|
1690 void CCmdMemInfo::AppendLineL(CTextFormatter& aFormatter, const TDesC& aCaption, HALData::TAttribute aHalAttribute, TBool aNewLine) |
|
1691 { |
|
1692 TInt value; |
|
1693 TInt err = HAL::Get(aHalAttribute, value); |
|
1694 if (err) |
|
1695 { |
|
1696 PrintWarning(_L("Unable to read %S%d"), &aCaption, err); |
|
1697 } |
|
1698 else |
|
1699 { |
|
1700 if ((aHalAttribute != HALData::EMemoryRAMFree) || ((aHalAttribute == HALData::EMemoryRAMFree) && (value != iLastTotalRamUsage))) |
|
1701 { |
|
1702 aFormatter.AppendL(aCaption); |
|
1703 if (iHumanReadable) |
|
1704 { |
|
1705 aFormatter.AppendHumanReadableSizeL(value, EColumnAlignedRight); |
|
1706 } |
|
1707 else |
|
1708 { |
|
1709 aFormatter.AppendFormatL(_L("%d"), value); |
|
1710 } |
|
1711 if (aNewLine) |
|
1712 { |
|
1713 aFormatter.AppendL(KNewLine); |
|
1714 } |
|
1715 } |
|
1716 if (aHalAttribute == HALData::EMemoryRAMFree) |
|
1717 { |
|
1718 iLastTotalRamUsage = value; |
|
1719 } |
|
1720 } |
|
1721 } |
|
1722 |
|
1723 void CCmdMemInfo::DoRunL() |
|
1724 { |
|
1725 if (iOnlyFreeRam && iOnlyTotalRam) |
|
1726 { |
|
1727 LeaveIfErr(KErrArgument, _L("Mutually exclusive options")); |
|
1728 } |
|
1729 CTextFormatter* formatter = CTextFormatter::NewLC(Stdout()); |
|
1730 if (iOnlyFreeRam) |
|
1731 { |
|
1732 AppendLineL(*formatter, KNullDesC, HALData::EMemoryRAMFree, EFalse); |
|
1733 } |
|
1734 else if (iOnlyTotalRam) |
|
1735 { |
|
1736 AppendLineL(*formatter, KNullDesC, HALData::EMemoryRAM, EFalse); |
|
1737 } |
|
1738 else |
|
1739 { |
|
1740 AppendLineL(*formatter, _L("Total ROM: "), HALData::EMemoryROM, ETrue); |
|
1741 AppendLineL(*formatter, _L("Total RAM: "), HALData::EMemoryRAM, ETrue); |
|
1742 AppendLineL(*formatter, _L("Page size: "), HALData::EMemoryPageSize, ETrue); |
|
1743 AppendLineL(*formatter, _L("Free RAM: "), HALData::EMemoryRAMFree, EFalse); |
|
1744 } |
|
1745 |
|
1746 Write(formatter->Descriptor()); |
|
1747 if (iUpdateRate) |
|
1748 { |
|
1749 if (Stdout().AttachedToConsole()) |
|
1750 { |
|
1751 RIoConsoleWriteHandle stdout = Stdout(); |
|
1752 stdout.SetCursorHeight(0); |
|
1753 } |
|
1754 FOREVER |
|
1755 { |
|
1756 User::After(iUpdateRate * 1000); |
|
1757 formatter->Zero(); |
|
1758 AppendLineL(*formatter, _L("\rFree RAM: "), HALData::EMemoryRAMFree, EFalse); |
|
1759 Write(formatter->Descriptor()); |
|
1760 } |
|
1761 } |
|
1762 CleanupStack::PopAndDestroy(formatter); |
|
1763 } |
|
1764 |
|
1765 void CCmdMemInfo::OptionsL(RCommandOptionList& aOptions) |
|
1766 { |
|
1767 _LIT(KCmdMemInfoOptUpdateRate, "rate"); |
|
1768 _LIT(KCmdMemInfoOptHuman, "human"); |
|
1769 _LIT(KCmdMemInfoOptOnlyFreeRam, "free"); |
|
1770 _LIT(KCmdMemInfoOptOnlyTotalRam, "total"); |
|
1771 |
|
1772 aOptions.AppendBoolL(iHumanReadable, KCmdMemInfoOptHuman); |
|
1773 aOptions.AppendUintL(iUpdateRate, KCmdMemInfoOptUpdateRate); |
|
1774 aOptions.AppendBoolL(iOnlyFreeRam, KCmdMemInfoOptOnlyFreeRam); |
|
1775 aOptions.AppendBoolL(iOnlyTotalRam, KCmdMemInfoOptOnlyTotalRam); |
|
1776 } |
|
1777 |
|
1778 |
|
1779 // |
|
1780 // CCmdDump. |
|
1781 // |
|
1782 |
|
1783 void Dump(const TDesC8& aData, CCommandBase& aCommand, TInt& aPos) |
|
1784 { |
|
1785 TBuf<80> out; |
|
1786 TBuf<16> ascii; |
|
1787 TInt dataIndex = 0; |
|
1788 do |
|
1789 { |
|
1790 out.Zero(); |
|
1791 ascii.Zero(); |
|
1792 out.AppendNumFixedWidthUC(aPos, EHex, 8); |
|
1793 out.Append(_L(": ")); |
|
1794 for (TInt i = 0; i < 16; ++i) |
|
1795 { |
|
1796 if (dataIndex < aData.Length()) |
|
1797 { |
|
1798 TUint8 byte = aData[dataIndex++]; |
|
1799 out.AppendNumFixedWidthUC(byte, EHex, 2); |
|
1800 out.Append(_L(" ")); |
|
1801 if ((byte < 0x20) || (byte >= 0x7f) || byte == '%') |
|
1802 { |
|
1803 byte = '.'; |
|
1804 } |
|
1805 ascii.Append(TChar(byte)); |
|
1806 ++aPos; |
|
1807 } |
|
1808 else |
|
1809 { |
|
1810 out.Append(_L(" ")); |
|
1811 aPos = 0; |
|
1812 } |
|
1813 } |
|
1814 out.Append(ascii); |
|
1815 out.Append(KNewLine); |
|
1816 aCommand.Write(out); |
|
1817 } |
|
1818 while (dataIndex < aData.Length()); |
|
1819 } |
|
1820 |
|
1821 CCommandBase* CCmdDump::NewLC() |
|
1822 { |
|
1823 CCmdDump* self = new(ELeave) CCmdDump(); |
|
1824 CleanupStack::PushL(self); |
|
1825 self->BaseConstructL(); |
|
1826 return self; |
|
1827 } |
|
1828 |
|
1829 CCmdDump::~CCmdDump() |
|
1830 { |
|
1831 iFileNames.Close(); |
|
1832 } |
|
1833 |
|
1834 CCmdDump::CCmdDump() |
|
1835 { |
|
1836 } |
|
1837 |
|
1838 const TDesC& CCmdDump::Name() const |
|
1839 { |
|
1840 _LIT(KCmdDumpName, "dump"); |
|
1841 return KCmdDumpName; |
|
1842 } |
|
1843 |
|
1844 void CCmdDump::DoRunL() |
|
1845 { |
|
1846 if (iFileNames.Count()) |
|
1847 { |
|
1848 for (TInt i = 0; i < iFileNames.Count(); i++) |
|
1849 { |
|
1850 TInt pos = 0; |
|
1851 const TFileName& fn = iFileNames[i]; |
|
1852 LeaveIfFileNotFound(fn); |
|
1853 RFile file; |
|
1854 User::LeaveIfError(file.Open(FsL(), fn, EFileRead)); |
|
1855 TBuf8<KBlockSize> buf; |
|
1856 TInt err = KErrNone; |
|
1857 if (iFileNames.Count() > 1) Printf(_L("%S:\r\n"), &fn); // For compatability don't print the file name if there's only one file |
|
1858 FOREVER |
|
1859 { |
|
1860 err = file.Read(buf); |
|
1861 if ((err == KErrNone) && (buf.Length() > 0)) |
|
1862 { |
|
1863 Dump(buf, *this, pos); |
|
1864 buf.Zero(); |
|
1865 } |
|
1866 else |
|
1867 { |
|
1868 break; |
|
1869 } |
|
1870 } |
|
1871 file.Close(); |
|
1872 } |
|
1873 } |
|
1874 else |
|
1875 { |
|
1876 TInt pos = 0; |
|
1877 RIoConsoleReadHandle& stdin = Stdin(); |
|
1878 if (iBinaryMode) |
|
1879 { |
|
1880 stdin.SetModeL(RIoReadWriteHandle::EBinary); |
|
1881 } |
|
1882 stdin.SetReadModeL(RIoReadHandle::EOneOrMore); |
|
1883 TBuf<KBlockSize> buf; |
|
1884 TInt err = KErrNone; |
|
1885 while (err == KErrNone) |
|
1886 { |
|
1887 err = stdin.Read(buf); |
|
1888 if (err == KErrNone) |
|
1889 { |
|
1890 Dump(TPtrC8((TUint8*)buf.Ptr(), buf.Length() * 2), *this, pos); |
|
1891 } |
|
1892 } |
|
1893 } |
|
1894 } |
|
1895 |
|
1896 void CCmdDump::OptionsL(RCommandOptionList& aOptions) |
|
1897 { |
|
1898 _LIT(KCmdDumpOptBinaryMode, "binary"); |
|
1899 aOptions.AppendBoolL(iBinaryMode, KCmdDumpOptBinaryMode); |
|
1900 } |
|
1901 |
|
1902 void CCmdDump::ArgumentsL(RCommandArgumentList& aArguments) |
|
1903 { |
|
1904 _LIT(KCmdDumpArg1, "file_name"); |
|
1905 aArguments.AppendFileNameL(iFileNames, KCmdDumpArg1); |
|
1906 } |
|
1907 |
|
1908 |
|
1909 // |
|
1910 // CCmdSleep. |
|
1911 // |
|
1912 |
|
1913 CCommandBase* CCmdSleep::NewLC() |
|
1914 { |
|
1915 CCmdSleep* self = new(ELeave) CCmdSleep(); |
|
1916 CleanupStack::PushL(self); |
|
1917 self->BaseConstructL(); |
|
1918 return self; |
|
1919 } |
|
1920 |
|
1921 CCmdSleep::~CCmdSleep() |
|
1922 { |
|
1923 } |
|
1924 |
|
1925 CCmdSleep::CCmdSleep() : CCommandBase(EManualComplete) |
|
1926 { |
|
1927 } |
|
1928 |
|
1929 const TDesC& CCmdSleep::Name() const |
|
1930 { |
|
1931 _LIT(KCmdSleepName, "sleep"); |
|
1932 return KCmdSleepName; |
|
1933 } |
|
1934 |
|
1935 void CCmdSleep::DoRunL() |
|
1936 { |
|
1937 if (iDuration > (KMaxTUint / 1000000)) |
|
1938 { |
|
1939 LeaveIfErr(KErrArgument, _L("Duration too large")); |
|
1940 } |
|
1941 |
|
1942 if (iDuration > 0) |
|
1943 { |
|
1944 User::After(iDuration * 1000000); |
|
1945 Complete(); |
|
1946 } |
|
1947 } |
|
1948 |
|
1949 void CCmdSleep::ArgumentsL(RCommandArgumentList& aArguments) |
|
1950 { |
|
1951 _LIT(KCmdSleepArg1, "duration"); |
|
1952 aArguments.AppendUintL(iDuration, KCmdSleepArg1); |
|
1953 } |
|
1954 |
|
1955 |
|
1956 // |
|
1957 // CCmdEnv. |
|
1958 // |
|
1959 |
|
1960 CCommandBase* CCmdEnv::NewLC() |
|
1961 { |
|
1962 CCmdEnv* self = new(ELeave) CCmdEnv(); |
|
1963 CleanupStack::PushL(self); |
|
1964 self->BaseConstructL(); |
|
1965 return self; |
|
1966 } |
|
1967 |
|
1968 CCmdEnv::~CCmdEnv() |
|
1969 { |
|
1970 } |
|
1971 |
|
1972 CCmdEnv::CCmdEnv() |
|
1973 { |
|
1974 } |
|
1975 |
|
1976 const TDesC& CCmdEnv::Name() const |
|
1977 { |
|
1978 _LIT(KCmdEnvName, "env"); |
|
1979 return KCmdEnvName; |
|
1980 } |
|
1981 |
|
1982 void CCmdEnv::DoRunL() |
|
1983 { |
|
1984 const IoUtils::CEnvironment& env = Env(); |
|
1985 |
|
1986 RPointerArray<HBufC> keys; |
|
1987 LtkUtils::CleanupResetAndDestroyPushL(keys); |
|
1988 env.GetKeysL(keys); |
|
1989 |
|
1990 const TInt numVars = keys.Count(); |
|
1991 for (TInt i = 0; i < numVars; ++i) |
|
1992 { |
|
1993 const TDesC& key = *keys[i]; |
|
1994 if (env.IsInt(key)) |
|
1995 { |
|
1996 Printf(_L("%S=%d\r\n"), &key, env.GetAsIntL(key)); |
|
1997 } |
|
1998 else if (env.IsDes(key)) |
|
1999 { |
|
2000 const TDesC& des = env.GetAsDesL(key); |
|
2001 Printf(_L("%S=%S\r\n"), &key, &des); |
|
2002 } |
|
2003 } |
|
2004 CleanupStack::PopAndDestroy(&keys); |
|
2005 } |
|
2006 |
|
2007 |
|
2008 // |
|
2009 // CCmdExport. |
|
2010 // |
|
2011 |
|
2012 CCommandBase* CCmdExport::NewLC() |
|
2013 { |
|
2014 CCmdExport* self = new(ELeave) CCmdExport(); |
|
2015 CleanupStack::PushL(self); |
|
2016 self->BaseConstructL(); |
|
2017 return self; |
|
2018 } |
|
2019 |
|
2020 CCmdExport::~CCmdExport() |
|
2021 { |
|
2022 delete iKey; |
|
2023 delete iVal; |
|
2024 } |
|
2025 |
|
2026 CCmdExport::CCmdExport() |
|
2027 { |
|
2028 } |
|
2029 |
|
2030 const TDesC& CCmdExport::Name() const |
|
2031 { |
|
2032 _LIT(KCmdExportName, "export"); |
|
2033 return KCmdExportName; |
|
2034 } |
|
2035 |
|
2036 void CCmdExport::DoRunL() |
|
2037 { |
|
2038 if (iStdin) |
|
2039 { |
|
2040 if (iVal) |
|
2041 { |
|
2042 Complete(KErrArgument, _L("You can only specify one of --stdin or <value>")); |
|
2043 return; |
|
2044 } |
|
2045 |
|
2046 Stdin().SetReadModeL(RIoReadHandle::EFull); |
|
2047 TInt err = Stdin().Read(iBuf); |
|
2048 if (err == KErrEof) |
|
2049 { |
|
2050 Env().SetL(*iKey, KNullDesC); |
|
2051 } |
|
2052 else |
|
2053 { |
|
2054 LeaveIfErr(err, _L("Couldn't read from stdin")); |
|
2055 Env().SetL(*iKey, iBuf); |
|
2056 } |
|
2057 } |
|
2058 else if (iVal) |
|
2059 { |
|
2060 Env().SetL(*iKey, *iVal); |
|
2061 } |
|
2062 else |
|
2063 { |
|
2064 Env().RemoveL(*iKey); |
|
2065 } |
|
2066 } |
|
2067 |
|
2068 void CCmdExport::OptionsL(RCommandOptionList& aOptions) |
|
2069 { |
|
2070 _LIT(KCmdExportOptStdin, "stdin"); |
|
2071 aOptions.AppendBoolL(iStdin, KCmdExportOptStdin); |
|
2072 } |
|
2073 |
|
2074 void CCmdExport::ArgumentsL(RCommandArgumentList& aArguments) |
|
2075 { |
|
2076 _LIT(KCmdExportArg1, "variable"); |
|
2077 _LIT(KCmdExportArg2, "value"); |
|
2078 aArguments.AppendStringL(iKey, KCmdExportArg1); |
|
2079 aArguments.AppendStringL(iVal, KCmdExportArg2); |
|
2080 } |
|
2081 |
|
2082 |
|
2083 // |
|
2084 // CCmdSort. |
|
2085 // |
|
2086 |
|
2087 CCommandBase* CCmdSort::NewLC() |
|
2088 { |
|
2089 CCmdSort* self = new(ELeave) CCmdSort(); |
|
2090 CleanupStack::PushL(self); |
|
2091 self->BaseConstructL(); |
|
2092 return self; |
|
2093 } |
|
2094 |
|
2095 CCmdSort::~CCmdSort() |
|
2096 { |
|
2097 } |
|
2098 |
|
2099 CCmdSort::CCmdSort() |
|
2100 { |
|
2101 } |
|
2102 |
|
2103 const TDesC& CCmdSort::Name() const |
|
2104 { |
|
2105 _LIT(KCmdSortName, "sort"); |
|
2106 return KCmdSortName; |
|
2107 } |
|
2108 |
|
2109 TInt ComparePtrs(const TPtrC& aPtr1, const TPtrC& aPtr2) |
|
2110 { |
|
2111 return aPtr1.Compare(aPtr2); |
|
2112 } |
|
2113 |
|
2114 void CCmdSort::DoRunL() |
|
2115 { |
|
2116 // Read all input into a buffer. |
|
2117 CTextBuffer* buffer = CTextBuffer::NewLC(0x100); |
|
2118 Stdin().SetReadMode(RIoReadHandle::EOneOrMore); |
|
2119 TBuf<0x100> buf; |
|
2120 while (Stdin().Read(buf) == KErrNone) |
|
2121 { |
|
2122 buffer->AppendL(buf); |
|
2123 } |
|
2124 |
|
2125 // Populate an ordered list of lines. |
|
2126 RArray<TPtrC> sortedLines; |
|
2127 CleanupClosePushL(sortedLines); |
|
2128 TPtrC ptr(buffer->Descriptor()); |
|
2129 FOREVER |
|
2130 { |
|
2131 TInt pos = ptr.Find(KNewLine); |
|
2132 if (pos >= 0) |
|
2133 { |
|
2134 pos += KNewLine().Length(); |
|
2135 TPtrC line(ptr.Left(pos)); |
|
2136 User::LeaveIfError(sortedLines.InsertInOrderAllowRepeats(line, TLinearOrder<TPtrC>(ComparePtrs))); |
|
2137 if (pos < (ptr.Length() - 1)) |
|
2138 { |
|
2139 ptr.Set(ptr.Mid(pos)); |
|
2140 } |
|
2141 else |
|
2142 { |
|
2143 break; |
|
2144 } |
|
2145 } |
|
2146 else |
|
2147 { |
|
2148 User::LeaveIfError(sortedLines.InsertInOrderAllowRepeats(ptr, TLinearOrder<TPtrC>(ComparePtrs))); |
|
2149 break; |
|
2150 } |
|
2151 } |
|
2152 |
|
2153 // Output the ordered list of lines. |
|
2154 const TInt numLines = sortedLines.Count(); |
|
2155 if (iReverse) |
|
2156 { |
|
2157 for (TInt i = (numLines - 1); i >= 0; --i) |
|
2158 { |
|
2159 Write(sortedLines[i]); |
|
2160 } |
|
2161 } |
|
2162 else |
|
2163 { |
|
2164 for (TInt i = 0; i < numLines; ++i) |
|
2165 { |
|
2166 Write(sortedLines[i]); |
|
2167 } |
|
2168 } |
|
2169 |
|
2170 CleanupStack::PopAndDestroy(2, buffer); |
|
2171 } |
|
2172 |
|
2173 void CCmdSort::OptionsL(RCommandOptionList& aOptions) |
|
2174 { |
|
2175 _LIT(KCmdSortOptReverse, "reverse"); |
|
2176 aOptions.AppendBoolL(iReverse, KCmdSortOptReverse); |
|
2177 } |
|
2178 |
|
2179 |
|
2180 // |
|
2181 // CCmdExists. |
|
2182 // |
|
2183 |
|
2184 CCommandBase* CCmdExists::NewLC() |
|
2185 { |
|
2186 CCmdExists* self = new(ELeave) CCmdExists(); |
|
2187 CleanupStack::PushL(self); |
|
2188 self->BaseConstructL(); |
|
2189 return self; |
|
2190 } |
|
2191 |
|
2192 CCmdExists::~CCmdExists() |
|
2193 { |
|
2194 } |
|
2195 |
|
2196 CCmdExists::CCmdExists() |
|
2197 { |
|
2198 } |
|
2199 |
|
2200 const TDesC& CCmdExists::Name() const |
|
2201 { |
|
2202 _LIT(KCmdExistsName, "exists"); |
|
2203 return KCmdExistsName; |
|
2204 } |
|
2205 |
|
2206 void CCmdExists::DoRunL() |
|
2207 { |
|
2208 TUint att; |
|
2209 Complete(!(FsL().Att(iFileName, att) == KErrNone)); |
|
2210 } |
|
2211 |
|
2212 void CCmdExists::ArgumentsL(RCommandArgumentList& aArguments) |
|
2213 { |
|
2214 _LIT(KCmdExistsArg, "file_name"); |
|
2215 aArguments.AppendFileNameL(iFileName, KCmdExistsArg); |
|
2216 } |
|
2217 |
|
2218 |
|
2219 // |
|
2220 // CCmdInfoPrint. |
|
2221 // |
|
2222 |
|
2223 CCommandBase* CCmdInfoPrint::NewLC() |
|
2224 { |
|
2225 CCmdInfoPrint* self = new(ELeave) CCmdInfoPrint(); |
|
2226 CleanupStack::PushL(self); |
|
2227 self->BaseConstructL(); |
|
2228 return self; |
|
2229 } |
|
2230 |
|
2231 CCmdInfoPrint::~CCmdInfoPrint() |
|
2232 { |
|
2233 delete iToPrint; |
|
2234 } |
|
2235 |
|
2236 CCmdInfoPrint::CCmdInfoPrint() |
|
2237 { |
|
2238 } |
|
2239 |
|
2240 const TDesC& CCmdInfoPrint::Name() const |
|
2241 { |
|
2242 _LIT(KCmdInfoPrintName, "infoprint"); |
|
2243 return KCmdInfoPrintName; |
|
2244 } |
|
2245 |
|
2246 void CCmdInfoPrint::DoRunL() |
|
2247 { |
|
2248 if (!iToPrint) |
|
2249 { |
|
2250 TBuf<0x100> toPrint; |
|
2251 Stdin().SetReadModeL(RIoReadHandle::EFull); |
|
2252 Stdin().Read(toPrint); |
|
2253 // remove a newline from the end, if one exists |
|
2254 if ((toPrint.Length() > 0) && (toPrint[toPrint.Length()-1] == '\n')) |
|
2255 { |
|
2256 toPrint.SetLength(toPrint.Length()-1); |
|
2257 if ((toPrint.Length() > 0) && (toPrint[toPrint.Length()-1] == '\r')) |
|
2258 { |
|
2259 toPrint.SetLength(toPrint.Length()-1); |
|
2260 } |
|
2261 } |
|
2262 User::InfoPrint(toPrint); |
|
2263 } |
|
2264 else |
|
2265 { |
|
2266 User::InfoPrint(*iToPrint); |
|
2267 } |
|
2268 } |
|
2269 |
|
2270 void CCmdInfoPrint::ArgumentsL(RCommandArgumentList& aArguments) |
|
2271 { |
|
2272 _LIT(KCmdInfoPrintArg, "message"); |
|
2273 aArguments.AppendStringL(iToPrint, KCmdInfoPrintArg); |
|
2274 } |
|
2275 |
|
2276 |
|
2277 // |
|
2278 // CCmdRDebug. |
|
2279 // |
|
2280 |
|
2281 CCommandBase* CCmdRDebug::NewLC() |
|
2282 { |
|
2283 CCmdRDebug* self = new(ELeave) CCmdRDebug(); |
|
2284 CleanupStack::PushL(self); |
|
2285 self->BaseConstructL(); |
|
2286 return self; |
|
2287 } |
|
2288 |
|
2289 CCmdRDebug::~CCmdRDebug() |
|
2290 { |
|
2291 delete iToPrint; |
|
2292 } |
|
2293 |
|
2294 CCmdRDebug::CCmdRDebug() |
|
2295 { |
|
2296 } |
|
2297 |
|
2298 const TDesC& CCmdRDebug::Name() const |
|
2299 { |
|
2300 _LIT(KCmdRDebugName, "rdebug"); |
|
2301 return KCmdRDebugName; |
|
2302 } |
|
2303 |
|
2304 void CCmdRDebug::DoRunL() |
|
2305 { |
|
2306 if (iToPrint) |
|
2307 { |
|
2308 RDebug::Print(*iToPrint); |
|
2309 } |
|
2310 else |
|
2311 { |
|
2312 RIoConsoleReadHandle& stdin = Stdin(); |
|
2313 stdin.SetReadModeL(RIoReadHandle::ELine); |
|
2314 TBuf<512> buf; |
|
2315 TInt err = KErrNone; |
|
2316 while (err == KErrNone) |
|
2317 { |
|
2318 err = stdin.Read(buf); |
|
2319 if (err == KErrNone) |
|
2320 { |
|
2321 RDebug::Print(buf); |
|
2322 } |
|
2323 } |
|
2324 } |
|
2325 } |
|
2326 |
|
2327 void CCmdRDebug::ArgumentsL(RCommandArgumentList& aArguments) |
|
2328 { |
|
2329 _LIT(KCmdRDebugArg, "message"); |
|
2330 aArguments.AppendStringL(iToPrint, KCmdRDebugArg); |
|
2331 } |
|
2332 |
|
2333 |
|
2334 // |
|
2335 // CCmdDate. |
|
2336 // |
|
2337 |
|
2338 CCommandBase* CCmdDate::NewLC() |
|
2339 { |
|
2340 CCmdDate* self = new(ELeave) CCmdDate(); |
|
2341 CleanupStack::PushL(self); |
|
2342 self->BaseConstructL(); |
|
2343 return self; |
|
2344 } |
|
2345 |
|
2346 CCmdDate::~CCmdDate() |
|
2347 { |
|
2348 delete iDateToSet; |
|
2349 } |
|
2350 |
|
2351 CCmdDate::CCmdDate() |
|
2352 { |
|
2353 } |
|
2354 |
|
2355 void CCmdDate::Display(const TTime& aTime) |
|
2356 { |
|
2357 if (iRaw) |
|
2358 { |
|
2359 Printf(_L("%Ld\r\n"), aTime.Int64()); |
|
2360 } |
|
2361 else if (iUseTimestampFormat) |
|
2362 { |
|
2363 TDateTime dateTime(aTime.DateTime()); |
|
2364 Printf(_L("%04d%02d%02d-%02d%02d.%02d"), dateTime.Year(), dateTime.Month() + 1, dateTime.Day() + 1, dateTime.Hour(), dateTime.Minute(), dateTime.Second()); |
|
2365 } |
|
2366 else |
|
2367 { |
|
2368 TDateTime dateTime(aTime.DateTime()); |
|
2369 Printf(_L("%+02d/%+02d/%+04d %+02d:%+02d:%+02d.%+06d\r\n"), dateTime.Day() + 1, dateTime.Month() + 1, dateTime.Year(), dateTime.Hour(), dateTime.Minute(), dateTime.Second(), dateTime.MicroSecond()); |
|
2370 } |
|
2371 } |
|
2372 |
|
2373 const TDesC& CCmdDate::Name() const |
|
2374 { |
|
2375 _LIT(KCmdDateName, "date"); |
|
2376 return KCmdDateName; |
|
2377 } |
|
2378 |
|
2379 void CCmdDate::DoRunL() |
|
2380 { |
|
2381 if (!iDateToSet && !iOptions.IsPresent(&iRawTimeToSet)) |
|
2382 { |
|
2383 TTime time; |
|
2384 if (iUniversalTime) |
|
2385 { |
|
2386 #ifdef FSHELL_CORE_SUPPORT_SECURE_TIME |
|
2387 if (iSecure) |
|
2388 { |
|
2389 LeaveIfErr(time.UniversalTimeSecure(), _L("Unable to get secure universal time")); |
|
2390 } |
|
2391 else |
|
2392 #endif |
|
2393 { |
|
2394 time.UniversalTime(); |
|
2395 } |
|
2396 } |
|
2397 else |
|
2398 { |
|
2399 #ifdef FSHELL_CORE_SUPPORT_SECURE_TIME |
|
2400 if (iSecure) |
|
2401 { |
|
2402 LeaveIfErr(time.HomeTimeSecure(), _L("Unable to get secure home time")); |
|
2403 } |
|
2404 else |
|
2405 #endif |
|
2406 { |
|
2407 time.HomeTime(); |
|
2408 } |
|
2409 } |
|
2410 Display(time); |
|
2411 } |
|
2412 else |
|
2413 { |
|
2414 _LIT(KSettingError, "Cannot set the time"); |
|
2415 TTime time(iRawTimeToSet); |
|
2416 if (iDateToSet) |
|
2417 { |
|
2418 _LIT(KParsingTime, "Cannot parse time string"); |
|
2419 LeaveIfErr(time.Parse(*iDateToSet), KParsingTime); |
|
2420 } |
|
2421 if (iJustDisplay) |
|
2422 { |
|
2423 Display(time); |
|
2424 } |
|
2425 else |
|
2426 { |
|
2427 if (iUniversalTime) |
|
2428 { |
|
2429 #ifdef FSHELL_CORE_SUPPORT_SECURE_TIME |
|
2430 if (iSecure) |
|
2431 { |
|
2432 LeaveIfErr(User::SetUTCTimeSecure(time), KSettingError); |
|
2433 } |
|
2434 else |
|
2435 #endif |
|
2436 { |
|
2437 LeaveIfErr(User::SetUTCTime(time), KSettingError); |
|
2438 } |
|
2439 } |
|
2440 else |
|
2441 { |
|
2442 #ifdef FSHELL_CORE_SUPPORT_SECURE_TIME |
|
2443 if (iSecure) |
|
2444 { |
|
2445 LeaveIfErr(User::SetHomeTimeSecure(time), KSettingError); |
|
2446 } |
|
2447 else |
|
2448 #endif |
|
2449 { |
|
2450 LeaveIfErr(User::SetHomeTime(time), KSettingError); |
|
2451 } |
|
2452 } |
|
2453 if (iOptions.IsPresent(&iUtcOffset)) |
|
2454 { |
|
2455 User::SetUTCOffset(TTimeIntervalSeconds(iUtcOffset)); |
|
2456 } |
|
2457 } |
|
2458 } |
|
2459 } |
|
2460 |
|
2461 void CCmdDate::OptionsL(RCommandOptionList& aOptions) |
|
2462 { |
|
2463 _LIT(KCmdDateOptUniversal, "universal"); |
|
2464 _LIT(KCmdDateOptSet, "set"); |
|
2465 _LIT(KCmdDateOptUtcOffset, "utc-offset"); |
|
2466 #ifdef FSHELL_CORE_SUPPORT_SECURE_TIME |
|
2467 _LIT(KCmdDateOptSecure, "secure"); |
|
2468 #endif |
|
2469 _LIT(KCmdDateOptRaw, "raw"); |
|
2470 _LIT(KCmdDateOptJustDisplay, "just-display"); |
|
2471 _LIT(KCmdDateOptSetRaw, "raw-set"); |
|
2472 _LIT(KCmdDataOptTimestamp, "timestamp"); |
|
2473 |
|
2474 aOptions.AppendBoolL(iUniversalTime, KCmdDateOptUniversal); |
|
2475 aOptions.AppendStringL(iDateToSet, KCmdDateOptSet); |
|
2476 aOptions.AppendIntL(iUtcOffset, KCmdDateOptUtcOffset); |
|
2477 #ifdef FSHELL_CORE_SUPPORT_SECURE_TIME |
|
2478 aOptions.AppendBoolL(iSecure, KCmdDateOptSecure); |
|
2479 #endif |
|
2480 aOptions.AppendBoolL(iRaw, KCmdDateOptRaw); |
|
2481 aOptions.AppendBoolL(iJustDisplay, KCmdDateOptJustDisplay); |
|
2482 aOptions.AppendIntL(iRawTimeToSet, KCmdDateOptSetRaw); |
|
2483 aOptions.AppendBoolL(iUseTimestampFormat, KCmdDataOptTimestamp); |
|
2484 } |
|
2485 |
|
2486 |
|
2487 // |
|
2488 // CCmdFsck. |
|
2489 // |
|
2490 |
|
2491 CCommandBase* CCmdFsck::NewLC() |
|
2492 { |
|
2493 CCmdFsck* self = new(ELeave) CCmdFsck(); |
|
2494 CleanupStack::PushL(self); |
|
2495 self->BaseConstructL(); |
|
2496 return self; |
|
2497 } |
|
2498 |
|
2499 CCmdFsck::~CCmdFsck() |
|
2500 { |
|
2501 delete iDriveLetter; |
|
2502 } |
|
2503 |
|
2504 CCmdFsck::CCmdFsck() |
|
2505 { |
|
2506 } |
|
2507 |
|
2508 const TDesC& CCmdFsck::Name() const |
|
2509 { |
|
2510 _LIT(KCmdFsckName, "fsck"); |
|
2511 return KCmdFsckName; |
|
2512 } |
|
2513 |
|
2514 void CCmdFsck::DoRunL() |
|
2515 { |
|
2516 TInt ret = FsL().CheckDisk(*iDriveLetter); |
|
2517 |
|
2518 switch (ret) |
|
2519 { |
|
2520 case KErrNotSupported: |
|
2521 Printf(_L("Not supported\r\n")); |
|
2522 break; |
|
2523 case 0: |
|
2524 Printf(_L("No errors\r\n")); |
|
2525 break; |
|
2526 case 1: |
|
2527 Printf(_L("Error: File cluster chain contains a bad value (<2 or >maxCluster)\r\n")); |
|
2528 break; |
|
2529 case 2: |
|
2530 Printf(_L("Error: Two files are linked to the same cluster\r\n")); |
|
2531 break; |
|
2532 case 3: |
|
2533 Printf(_L("Error: Unallocated cluster contains a value != 0\r\n")); |
|
2534 break; |
|
2535 case 4: |
|
2536 Printf(_L("Error: Size of file != number of clusters in chain\r\n")); |
|
2537 break; |
|
2538 default: |
|
2539 Printf(_L("Error: %d\r\n"), ret); |
|
2540 } |
|
2541 |
|
2542 User::LeaveIfError(ret); |
|
2543 } |
|
2544 |
|
2545 void CCmdFsck::ArgumentsL(RCommandArgumentList& aArguments) |
|
2546 { |
|
2547 _LIT(KCmdFsckArg, "drive_letter"); |
|
2548 aArguments.AppendStringL(iDriveLetter, KCmdFsckArg); |
|
2549 } |
|
2550 |
|
2551 |
|
2552 // |
|
2553 // CCmdDriver. |
|
2554 // |
|
2555 |
|
2556 CCommandBase* CCmdDriver::NewLC() |
|
2557 { |
|
2558 CCmdDriver* self = new(ELeave) CCmdDriver(); |
|
2559 CleanupStack::PushL(self); |
|
2560 self->BaseConstructL(); |
|
2561 return self; |
|
2562 } |
|
2563 |
|
2564 CCmdDriver::~CCmdDriver() |
|
2565 { |
|
2566 delete iDriverName; |
|
2567 } |
|
2568 |
|
2569 CCmdDriver::CCmdDriver() |
|
2570 { |
|
2571 } |
|
2572 |
|
2573 const TDesC& CCmdDriver::Name() const |
|
2574 { |
|
2575 _LIT(KCmdDriverName, "driver"); |
|
2576 return KCmdDriverName; |
|
2577 } |
|
2578 |
|
2579 void CCmdDriver::DoRunL() |
|
2580 { |
|
2581 TInt err = KErrNone; |
|
2582 switch (iOperation) |
|
2583 { |
|
2584 case ELoad: |
|
2585 { |
|
2586 if (iType == ELogical) |
|
2587 { |
|
2588 err = User::LoadLogicalDevice(*iDriverName); |
|
2589 } |
|
2590 else |
|
2591 { |
|
2592 err = User::LoadPhysicalDevice(*iDriverName); |
|
2593 } |
|
2594 break; |
|
2595 } |
|
2596 case EFree: |
|
2597 { |
|
2598 if (iType == ELogical) |
|
2599 { |
|
2600 err = User::FreeLogicalDevice(*iDriverName); |
|
2601 } |
|
2602 else |
|
2603 { |
|
2604 err = User::FreePhysicalDevice(*iDriverName); |
|
2605 } |
|
2606 break; |
|
2607 } |
|
2608 case EFind: |
|
2609 { |
|
2610 if (iType == ELogical) |
|
2611 { |
|
2612 TFindLogicalDevice findLogicalDevice; |
|
2613 TFullName name; |
|
2614 while (findLogicalDevice.Next(name) == KErrNone) |
|
2615 { |
|
2616 Printf(_L("%S\r\n"), &name); |
|
2617 } |
|
2618 } |
|
2619 else |
|
2620 { |
|
2621 TFindPhysicalDevice findPhysicalDevice; |
|
2622 TFullName name; |
|
2623 while (findPhysicalDevice.Next(name) == KErrNone) |
|
2624 { |
|
2625 Printf(_L("%S\r\n"), &name); |
|
2626 } |
|
2627 } |
|
2628 break; |
|
2629 } |
|
2630 default: |
|
2631 { |
|
2632 ASSERT(EFalse); |
|
2633 break; |
|
2634 } |
|
2635 } |
|
2636 |
|
2637 if (err) |
|
2638 { |
|
2639 TPtrC operation(iArguments.AsString(&iOperation)); |
|
2640 TPtrC type(iArguments.AsString(&iType)); |
|
2641 PrintError(err, _L("Unable to %S %S device"), &operation, &type); |
|
2642 User::Leave(err); |
|
2643 } |
|
2644 } |
|
2645 |
|
2646 void CCmdDriver::ArgumentsL(RCommandArgumentList& aArguments) |
|
2647 { |
|
2648 _LIT(KCmdDriverArg1, "operation"); |
|
2649 _LIT(KCmdDriverArg2, "type"); |
|
2650 _LIT(KCmdDriverArg3, "name"); |
|
2651 |
|
2652 aArguments.AppendEnumL((TInt&)iOperation, KCmdDriverArg1); |
|
2653 aArguments.AppendEnumL((TInt&)iType, KCmdDriverArg2); |
|
2654 aArguments.AppendStringL(iDriverName, KCmdDriverArg3); |
|
2655 } |
|
2656 |
|
2657 |
|
2658 // |
|
2659 // CCmdChunkInfo. |
|
2660 // |
|
2661 |
|
2662 CCommandBase* CCmdChunkInfo::NewLC() |
|
2663 { |
|
2664 CCmdChunkInfo* self = new(ELeave) CCmdChunkInfo(); |
|
2665 CleanupStack::PushL(self); |
|
2666 self->BaseConstructL(); |
|
2667 return self; |
|
2668 } |
|
2669 |
|
2670 CCmdChunkInfo::~CCmdChunkInfo() |
|
2671 { |
|
2672 delete iOwningProcess; |
|
2673 delete iBuf; |
|
2674 delete iFormatter; |
|
2675 } |
|
2676 |
|
2677 CCmdChunkInfo::CCmdChunkInfo() |
|
2678 { |
|
2679 } |
|
2680 |
|
2681 void CCmdChunkInfo::ListChunksL() |
|
2682 { |
|
2683 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
2684 TInt bufSize = 1024; |
|
2685 TInt err = KErrNone; |
|
2686 HBufC8* addressesBuf; |
|
2687 do |
|
2688 { |
|
2689 addressesBuf = HBufC8::NewLC(bufSize); |
|
2690 TPtr8 addressesPtr(addressesBuf->Des()); |
|
2691 if (iControllingProcess != 0) |
|
2692 { |
|
2693 err = iMemAccess.GetChunkAddresses(iControllingProcess, addressesPtr); |
|
2694 } |
|
2695 else |
|
2696 { |
|
2697 err = iMemAccess.GetObjectAddresses(EChunk, iOwningProcess ? *iOwningProcess : KNullDesC(), addressesPtr); |
|
2698 } |
|
2699 if (err == KErrOverflow) |
|
2700 { |
|
2701 CleanupStack::PopAndDestroy(addressesBuf); |
|
2702 bufSize *= 2; |
|
2703 } |
|
2704 } |
|
2705 while (err == KErrOverflow); |
|
2706 |
|
2707 if (err) |
|
2708 { |
|
2709 PrintError(err, _L("Unable to read chunk addresses.")); |
|
2710 User::Leave(err); |
|
2711 } |
|
2712 |
|
2713 const TInt numAddresses = addressesBuf->Length() / sizeof(TUint32*); |
|
2714 if (numAddresses == 0) |
|
2715 { |
|
2716 Write(_L("No chunks found.\r\n")); |
|
2717 } |
|
2718 else |
|
2719 { |
|
2720 TUint32* p = (TUint32*)addressesBuf->Ptr(); |
|
2721 TInt offset = 0; |
|
2722 while (offset < numAddresses) |
|
2723 { |
|
2724 TChunkKernelInfo chunkInfo; |
|
2725 TPckg<TChunkKernelInfo> chunkInfoPckg(chunkInfo); |
|
2726 TUint32* ptr = p + offset++; |
|
2727 err = iMemAccess.GetObjectInfo(EChunk, (TUint8*)(*ptr), chunkInfoPckg); |
|
2728 if (err == KErrNone) |
|
2729 { |
|
2730 iFullName.Copy(chunkInfo.iFullName); |
|
2731 if (iIncludeSize) |
|
2732 { |
|
2733 iBuf->AppendFormatL(_L("0x%08x\t"), *ptr); |
|
2734 if (iHumanReadable) |
|
2735 { |
|
2736 iBuf->AppendHumanReadableSizeL(chunkInfo.iSize, EUnaligned); |
|
2737 iBuf->AppendFormatL(KTab); |
|
2738 } |
|
2739 else |
|
2740 { |
|
2741 iBuf->AppendFormatL(_L("%d\t"), chunkInfo.iSize); |
|
2742 } |
|
2743 iBuf->AppendFormatL(_L("\'%S\'\r\n"), &iFullName); |
|
2744 } |
|
2745 else |
|
2746 { |
|
2747 iBuf->AppendFormatL(_L("0x%08x\t\'%S\'\r\n"), *ptr, &iFullName); |
|
2748 } |
|
2749 } |
|
2750 else if (err != KErrNotFound) |
|
2751 { |
|
2752 // Only abort on something other than KErrNotFound. KErrNotFound could legitimately |
|
2753 // happen if the chunk in question has been deleted since we called RMemoryAccess::GetObjectAddresses. |
|
2754 PrintError(err, _L("Unable to read chunk at 0x%08x, aborting."), ptr); |
|
2755 User::Leave(err); |
|
2756 } |
|
2757 } |
|
2758 } |
|
2759 |
|
2760 CleanupStack::PopAndDestroy(addressesBuf); |
|
2761 #endif |
|
2762 } |
|
2763 |
|
2764 void CCmdChunkInfo::PrintChunkInfoL() |
|
2765 { |
|
2766 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
2767 TChunkKernelInfo chunkInfo; |
|
2768 TPckg<TChunkKernelInfo> chunkInfoPckg(chunkInfo); |
|
2769 TInt err = iMemAccess.GetObjectInfo(EChunk, (TUint8*)iAddress, chunkInfoPckg); |
|
2770 if (err) |
|
2771 { |
|
2772 PrintError(err, _L("Unable to get info for chunk 0x%08x"), iAddress); |
|
2773 User::Leave(err); |
|
2774 } |
|
2775 else |
|
2776 { |
|
2777 iFullName.Copy(chunkInfo.iFullName); |
|
2778 iBuf->AppendFormatL(_L("Name:\t\'%S\'\r\n"), &iFullName); |
|
2779 iBuf->AppendFormatL(_L("Base:\t0x%08x\r\n"), chunkInfo.iBase); |
|
2780 PrintSizeL(_L("Max size:\t"), chunkInfo.iMaxSize); |
|
2781 PrintSizeL(_L("Current size:\t"), chunkInfo.iSize); |
|
2782 iBuf->AppendFormatL(_L("Attributes:\t0x%08x\r\n"), chunkInfo.iAttributes); |
|
2783 iBuf->AppendFormatL(_L("Type:\t0x%08x\r\n"), chunkInfo.iChunkType); |
|
2784 iBuf->AppendFormatL(_L("Restrictions:\t0x%08x\r\n"), chunkInfo.iRestrictions); |
|
2785 |
|
2786 RProcess process; |
|
2787 TInt err = process.Open(chunkInfo.iControllingOwnerProcessId); |
|
2788 if (err == KErrNone) |
|
2789 { |
|
2790 iName = process.Name(); |
|
2791 process.Close(); |
|
2792 iBuf->AppendFormatL(_L("Controlling process:\t\'%S\' (%u)\r\n"), &iName, chunkInfo.iControllingOwnerProcessId); |
|
2793 LtkUtils::RProxyAllocatorHelper allocHelper; |
|
2794 CleanupClosePushL(allocHelper); |
|
2795 err = allocHelper.OpenChunkHeap(iMemAccess, (TAny*)iAddress); |
|
2796 if (err == KErrNone) |
|
2797 { |
|
2798 iBuf->AppendFormatL(_L("Allocator type:\t%S\r\n"), &allocHelper.Description()); |
|
2799 PrintSizeL(_L("Heap size:\t"), allocHelper.CommittedSize()); |
|
2800 PrintSizeL(_L("Heap max size:\t"), allocHelper.MaxCommittedSize()); |
|
2801 iBuf->AppendFormatL(_L("Alloc count:\t%d\r\n"), allocHelper.AllocationCount()); |
|
2802 PrintSizeL(_L("Total alloc size:\t"), allocHelper.AllocatedSize()); |
|
2803 TReal overheadRatio = ((allocHelper.CommittedSize() - allocHelper.AllocatedSize() - allocHelper.CommittedFreeSpace()) * 100) / (TReal)allocHelper.CommittedSize(); |
|
2804 iBuf->AppendFormatL(_L("Metadata overhead:\t%00.2f%%\r\n"), overheadRatio); |
|
2805 TInt val = allocHelper.SizeForCellType(RAllocatorHelper::EDlaAllocation); |
|
2806 if (val >= 0) |
|
2807 { |
|
2808 PrintSizeL(_L("DL alloc size:\t"), val); |
|
2809 iBuf->AppendFormatL(_L("DL alloc count:\t%d\r\n"), allocHelper.CountForCellType(RAllocatorHelper::EDlaAllocation)); |
|
2810 PrintSizeL(_L("DL free size:\t"), allocHelper.SizeForCellType(RAllocatorHelper::EDlaFreeCell)); |
|
2811 iBuf->AppendFormatL(_L("DL free cell count:\t%d\r\n"), allocHelper.CountForCellType(RAllocatorHelper::EDlaFreeCell)); |
|
2812 PrintSizeL(_L("Paged alloc size:\t"), allocHelper.SizeForCellType(RAllocatorHelper::EPageAllocation)); |
|
2813 iBuf->AppendFormatL(_L("Paged alloc count:\t%d\r\n"), allocHelper.CountForCellType(RAllocatorHelper::EPageAllocation)); |
|
2814 PrintSizeL(_L("Slab alloc size:\t"), allocHelper.SizeForCellType(RAllocatorHelper::ESlabAllocation)); |
|
2815 iBuf->AppendFormatL(_L("Slab alloc count:\t%d\r\n"), allocHelper.CountForCellType(RAllocatorHelper::ESlabAllocation)); |
|
2816 PrintSizeL(_L("Slab free size:\t"), allocHelper.SizeForCellType(RAllocatorHelper::ESlabFreeCell)); |
|
2817 iBuf->AppendFormatL(_L("Slab free cell count:\t%d\r\n"), allocHelper.CountForCellType(RAllocatorHelper::ESlabFreeCell)); |
|
2818 PrintSizeL(_L("Unused slabs size:\t"), allocHelper.SizeForCellType(RAllocatorHelper::ESlabFreeSlab)); |
|
2819 iBuf->AppendFormatL(_L("Unused slabs count:\t%d\r\n"), allocHelper.CountForCellType(RAllocatorHelper::ESlabFreeSlab)); |
|
2820 } |
|
2821 else if (val != KErrNotSupported) |
|
2822 { |
|
2823 iBuf->AppendFormatL(_L("\t[Error %d returned from heap stats]\r\n"), val); |
|
2824 } |
|
2825 } |
|
2826 else |
|
2827 { |
|
2828 iBuf->AppendL(_L("\t[RHeap allocator not found]\r\n")); |
|
2829 } |
|
2830 CleanupStack::PopAndDestroy(&allocHelper); |
|
2831 } |
|
2832 if (err) |
|
2833 { |
|
2834 PrintWarning(_L("Unable to read RHeap info: %d"), err); |
|
2835 } |
|
2836 } |
|
2837 #endif |
|
2838 } |
|
2839 |
|
2840 void CCmdChunkInfo::PrintSizeL(const TDesC& aCaption, TInt aSize) |
|
2841 { |
|
2842 if (iHumanReadable) |
|
2843 { |
|
2844 iBuf->AppendL(aCaption); |
|
2845 iBuf->AppendHumanReadableSizeL(aSize, EUnaligned); |
|
2846 iBuf->AppendL(KNewLine); |
|
2847 } |
|
2848 else |
|
2849 { |
|
2850 _LIT(KFormat, "%S%d\r\n"); |
|
2851 iBuf->AppendFormatL(KFormat, &aCaption, aSize); |
|
2852 } |
|
2853 } |
|
2854 |
|
2855 const TDesC& CCmdChunkInfo::Name() const |
|
2856 { |
|
2857 _LIT(KCmdChunkInfoName, "chunkinfo"); |
|
2858 return KCmdChunkInfoName; |
|
2859 } |
|
2860 |
|
2861 void CCmdChunkInfo::DoPrintL() |
|
2862 { |
|
2863 iBuf->Zero(); |
|
2864 iFormatter->Zero(); |
|
2865 |
|
2866 if (iAddress == 0) |
|
2867 { |
|
2868 ListChunksL(); |
|
2869 } |
|
2870 else |
|
2871 { |
|
2872 PrintChunkInfoL(); |
|
2873 } |
|
2874 |
|
2875 iFormatter->TabulateL(0, 2, iBuf->Descriptor(), ETruncateLongestColumn); |
|
2876 Write(iFormatter->Descriptor()); |
|
2877 } |
|
2878 |
|
2879 void CCmdChunkInfo::DoRunL() |
|
2880 { |
|
2881 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
2882 iFormatter = CTextFormatter::NewL(Stdout()); |
|
2883 iBuf = IoUtils::CTextBuffer::NewL(0x100); |
|
2884 LoadMemoryAccessL(); |
|
2885 |
|
2886 RIoConsoleWriteHandle stdout = Stdout(); |
|
2887 TBool attachedToConsole(stdout.AttachedToConsole()); |
|
2888 if (attachedToConsole && iUpdateRate && iAddress) |
|
2889 { |
|
2890 stdout.SetCursorHeight(0); |
|
2891 stdout.ClearScreen(); |
|
2892 } |
|
2893 |
|
2894 DoPrintL(); |
|
2895 |
|
2896 if (iUpdateRate && iAddress) |
|
2897 { |
|
2898 FOREVER |
|
2899 { |
|
2900 User::After(iUpdateRate * 1000); |
|
2901 if (attachedToConsole) |
|
2902 { |
|
2903 stdout.ClearScreen(); |
|
2904 } |
|
2905 DoPrintL(); |
|
2906 } |
|
2907 } |
|
2908 #else |
|
2909 PrintError(KErrNotSupported, _L("Unable to fetch chunk information because fshell was not built with FSHELL_MEMORY_ACCESS_SUPPORT defined. That probably means this plaform doesn't support the MemoryAccess device driver.")); |
|
2910 User::Leave(KErrNotSupported); |
|
2911 #endif |
|
2912 } |
|
2913 |
|
2914 void CCmdChunkInfo::OptionsL(RCommandOptionList& aOptions) |
|
2915 { |
|
2916 _LIT(KCmdChunkInfoOptRate, "rate"); |
|
2917 _LIT(KCmdChunkInfoOptHuman, "human"); |
|
2918 _LIT(KCmdChunkInfoOptOwningProcess, "owning-process"); |
|
2919 _LIT(KCmdChunkInfoOptControllingProcess, "controlling-process"); |
|
2920 _LIT(KCmdChunkInfoOptSize, "size"); |
|
2921 |
|
2922 aOptions.AppendUintL(iUpdateRate, KCmdChunkInfoOptRate); |
|
2923 aOptions.AppendBoolL(iHumanReadable, KCmdChunkInfoOptHuman); |
|
2924 aOptions.AppendStringL(iOwningProcess, KCmdChunkInfoOptOwningProcess); |
|
2925 aOptions.AppendUintL(iControllingProcess, KCmdChunkInfoOptControllingProcess); |
|
2926 aOptions.AppendBoolL(iIncludeSize, KCmdChunkInfoOptSize); |
|
2927 |
|
2928 } |
|
2929 |
|
2930 void CCmdChunkInfo::ArgumentsL(RCommandArgumentList& aArguments) |
|
2931 { |
|
2932 _LIT(KCmdChunkInfoArg, "chunk_address"); |
|
2933 aArguments.AppendUintL(iAddress, KCmdChunkInfoArg); |
|
2934 } |
|
2935 |
|
2936 |
|
2937 // |
|
2938 // CCmdSvrInfo. |
|
2939 // |
|
2940 |
|
2941 CCommandBase* CCmdSvrInfo::NewLC() |
|
2942 { |
|
2943 CCmdSvrInfo* self = new(ELeave) CCmdSvrInfo(); |
|
2944 CleanupStack::PushL(self); |
|
2945 self->BaseConstructL(); |
|
2946 return self; |
|
2947 } |
|
2948 |
|
2949 CCmdSvrInfo::~CCmdSvrInfo() |
|
2950 { |
|
2951 delete iBuf; |
|
2952 delete iFormatter; |
|
2953 } |
|
2954 |
|
2955 CCmdSvrInfo::CCmdSvrInfo() |
|
2956 { |
|
2957 } |
|
2958 |
|
2959 void CCmdSvrInfo::ListServersL() |
|
2960 { |
|
2961 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
2962 TInt bufSize = 1024; |
|
2963 TInt err = KErrNone; |
|
2964 HBufC8* addressesBuf; |
|
2965 do |
|
2966 { |
|
2967 addressesBuf = HBufC8::NewLC(bufSize); |
|
2968 TPtr8 addressesPtr(addressesBuf->Des()); |
|
2969 err = iMemAccess.GetObjectAddresses(EServer, KNullDesC(), addressesPtr); |
|
2970 if (err == KErrOverflow) |
|
2971 { |
|
2972 CleanupStack::PopAndDestroy(addressesBuf); |
|
2973 bufSize *= 2; |
|
2974 } |
|
2975 } |
|
2976 while (err == KErrOverflow); |
|
2977 |
|
2978 if (err) |
|
2979 { |
|
2980 PrintError(err, _L("Unable to read server addresses.")); |
|
2981 User::Leave(err); |
|
2982 } |
|
2983 |
|
2984 const TInt numAddresses = addressesBuf->Length() / sizeof(TUint32*); |
|
2985 if (numAddresses == 0) |
|
2986 { |
|
2987 Write(_L("No servers found.\r\n")); |
|
2988 } |
|
2989 else |
|
2990 { |
|
2991 TUint32* p = (TUint32*)addressesBuf->Ptr(); |
|
2992 TInt offset = 0; |
|
2993 while (offset < numAddresses) |
|
2994 { |
|
2995 TPckg<TServerKernelInfo> serverInfoPckg(iServerInfo); |
|
2996 TUint32* ptr = p + offset++; |
|
2997 err = iMemAccess.GetObjectInfo(EServer, (TUint8*)(*ptr), serverInfoPckg); |
|
2998 if (err == KErrNone) |
|
2999 { |
|
3000 iFullName.Copy(iServerInfo.iFullName); |
|
3001 iBuf->AppendFormatL(_L("0x%08x\t\'%S\'\r\n"), *ptr, &iFullName); |
|
3002 } |
|
3003 else if (err != KErrNotFound) |
|
3004 { |
|
3005 // Only warn on something other than KErrNotFound. KErrNotFound could legitimately |
|
3006 // happen if the chunk in question has been deleted since we called RMemoryAccess::GetObjectAddresses. |
|
3007 PrintWarning(_L("Unable to read server at 0x%08x (%d)"), ptr, err); |
|
3008 } |
|
3009 } |
|
3010 } |
|
3011 |
|
3012 CleanupStack::PopAndDestroy(addressesBuf); |
|
3013 |
|
3014 #endif |
|
3015 } |
|
3016 |
|
3017 void CCmdSvrInfo::ListSessionsL() |
|
3018 { |
|
3019 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
3020 TPckg<TServerKernelInfo> serverInfoPckg(iServerInfo); |
|
3021 TInt err = iMemAccess.GetObjectInfo(EServer, (TUint8*)iAddress, serverInfoPckg); |
|
3022 if (err) |
|
3023 { |
|
3024 PrintError(err, _L("Unable to get info for server 0x%08x"), iAddress); |
|
3025 User::Leave(err); |
|
3026 } |
|
3027 |
|
3028 TPckg<TThreadKernelInfo> threadInfoPckg(iThreadInfo); |
|
3029 err = iMemAccess.GetObjectInfo(EThread, iServerInfo.iAddressOfOwningThread, threadInfoPckg); |
|
3030 if (err) |
|
3031 { |
|
3032 PrintError(err, _L("Unable to get info for thread 0x%08x"), iServerInfo.iAddressOfOwningThread); |
|
3033 User::Leave(err); |
|
3034 } |
|
3035 |
|
3036 iFullName.Copy(iThreadInfo.iFullName); |
|
3037 iBuf->AppendFormatL(_L("Owning thread id:\t%u\r\n"), iThreadInfo.iThreadId); |
|
3038 iBuf->AppendFormatL(_L("Owning thread name:\t\'%S\'\r\n"), &iFullName); |
|
3039 TUint type = iServerInfo.iSessionType; |
|
3040 iBuf->AppendFormatL(_L("Session type:\t%u\r\n"), type); |
|
3041 |
|
3042 for (TUint i = iServerInfo.iSessionQ.iStartFrom; i < iServerInfo.iSessionQ.iCount; ++i) |
|
3043 { |
|
3044 TPckg<TSessionKernelInfo> sessionInfoPckg(iSessionInfo); |
|
3045 err = iMemAccess.GetObjectInfo(ESession, iServerInfo.iSessionQ.iBuffer[i], sessionInfoPckg); |
|
3046 if (err) |
|
3047 { |
|
3048 PrintWarning(_L("Unable to get info for session 0x%08x (%d)"), iServerInfo.iSessionQ.iBuffer[i], err); |
|
3049 } |
|
3050 else |
|
3051 { |
|
3052 iFullName.Copy(iSessionInfo.iFullName); |
|
3053 iBuf->AppendFormatL(_L("Session:\t\'%S\'\r\n"), &iFullName); |
|
3054 |
|
3055 TPckg<TProcessKernelInfo> processInfoPckg(iProcessInfo); |
|
3056 err = iMemAccess.GetObjectInfo(EProcess, iSessionInfo.iAddressOfKernelOwner, processInfoPckg); |
|
3057 if (err == KErrNone) |
|
3058 { |
|
3059 iFullName.Copy(iProcessInfo.iFullName); |
|
3060 iBuf->AppendFormatL(_L("Session owner:\t\'%S\'\r\n"), &iFullName); |
|
3061 } |
|
3062 else |
|
3063 { |
|
3064 err = iMemAccess.GetObjectInfo(EThread, iSessionInfo.iAddressOfKernelOwner, threadInfoPckg); |
|
3065 if (err == KErrNone) |
|
3066 { |
|
3067 iFullName.Copy(iThreadInfo.iFullName); |
|
3068 iBuf->AppendFormatL(_L("Session owner:\t\'%S\'\r\n"), &iFullName); |
|
3069 } |
|
3070 else |
|
3071 { |
|
3072 PrintWarning(_L("Unable to get info for session owner 0x%08x (%d)"), iSessionInfo.iAddressOfKernelOwner, err); |
|
3073 } |
|
3074 } |
|
3075 } |
|
3076 } |
|
3077 #endif |
|
3078 } |
|
3079 |
|
3080 const TDesC& CCmdSvrInfo::Name() const |
|
3081 { |
|
3082 _LIT(KCmdSvrInfoName, "svrinfo"); |
|
3083 return KCmdSvrInfoName; |
|
3084 } |
|
3085 |
|
3086 void CCmdSvrInfo::DoRunL() |
|
3087 { |
|
3088 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
3089 iFormatter = CTextFormatter::NewL(Stdout()); |
|
3090 iBuf = IoUtils::CTextBuffer::NewL(0x100); |
|
3091 LoadMemoryAccessL(); |
|
3092 |
|
3093 if (iAddress == 0) |
|
3094 { |
|
3095 ListServersL(); |
|
3096 } |
|
3097 else |
|
3098 { |
|
3099 ListSessionsL(); |
|
3100 } |
|
3101 |
|
3102 iFormatter->TabulateL(0, 2, iBuf->Descriptor(), ETruncateLongestColumn); |
|
3103 Write(iFormatter->Descriptor()); |
|
3104 #else |
|
3105 PrintError(KErrNotSupported, _L("Unable to fetch server information because fshell was not built with FSHELL_MEMORY_ACCESS_SUPPORT defined. That probably means this plaform doesn't support the MemoryAccess device driver.")); |
|
3106 User::Leave(KErrNotSupported); |
|
3107 #endif |
|
3108 } |
|
3109 |
|
3110 void CCmdSvrInfo::ArgumentsL(RCommandArgumentList& aArguments) |
|
3111 { |
|
3112 _LIT(KCmdSvrInfoArg, "server_address"); |
|
3113 aArguments.AppendUintL(iAddress, KCmdSvrInfoArg); |
|
3114 } |
|
3115 |
|
3116 |
|
3117 // |
|
3118 // CCmdTickle. |
|
3119 // |
|
3120 |
|
3121 CCommandBase* CCmdTickle::NewLC() |
|
3122 { |
|
3123 CCmdTickle* self = new (ELeave) CCmdTickle(); |
|
3124 CleanupStack::PushL(self); |
|
3125 self->BaseConstructL(); |
|
3126 return self; |
|
3127 } |
|
3128 |
|
3129 CCmdTickle::~CCmdTickle() |
|
3130 { |
|
3131 } |
|
3132 |
|
3133 CCmdTickle::CCmdTickle() |
|
3134 { |
|
3135 } |
|
3136 |
|
3137 void CCmdTickle::DoRunL() |
|
3138 { |
|
3139 User::ResetInactivityTime(); |
|
3140 const TInt KGiveSystemTimeToFocus = 500000; // microseconds |
|
3141 User::After(KGiveSystemTimeToFocus); |
|
3142 } |
|
3143 |
|
3144 const TDesC& CCmdTickle::Name() const |
|
3145 { |
|
3146 _LIT(KName, "tickle"); |
|
3147 return KName; |
|
3148 } |
|
3149 |
|
3150 |
|
3151 // |
|
3152 // CCmdTicks. |
|
3153 // |
|
3154 |
|
3155 CCommandBase* CCmdTicks::NewLC() |
|
3156 { |
|
3157 CCmdTicks* self = new (ELeave) CCmdTicks(); |
|
3158 CleanupStack::PushL(self); |
|
3159 self->BaseConstructL(); |
|
3160 return self; |
|
3161 } |
|
3162 |
|
3163 CCmdTicks::~CCmdTicks() |
|
3164 { |
|
3165 } |
|
3166 |
|
3167 CCmdTicks::CCmdTicks() |
|
3168 { |
|
3169 } |
|
3170 |
|
3171 TInt NanoTickPeriod() |
|
3172 { |
|
3173 TInt nanoTickPeriod; |
|
3174 if (HAL::Get(HAL::ENanoTickPeriod, nanoTickPeriod) != KErrNone) |
|
3175 { |
|
3176 nanoTickPeriod = 1000; |
|
3177 } |
|
3178 return nanoTickPeriod; |
|
3179 } |
|
3180 |
|
3181 TInt FastCounterFrequency() |
|
3182 { |
|
3183 TInt fastCounterFrequency; |
|
3184 if (HAL::Get(HAL::EFastCounterFrequency, fastCounterFrequency) != KErrNone) |
|
3185 { |
|
3186 fastCounterFrequency = 1000; |
|
3187 } |
|
3188 return fastCounterFrequency; |
|
3189 } |
|
3190 |
|
3191 TBool FastCounterCountsUp() |
|
3192 { |
|
3193 TBool countsUp; |
|
3194 if (HAL::Get(HAL::EFastCounterCountsUp, countsUp) != KErrNone) |
|
3195 { |
|
3196 countsUp = EFalse; |
|
3197 } |
|
3198 return countsUp; |
|
3199 } |
|
3200 |
|
3201 void CCmdTicks::DoRunL() |
|
3202 { |
|
3203 TUint nticks = User::NTickCount(); |
|
3204 TUint fast = User::FastCounter(); |
|
3205 |
|
3206 Printf(_L("NKern ticks: %u\r\n"), nticks); |
|
3207 Printf(_L("Fast ticks: %u\r\n"), fast); |
|
3208 |
|
3209 if (iVerbose) |
|
3210 { |
|
3211 Printf(_L("\r\nNKern tick period: %d\r\n"), NanoTickPeriod()); |
|
3212 Printf(_L("Fast counter frequency: %d\r\n"), FastCounterFrequency()); |
|
3213 Printf(_L("Fast counter counts up: %d\r\n"), FastCounterCountsUp()); |
|
3214 } |
|
3215 } |
|
3216 |
|
3217 const TDesC& CCmdTicks::Name() const |
|
3218 { |
|
3219 _LIT(KName, "ticks"); |
|
3220 return KName; |
|
3221 } |
|
3222 |
|
3223 void CCmdTicks::OptionsL(RCommandOptionList& aOptions) |
|
3224 { |
|
3225 aOptions.AppendBoolL(iVerbose, KOptVerbose); |
|
3226 } |
|
3227 |
|
3228 |
|
3229 // |
|
3230 // CCmdUpTime. |
|
3231 // |
|
3232 |
|
3233 CCommandBase* CCmdUpTime::NewLC() |
|
3234 { |
|
3235 CCmdUpTime* self = new (ELeave) CCmdUpTime(); |
|
3236 CleanupStack::PushL(self); |
|
3237 self->BaseConstructL(); |
|
3238 return self; |
|
3239 } |
|
3240 |
|
3241 CCmdUpTime::~CCmdUpTime() |
|
3242 { |
|
3243 } |
|
3244 |
|
3245 CCmdUpTime::CCmdUpTime() |
|
3246 { |
|
3247 } |
|
3248 |
|
3249 void AppendTimeUnit(TInt aValue, const TDesC& aUnit, TDes& aBuf) |
|
3250 { |
|
3251 if (aValue == 1) |
|
3252 { |
|
3253 aBuf.AppendFormat(_L("1 %S "), &aUnit); |
|
3254 } |
|
3255 else |
|
3256 { |
|
3257 aBuf.AppendFormat(_L("%d %Ss "), aValue, &aUnit); |
|
3258 } |
|
3259 } |
|
3260 |
|
3261 void FormatTime(const TUint64& aInterval, TDes& aBuf) |
|
3262 { |
|
3263 const TInt ms = 1000; |
|
3264 const TInt s = ms * ms; |
|
3265 const TInt64 m = s * 60; |
|
3266 const TInt64 h = m * 60; |
|
3267 const TInt64 d = h * 24; |
|
3268 |
|
3269 TInt64 interval = aInterval; |
|
3270 const TInt numDays = interval / d; |
|
3271 if (numDays > 0) |
|
3272 { |
|
3273 AppendTimeUnit(numDays, _L("day"), aBuf); |
|
3274 interval = interval % d; |
|
3275 } |
|
3276 |
|
3277 const TInt numHours = interval / h; |
|
3278 if (numHours > 0) |
|
3279 { |
|
3280 AppendTimeUnit(numHours, _L("hour"), aBuf); |
|
3281 interval = interval % h; |
|
3282 } |
|
3283 |
|
3284 const TInt numMinutes = interval / m; |
|
3285 if (numMinutes > 0) |
|
3286 { |
|
3287 AppendTimeUnit(numMinutes, _L("minute"), aBuf); |
|
3288 interval = interval % m; |
|
3289 } |
|
3290 |
|
3291 TBuf<16> format(_L("%.2f ")); |
|
3292 TReal realInterval = interval; |
|
3293 if (realInterval >= s) |
|
3294 { |
|
3295 realInterval /= s; |
|
3296 format.Append(_L("s")); |
|
3297 } |
|
3298 else if (realInterval >= ms) |
|
3299 { |
|
3300 realInterval /= ms; |
|
3301 format.Append(_L("ms")); |
|
3302 } |
|
3303 else |
|
3304 { |
|
3305 format.Append(_L("us")); |
|
3306 } |
|
3307 aBuf.AppendFormat(format, realInterval); |
|
3308 } |
|
3309 |
|
3310 void CCmdUpTime::DoRunL() |
|
3311 { |
|
3312 TUint64 n = User::NTickCount(); |
|
3313 n *= NanoTickPeriod(); |
|
3314 |
|
3315 if (iHuman) |
|
3316 { |
|
3317 TBuf<256> timeBuf; |
|
3318 FormatTime(n, timeBuf); |
|
3319 Printf(_L("%S"), &timeBuf); |
|
3320 } |
|
3321 else |
|
3322 { |
|
3323 Printf(_L("%Lu"), n); |
|
3324 } |
|
3325 } |
|
3326 |
|
3327 const TDesC& CCmdUpTime::Name() const |
|
3328 { |
|
3329 _LIT(KName, "uptime"); |
|
3330 return KName; |
|
3331 } |
|
3332 |
|
3333 void CCmdUpTime::OptionsL(RCommandOptionList& aOptions) |
|
3334 { |
|
3335 aOptions.AppendBoolL(iHuman, KOptHuman); |
|
3336 } |
|
3337 |
|
3338 |
|
3339 // |
|
3340 // CCmdVar. |
|
3341 // |
|
3342 |
|
3343 CCommandBase* CCmdVar::NewLC() |
|
3344 { |
|
3345 CCmdVar* self = new (ELeave) CCmdVar(); |
|
3346 CleanupStack::PushL(self); |
|
3347 self->BaseConstructL(); |
|
3348 return self; |
|
3349 } |
|
3350 |
|
3351 CCmdVar::~CCmdVar() |
|
3352 { |
|
3353 delete iVar1; |
|
3354 delete iArg; |
|
3355 } |
|
3356 |
|
3357 CCmdVar::CCmdVar() |
|
3358 { |
|
3359 } |
|
3360 |
|
3361 void CCmdVar::DoRunL() |
|
3362 { |
|
3363 IoUtils::CEnvironment& env = Env(); |
|
3364 switch (iOperation) |
|
3365 { |
|
3366 case EDefined: |
|
3367 if (iArg) |
|
3368 { |
|
3369 Complete(KErrArgument, _L("Argument should not be specified for \"defined\" operation")); |
|
3370 } |
|
3371 else |
|
3372 { |
|
3373 SetErrorReported(ETrue); // To silence leaves. |
|
3374 Complete(!env.IsDefined(*iVar1)); |
|
3375 } |
|
3376 break; |
|
3377 case ENotDefined: |
|
3378 if (iArg) |
|
3379 { |
|
3380 Complete(KErrArgument, _L("Argument should not be specified for \"not-defined\" operation")); |
|
3381 } |
|
3382 else |
|
3383 { |
|
3384 SetErrorReported(ETrue); // To silence leaves. |
|
3385 Complete(env.IsDefined(*iVar1)); |
|
3386 } |
|
3387 break; |
|
3388 case EEqual: |
|
3389 if (iArg == NULL) |
|
3390 { |
|
3391 Complete(KErrArgument, _L("Argument must be specified for == operation")); |
|
3392 } |
|
3393 else |
|
3394 { |
|
3395 SetErrorReported(ETrue); // To silence leaves. |
|
3396 Complete(!(env.GetAsDesL(*iVar1) == *iArg)); |
|
3397 } |
|
3398 break; |
|
3399 case ENotEqual: |
|
3400 if (iArg == NULL) |
|
3401 { |
|
3402 Complete(KErrArgument, _L("Argument must be specified for != operation")); |
|
3403 } |
|
3404 else |
|
3405 { |
|
3406 SetErrorReported(ETrue); // To silence leaves. |
|
3407 Complete(env.GetAsDesL(*iVar1) == *iArg); |
|
3408 } |
|
3409 break; |
|
3410 case EAdd: |
|
3411 case ESubtract: |
|
3412 { |
|
3413 if (iArg == NULL) LeaveIfErr(KErrArgument, _L("Argument must be specified for add and subtract operations")); |
|
3414 TLex lex(*iArg); |
|
3415 TInt operand; |
|
3416 TInt err = lex.Val(operand); |
|
3417 LeaveIfErr(err, _L("Couldn't parse an integer from argument '%S'"), iArg); |
|
3418 if (iOperation == ESubtract) operand = -operand; |
|
3419 TInt current = 0; |
|
3420 TRAP_IGNORE(current = env.GetAsIntL(*iVar1)); // If it doesn't yet exist or isn't an int, we'll treat it as if it was zero |
|
3421 env.SetL(*iVar1, current + operand); |
|
3422 break; |
|
3423 } |
|
3424 default: |
|
3425 User::Leave(KErrNotSupported); |
|
3426 } |
|
3427 } |
|
3428 |
|
3429 const TDesC& CCmdVar::Name() const |
|
3430 { |
|
3431 _LIT(KName, "var"); |
|
3432 return KName; |
|
3433 } |
|
3434 |
|
3435 void CCmdVar::ArgumentsL(RCommandArgumentList& aArguments) |
|
3436 { |
|
3437 _LIT(KArgVariable, "variable"); |
|
3438 _LIT(KArgOperation, "operation"); |
|
3439 _LIT(KArgArgument, "argument"); |
|
3440 |
|
3441 aArguments.AppendStringL(iVar1, KArgVariable); |
|
3442 aArguments.AppendEnumL((TInt&)iOperation, KArgOperation); |
|
3443 aArguments.AppendStringL(iArg, KArgArgument); |
|
3444 } |
|
3445 |
|
3446 |
|
3447 // |
|
3448 // CCmdSource. |
|
3449 // |
|
3450 |
|
3451 CCommandBase* CCmdSource::NewLC() |
|
3452 { |
|
3453 CCmdSource* self = new (ELeave) CCmdSource(); |
|
3454 CleanupStack::PushL(self); |
|
3455 self->BaseConstructL(); |
|
3456 return self; |
|
3457 } |
|
3458 |
|
3459 CCmdSource::~CCmdSource() |
|
3460 { |
|
3461 delete iArgs; |
|
3462 delete iScriptData; |
|
3463 delete iParser; |
|
3464 } |
|
3465 |
|
3466 CCmdSource::CCmdSource() : CCommandBase(EManualComplete) |
|
3467 { |
|
3468 } |
|
3469 |
|
3470 void CCmdSource::DoRunL() |
|
3471 { |
|
3472 TIoHandleSet ioHandles(IoSession(), Stdin(), Stdout(), Stderr()); |
|
3473 TBool helpPrinted; |
|
3474 iScriptData = CShell::ReadScriptL(iFileName, iArgs, Env(), FsL(), ioHandles, helpPrinted); |
|
3475 |
|
3476 if (helpPrinted) |
|
3477 { |
|
3478 Complete(); |
|
3479 } |
|
3480 else |
|
3481 { |
|
3482 TUint mode = CParser::EExportLineNumbers; |
|
3483 if (iKeepGoing) |
|
3484 { |
|
3485 mode |= CParser::EKeepGoing; |
|
3486 } |
|
3487 iParser = CParser::NewL(mode, *iScriptData, IoSession(), Stdin(), Stdout(), Stderr(), Env(), gShell->CommandFactory(), this); |
|
3488 iParser->Start(); |
|
3489 } |
|
3490 } |
|
3491 |
|
3492 const TDesC& CCmdSource::Name() const |
|
3493 { |
|
3494 _LIT(KName, "source"); |
|
3495 return KName; |
|
3496 } |
|
3497 |
|
3498 void CCmdSource::ArgumentsL(RCommandArgumentList& aArguments) |
|
3499 { |
|
3500 _LIT(KArgFileName, "script_file_name"); |
|
3501 aArguments.AppendFileNameL(iFileName, KArgFileName); |
|
3502 |
|
3503 _LIT(KArgArgs, "script_args"); |
|
3504 aArguments.AppendStringL(iArgs, KArgArgs); |
|
3505 } |
|
3506 |
|
3507 void CCmdSource::OptionsL(RCommandOptionList& aOptions) |
|
3508 { |
|
3509 _LIT(KOptKeepGoing, "keep-going"); |
|
3510 aOptions.AppendBoolL(iKeepGoing, KOptKeepGoing); |
|
3511 } |
|
3512 |
|
3513 void CCmdSource::HandleParserComplete(CParser&, const TError& aError) |
|
3514 { |
|
3515 TInt err = aError.Error(); |
|
3516 if (err < 0) |
|
3517 { |
|
3518 aError.Report(); |
|
3519 const TDesC& scriptPath = Env().GetAsDes(KScriptPath); |
|
3520 const TDesC& scriptName = Env().GetAsDes(KScriptName); |
|
3521 PrintError(err, _L("Aborted \"%S\" at line %d"), &aError.ScriptFileName(), aError.ScriptLineNumber()); |
|
3522 } |
|
3523 Complete(err); |
|
3524 } |
|
3525 |
|
3526 // |
|
3527 // CCmdStart. |
|
3528 // |
|
3529 |
|
3530 CCommandBase* CCmdStart::NewLC() |
|
3531 { |
|
3532 CCmdStart* self = new (ELeave) CCmdStart(); |
|
3533 CleanupStack::PushL(self); |
|
3534 self->BaseConstructL(); |
|
3535 return self; |
|
3536 } |
|
3537 |
|
3538 CCmdStart::~CCmdStart() |
|
3539 { |
|
3540 delete iExe; |
|
3541 delete iCommandLine; |
|
3542 } |
|
3543 |
|
3544 CCmdStart::CCmdStart() |
|
3545 { |
|
3546 } |
|
3547 |
|
3548 void CCmdStart::DoRunL() |
|
3549 { |
|
3550 if (iRendezvous && iWait) |
|
3551 { |
|
3552 LeaveIfErr(KErrArgument, _L("--rendezvous cannot be used with --wait")); |
|
3553 } |
|
3554 if (iTimeout && !(iRendezvous || iWait)) |
|
3555 { |
|
3556 LeaveIfErr(KErrArgument, _L("--timeout must be used with either --rendezvous or --wait")); |
|
3557 } |
|
3558 if (iMeasure && !(iRendezvous || iWait)) |
|
3559 { |
|
3560 LeaveIfErr(KErrArgument, _L("--measure must be used with either --rendezvous or --wait")); |
|
3561 } |
|
3562 |
|
3563 TRequestStatus waitStatus; |
|
3564 RProcess process; |
|
3565 LeaveIfErr(process.Create(*iExe, iCommandLine ? *iCommandLine : KNullDesC(), EOwnerThread), _L("Couldn't create \"%S\" process"), iExe); |
|
3566 CleanupClosePushL(process); |
|
3567 |
|
3568 if (iRendezvous) |
|
3569 { |
|
3570 process.Rendezvous(waitStatus); |
|
3571 if (waitStatus != KRequestPending) |
|
3572 { |
|
3573 User::WaitForRequest(waitStatus); |
|
3574 process.Kill(0); |
|
3575 LeaveIfErr(waitStatus.Int(), _L("Failed to log on to process")); |
|
3576 } |
|
3577 } |
|
3578 else if (iWait) |
|
3579 { |
|
3580 process.Logon(waitStatus); |
|
3581 if (waitStatus != KRequestPending) |
|
3582 { |
|
3583 User::WaitForRequest(waitStatus); |
|
3584 process.Kill(0); |
|
3585 LeaveIfErr(waitStatus.Int(), _L("Failed to log on to process")); |
|
3586 } |
|
3587 } |
|
3588 |
|
3589 TRequestStatus timerStat; |
|
3590 RTimer timer; |
|
3591 if (iTimeout) |
|
3592 { |
|
3593 User::LeaveIfError(timer.CreateLocal()); |
|
3594 CleanupClosePushL(timer); |
|
3595 timer.After(timerStat, iTimeout * 1000 * 1000); |
|
3596 } |
|
3597 |
|
3598 TUint32 startTime = 0, endTime = 0; |
|
3599 if (iMeasure) startTime = User::NTickCount(); |
|
3600 |
|
3601 process.Resume(); |
|
3602 |
|
3603 if (iTimeout) |
|
3604 { |
|
3605 timer.After(timerStat, iTimeout * 1000 * 1000); |
|
3606 User::WaitForRequest(waitStatus, timerStat); |
|
3607 if (iMeasure) endTime = User::NTickCount(); |
|
3608 |
|
3609 if (waitStatus == KRequestPending) |
|
3610 { |
|
3611 // Then the timer expired |
|
3612 if (iRendezvous) |
|
3613 { |
|
3614 process.RendezvousCancel(waitStatus); |
|
3615 } |
|
3616 else if (iWait) |
|
3617 { |
|
3618 process.LogonCancel(waitStatus); |
|
3619 } |
|
3620 User::WaitForRequest(waitStatus); |
|
3621 LeaveIfErr(KErrTimedOut, _L("Timed out waiting for \"%S\""), iExe); |
|
3622 } |
|
3623 else |
|
3624 { |
|
3625 timer.Cancel(); |
|
3626 User::WaitForRequest(timerStat); |
|
3627 } |
|
3628 |
|
3629 CleanupStack::PopAndDestroy(&timer); |
|
3630 } |
|
3631 else if (iRendezvous || iWait) |
|
3632 { |
|
3633 User::WaitForRequest(waitStatus); |
|
3634 if (iMeasure) endTime = User::NTickCount(); |
|
3635 } |
|
3636 |
|
3637 CleanupStack::PopAndDestroy(&process); |
|
3638 |
|
3639 if (iMeasure) |
|
3640 { |
|
3641 TUint32 elapsed = endTime - startTime; |
|
3642 elapsed *= NanoTickPeriod(); |
|
3643 TBuf<50> timeBuf; |
|
3644 FormatTime(elapsed, timeBuf); |
|
3645 Write(timeBuf); |
|
3646 Write(_L("\r\n")); |
|
3647 } |
|
3648 |
|
3649 if (iRendezvous) |
|
3650 { |
|
3651 LeaveIfErr(waitStatus.Int(), _L("Error returned from rendezvous")); |
|
3652 } |
|
3653 if (iWait) |
|
3654 { |
|
3655 LeaveIfErr(waitStatus.Int(), _L("Error returned from logon")); |
|
3656 } |
|
3657 } |
|
3658 |
|
3659 const TDesC& CCmdStart::Name() const |
|
3660 { |
|
3661 _LIT(KName, "start"); |
|
3662 return KName; |
|
3663 } |
|
3664 |
|
3665 void CCmdStart::ArgumentsL(RCommandArgumentList& aArguments) |
|
3666 { |
|
3667 _LIT(KExeName, "exe-name"); |
|
3668 _LIT(KArgs, "arguments"); |
|
3669 |
|
3670 aArguments.AppendStringL(iExe, KExeName); |
|
3671 aArguments.AppendStringL(iCommandLine, KArgs); |
|
3672 } |
|
3673 |
|
3674 void CCmdStart::OptionsL(RCommandOptionList& aOptions) |
|
3675 { |
|
3676 _LIT(KOptRendezvous, "rendezvous"); |
|
3677 _LIT(KOptWait, "wait"); |
|
3678 _LIT(KOptTimeout, "timeout"); |
|
3679 _LIT(KOptMeasure, "measure"); |
|
3680 |
|
3681 aOptions.AppendBoolL(iRendezvous, KOptRendezvous); |
|
3682 aOptions.AppendBoolL(iWait, KOptWait); |
|
3683 aOptions.AppendIntL(iTimeout, KOptTimeout); |
|
3684 aOptions.AppendBoolL(iMeasure, KOptMeasure); |
|
3685 } |
|
3686 |
|
3687 |
|
3688 // |
|
3689 // CCmdCompare. |
|
3690 // |
|
3691 |
|
3692 CCommandBase* CCmdCompare::NewLC() |
|
3693 { |
|
3694 CCmdCompare* self = new (ELeave) CCmdCompare(); |
|
3695 CleanupStack::PushL(self); |
|
3696 self->BaseConstructL(); |
|
3697 return self; |
|
3698 } |
|
3699 |
|
3700 CCmdCompare::~CCmdCompare() |
|
3701 { |
|
3702 } |
|
3703 |
|
3704 CCmdCompare::CCmdCompare() |
|
3705 { |
|
3706 } |
|
3707 |
|
3708 void CCmdCompare::DoRunL() |
|
3709 { |
|
3710 RFile file1; |
|
3711 LeaveIfErr(file1.Open(FsL(), iFileName1, EFileRead), _L("Couldn't open \"%S\" for reading"), &iFileName1); |
|
3712 CleanupClosePushL(file1); |
|
3713 RFile file2; |
|
3714 LeaveIfErr(file2.Open(FsL(), iFileName2, EFileRead), _L("Couldn't open \"%S\" for reading"), &iFileName2); |
|
3715 CleanupClosePushL(file2); |
|
3716 |
|
3717 TBool same(ETrue); |
|
3718 FOREVER |
|
3719 { |
|
3720 TBuf8<KBlockSize> buf1; |
|
3721 TBuf8<KBlockSize> buf2; |
|
3722 LeaveIfErr(file1.Read(buf1), _L("Couldn't read \"%S\""), &iFileName1); |
|
3723 LeaveIfErr(file2.Read(buf2), _L("Couldn't read \"%S\""), &iFileName2); |
|
3724 if (buf1 != buf2) |
|
3725 { |
|
3726 same = EFalse; |
|
3727 break; |
|
3728 } |
|
3729 if (buf1.Length() == 0) |
|
3730 { |
|
3731 break; |
|
3732 } |
|
3733 } |
|
3734 |
|
3735 CleanupStack::PopAndDestroy(2, &file1); |
|
3736 if (iVerbose) |
|
3737 { |
|
3738 if (same) |
|
3739 { |
|
3740 Write(_L("Identical\r\n")); |
|
3741 } |
|
3742 else |
|
3743 { |
|
3744 Write(_L("Different\r\n")); |
|
3745 } |
|
3746 } |
|
3747 Complete(!same); |
|
3748 } |
|
3749 |
|
3750 const TDesC& CCmdCompare::Name() const |
|
3751 { |
|
3752 _LIT(KName, "compare"); |
|
3753 return KName; |
|
3754 } |
|
3755 |
|
3756 void CCmdCompare::ArgumentsL(RCommandArgumentList& aArguments) |
|
3757 { |
|
3758 _LIT(KFileName1, "file_name_1"); |
|
3759 _LIT(KFileName2, "file_name_2"); |
|
3760 aArguments.AppendFileNameL(iFileName1, KFileName1); |
|
3761 aArguments.AppendFileNameL(iFileName2, KFileName2); |
|
3762 } |
|
3763 |
|
3764 void CCmdCompare::OptionsL(RCommandOptionList& aOptions) |
|
3765 { |
|
3766 aOptions.AppendBoolL(iVerbose, KOptVerbose); |
|
3767 } |
|
3768 |
|
3769 |
|
3770 // |
|
3771 // CCmdTime. |
|
3772 // |
|
3773 |
|
3774 CCommandBase* CCmdTime::NewLC() |
|
3775 { |
|
3776 CCmdTime* self = new (ELeave) CCmdTime(); |
|
3777 CleanupStack::PushL(self); |
|
3778 self->BaseConstructL(); |
|
3779 return self; |
|
3780 } |
|
3781 |
|
3782 CCmdTime::~CCmdTime() |
|
3783 { |
|
3784 delete iParser; |
|
3785 delete iCommandLine; |
|
3786 } |
|
3787 |
|
3788 CCmdTime::CCmdTime() : CCommandBase(EManualComplete), iRepeatCount(1) |
|
3789 { |
|
3790 } |
|
3791 |
|
3792 void CCmdTime::DoRunL() |
|
3793 { |
|
3794 NextIterationL(); |
|
3795 } |
|
3796 |
|
3797 void CCmdTime::NextIterationL() |
|
3798 { |
|
3799 delete iParser; |
|
3800 iParser = NULL; |
|
3801 iParser = CParser::NewL(CParser::ENormal, *iCommandLine, IoSession(), Stdin(), Stdout(), Stderr(), Env(), gShell->CommandFactory(), this); |
|
3802 iCountBefore = iFastCounter ? User::FastCounter() : User::NTickCount(); |
|
3803 iParser->Start(); |
|
3804 } |
|
3805 |
|
3806 const TDesC& CCmdTime::Name() const |
|
3807 { |
|
3808 _LIT(KName, "time"); |
|
3809 return KName; |
|
3810 } |
|
3811 |
|
3812 void CCmdTime::ArgumentsL(RCommandArgumentList& aArguments) |
|
3813 { |
|
3814 _LIT(KArgs, "command"); |
|
3815 aArguments.AppendStringL(iCommandLine, KArgs); |
|
3816 } |
|
3817 |
|
3818 void CCmdTime::OptionsL(RCommandOptionList& aOptions) |
|
3819 { |
|
3820 _LIT(KOptFastCounter, "fast-counter"); |
|
3821 _LIT(KOptRepeatCount, "repeat"); |
|
3822 aOptions.AppendBoolL(iHuman, KOptHuman); |
|
3823 aOptions.AppendBoolL(iFastCounter, KOptFastCounter); |
|
3824 aOptions.AppendIntL(iRepeatCount, KOptRepeatCount); |
|
3825 } |
|
3826 |
|
3827 void CCmdTime::HandleParserComplete(CParser&, const TError& aError) |
|
3828 { |
|
3829 if (aError.Error() < 0) |
|
3830 { |
|
3831 aError.Report(); |
|
3832 } |
|
3833 |
|
3834 TUint32 countAfter = iFastCounter ? User::FastCounter() : User::NTickCount(); |
|
3835 |
|
3836 TUint64 difference; |
|
3837 if (iFastCounter) |
|
3838 { |
|
3839 difference = FastCounterCountsUp() ? (countAfter - iCountBefore) : (iCountBefore - countAfter); |
|
3840 difference *= 1000000; |
|
3841 difference /= FastCounterFrequency(); |
|
3842 } |
|
3843 else |
|
3844 { |
|
3845 difference = countAfter - iCountBefore; |
|
3846 difference *= NanoTickPeriod(); |
|
3847 } |
|
3848 |
|
3849 if (Stdout().AttachedToConsole()) |
|
3850 { |
|
3851 TPoint cursorPos; |
|
3852 Stdout().GetCursorPos(cursorPos); |
|
3853 if (cursorPos.iX != 0) |
|
3854 { |
|
3855 Write(KNewLine); |
|
3856 } |
|
3857 } |
|
3858 |
|
3859 if (iHuman) |
|
3860 { |
|
3861 TBuf<256> timeBuf; |
|
3862 FormatTime(difference, timeBuf); |
|
3863 timeBuf.Append(KNewLine); |
|
3864 Write(timeBuf); |
|
3865 } |
|
3866 else if (iRepeatCount == 1) |
|
3867 { |
|
3868 // Don't print individual times if we asked for non-human readable output. (If you want that behaviour, use "repeat n time xyz...") |
|
3869 Printf(_L("%Lu\r\n"), difference); |
|
3870 } |
|
3871 |
|
3872 iTotalTime += difference; |
|
3873 iIteration++; |
|
3874 if (iRepeatCount > 1 && iIteration == iRepeatCount) |
|
3875 { |
|
3876 // Need to print the average |
|
3877 difference = iTotalTime / iRepeatCount; |
|
3878 if (iHuman) |
|
3879 { |
|
3880 TBuf<256> timeBuf; |
|
3881 timeBuf.Append(_L("Average: ")); |
|
3882 FormatTime(difference, timeBuf); |
|
3883 timeBuf.Append(KNewLine); |
|
3884 Write(timeBuf); |
|
3885 } |
|
3886 else |
|
3887 { |
|
3888 Printf(_L("%Lu\r\n"), difference); |
|
3889 } |
|
3890 } |
|
3891 if (aError.Error() < 0 || iIteration == iRepeatCount) |
|
3892 { |
|
3893 Complete(aError.Error()); |
|
3894 } |
|
3895 else |
|
3896 { |
|
3897 // Rerun the fun |
|
3898 TRAPD(err, NextIterationL()); |
|
3899 if (err) Complete(err); |
|
3900 } |
|
3901 } |
|
3902 |
|
3903 |
|
3904 // |
|
3905 // CCmdRepeat. |
|
3906 // |
|
3907 |
|
3908 CCommandBase* CCmdRepeat::NewLC() |
|
3909 { |
|
3910 CCmdRepeat* self = new (ELeave) CCmdRepeat(); |
|
3911 CleanupStack::PushL(self); |
|
3912 self->BaseConstructL(); |
|
3913 return self; |
|
3914 } |
|
3915 |
|
3916 CCmdRepeat::~CCmdRepeat() |
|
3917 { |
|
3918 delete iParser; |
|
3919 delete iCommandLine; |
|
3920 } |
|
3921 |
|
3922 CCmdRepeat::CCmdRepeat() : CCommandBase(EManualComplete) |
|
3923 { |
|
3924 } |
|
3925 |
|
3926 void CCmdRepeat::DoRunL() |
|
3927 { |
|
3928 if (iNumRepeats == 0) |
|
3929 { |
|
3930 iForever = ETrue; |
|
3931 } |
|
3932 |
|
3933 CreateParserL(); |
|
3934 } |
|
3935 |
|
3936 const TDesC& CCmdRepeat::Name() const |
|
3937 { |
|
3938 _LIT(KName, "repeat"); |
|
3939 return KName; |
|
3940 } |
|
3941 |
|
3942 void CCmdRepeat::ArgumentsL(RCommandArgumentList& aArguments) |
|
3943 { |
|
3944 _LIT(KCount, "count"); |
|
3945 _LIT(KArgs, "command"); |
|
3946 |
|
3947 aArguments.AppendUintL(iNumRepeats, KCount); |
|
3948 aArguments.AppendStringL(iCommandLine, KArgs); |
|
3949 } |
|
3950 |
|
3951 void CCmdRepeat::OptionsL(RCommandOptionList& aOptions) |
|
3952 { |
|
3953 _LIT(KOptKeepGoing, "keep-going"); |
|
3954 _LIT(KOptWait, "wait"); |
|
3955 |
|
3956 aOptions.AppendBoolL(iKeepGoing, KOptKeepGoing); |
|
3957 aOptions.AppendIntL(iWaitTime, KOptWait); |
|
3958 } |
|
3959 |
|
3960 void CCmdRepeat::HandleParserComplete(CParser&, const TError& aError) |
|
3961 { |
|
3962 TRAPD(err, HandleParserCompleteL(aError)); |
|
3963 if (err) |
|
3964 { |
|
3965 Complete(err); |
|
3966 } |
|
3967 } |
|
3968 |
|
3969 void CCmdRepeat::HandleParserCompleteL(const TError& aError) |
|
3970 { |
|
3971 if (aError.Error() < 0) |
|
3972 { |
|
3973 aError.Report(); |
|
3974 } |
|
3975 |
|
3976 if (((aError.Error() == KErrNone) || iKeepGoing) && ((++iCount < iNumRepeats) || iForever)) |
|
3977 { |
|
3978 delete iParser; |
|
3979 iParser = NULL; |
|
3980 if (iWaitTime) User::After(iWaitTime * 1000); |
|
3981 CreateParserL(); |
|
3982 } |
|
3983 else |
|
3984 { |
|
3985 Complete(aError.Error()); |
|
3986 } |
|
3987 } |
|
3988 |
|
3989 void CCmdRepeat::CreateParserL() |
|
3990 { |
|
3991 TBuf<32> buf; |
|
3992 buf.AppendNum(iCount); |
|
3993 Env().SetL(KRepeatCount, buf); |
|
3994 iParser = CParser::NewL(iKeepGoing ? CParser::EKeepGoing : CParser::ENormal, *iCommandLine, IoSession(), Stdin(), Stdout(), Stderr(), Env(), gShell->CommandFactory(), this); |
|
3995 iParser->Start(); |
|
3996 } |
|
3997 |
|
3998 |
|
3999 // |
|
4000 // CCmdDebug. |
|
4001 // |
|
4002 |
|
4003 CCommandBase* CCmdDebug::NewLC() |
|
4004 { |
|
4005 CCmdDebug* self = new (ELeave) CCmdDebug(); |
|
4006 CleanupStack::PushL(self); |
|
4007 self->BaseConstructL(); |
|
4008 return self; |
|
4009 } |
|
4010 |
|
4011 CCmdDebug::~CCmdDebug() |
|
4012 { |
|
4013 delete iScriptData; |
|
4014 delete iParser; |
|
4015 delete iArgs; |
|
4016 } |
|
4017 |
|
4018 CCmdDebug::CCmdDebug() : CCommandBase(EManualComplete) |
|
4019 { |
|
4020 } |
|
4021 |
|
4022 void CCmdDebug::DoRunL() |
|
4023 { |
|
4024 TIoHandleSet ioHandles(IoSession(), Stdin(), Stdout(), Stderr()); |
|
4025 TBool helpPrinted; |
|
4026 iScriptData = CShell::ReadScriptL(iFileName, iArgs, Env(), FsL(), ioHandles, helpPrinted); |
|
4027 if (helpPrinted) |
|
4028 { |
|
4029 Complete(); |
|
4030 } |
|
4031 else |
|
4032 { |
|
4033 TUint mode = CParser::EDebug | CParser::EExportLineNumbers; |
|
4034 if (iKeepGoing) |
|
4035 { |
|
4036 mode |= CParser::EKeepGoing; |
|
4037 } |
|
4038 iParser = CParser::NewL(mode, *iScriptData, IoSession(), Stdin(), Stdout(), Stderr(), Env(), gShell->CommandFactory(), this); |
|
4039 iParser->Start(); |
|
4040 } |
|
4041 } |
|
4042 |
|
4043 const TDesC& CCmdDebug::Name() const |
|
4044 { |
|
4045 _LIT(KName, "debug"); |
|
4046 return KName; |
|
4047 } |
|
4048 |
|
4049 void CCmdDebug::ArgumentsL(RCommandArgumentList& aArguments) |
|
4050 { |
|
4051 _LIT(KArgFileName, "script_file_name"); |
|
4052 aArguments.AppendFileNameL(iFileName, KArgFileName); |
|
4053 |
|
4054 _LIT(KArgArgs, "script_args"); |
|
4055 aArguments.AppendStringL(iArgs, KArgArgs); |
|
4056 } |
|
4057 |
|
4058 void CCmdDebug::OptionsL(RCommandOptionList& aOptions) |
|
4059 { |
|
4060 _LIT(KOptKeepGoing, "keep-going"); |
|
4061 aOptions.AppendBoolL(iKeepGoing, KOptKeepGoing); |
|
4062 } |
|
4063 |
|
4064 void CCmdDebug::HandleParserComplete(CParser&, const TError& aError) |
|
4065 { |
|
4066 Printf(_L("Completed with %d (%S)\r\n"), aError.Error(), Stringify::Error(aError.Error())); |
|
4067 Complete(aError.Error()); |
|
4068 } |
|
4069 |
|
4070 void CCmdDebug::AboutToExecuteLine(const TDesC& aOrignalLine, const TDesC& aExpandedLine) |
|
4071 { |
|
4072 Write(aOrignalLine); |
|
4073 Write(KNewLine); |
|
4074 TRAP_IGNORE(InteractL(aExpandedLine)); |
|
4075 } |
|
4076 |
|
4077 void CCmdDebug::LineReturned(TInt aError) |
|
4078 { |
|
4079 Printf(_L("Returned %d (%S)\r\n"), aError, Stringify::Error(aError)); |
|
4080 } |
|
4081 |
|
4082 void CCmdDebug::InteractL(const TDesC& aExpandedLine) |
|
4083 { |
|
4084 FOREVER |
|
4085 { |
|
4086 TBuf<1> command; |
|
4087 ReadL(command); |
|
4088 |
|
4089 _LIT(KStep, "s"); |
|
4090 _LIT(KExpand, "x"); |
|
4091 |
|
4092 if (command == KStep) |
|
4093 { |
|
4094 return; |
|
4095 } |
|
4096 else if (command == KExpand) |
|
4097 { |
|
4098 Write(aExpandedLine); |
|
4099 Write(KNewLine); |
|
4100 } |
|
4101 else |
|
4102 { |
|
4103 Write(_L("Unknown command\r\n")); |
|
4104 } |
|
4105 } |
|
4106 } |
|
4107 |
|
4108 |
|
4109 // |
|
4110 // CCmdReadMem. |
|
4111 // |
|
4112 |
|
4113 CCommandBase* CCmdReadMem::NewLC() |
|
4114 { |
|
4115 CCmdReadMem* self = new(ELeave) CCmdReadMem(); |
|
4116 CleanupStack::PushL(self); |
|
4117 self->BaseConstructL(); |
|
4118 return self; |
|
4119 } |
|
4120 |
|
4121 CCmdReadMem::~CCmdReadMem() |
|
4122 { |
|
4123 } |
|
4124 |
|
4125 CCmdReadMem::CCmdReadMem() |
|
4126 { |
|
4127 } |
|
4128 |
|
4129 const TDesC& CCmdReadMem::Name() const |
|
4130 { |
|
4131 _LIT(KName, "readmem"); |
|
4132 return KName; |
|
4133 } |
|
4134 |
|
4135 void CCmdReadMem::DoRunL() |
|
4136 { |
|
4137 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
4138 LoadMemoryAccessL(); |
|
4139 |
|
4140 if (iFileName.Length() > 0) |
|
4141 { |
|
4142 LeaveIfErr(iFile.Create(FsL(), iFileName, EFileWrite), _L("Unable to create \"%S\""), &iFileName); |
|
4143 } |
|
4144 |
|
4145 if (!iOptions.IsPresent(&iThreadId)) |
|
4146 { |
|
4147 iThreadId = RThread().Id(); |
|
4148 } |
|
4149 |
|
4150 TBuf8<KBlockSize> buf; |
|
4151 TInt bytesRead = 0; |
|
4152 TInt dumpPos = 0; |
|
4153 while ((TUint)bytesRead < iSize) |
|
4154 { |
|
4155 buf.Zero(); |
|
4156 TThreadMemoryAccessParamsBuf memoryAccessParamsBuf; |
|
4157 TThreadMemoryAccessParams& memoryAccessParams = memoryAccessParamsBuf(); |
|
4158 memoryAccessParams.iId = iThreadId; |
|
4159 memoryAccessParams.iAddr = (TUint8*)iAddress + bytesRead; |
|
4160 TInt bytesToRead = iSize - bytesRead; |
|
4161 if (bytesToRead > KBlockSize) |
|
4162 { |
|
4163 bytesToRead = KBlockSize; |
|
4164 } |
|
4165 memoryAccessParams.iSize = bytesToRead; |
|
4166 User::LeaveIfError(iMemAccess.GetThreadMem(memoryAccessParamsBuf, buf)); |
|
4167 if (iFile.SubSessionHandle()) |
|
4168 { |
|
4169 User::LeaveIfError(iFile.Write(buf)); |
|
4170 } |
|
4171 else |
|
4172 { |
|
4173 Dump(buf, *this, dumpPos); |
|
4174 } |
|
4175 bytesRead += bytesToRead; |
|
4176 } |
|
4177 |
|
4178 #else |
|
4179 PrintError(KErrNotSupported, _L("Unable to read memory because fshell was not built with FSHELL_MEMORY_ACCESS_SUPPORT defined. That probably means this plaform doesn't support the MemoryAccess device driver.")); |
|
4180 User::Leave(KErrNotSupported); |
|
4181 #endif |
|
4182 } |
|
4183 |
|
4184 void CCmdReadMem::OptionsL(RCommandOptionList& aOptions) |
|
4185 { |
|
4186 _LIT(KCmdOptThreadId, "thread_id"); |
|
4187 aOptions.AppendIntL(iThreadId, KCmdOptThreadId); |
|
4188 } |
|
4189 |
|
4190 void CCmdReadMem::ArgumentsL(RCommandArgumentList& aArguments) |
|
4191 { |
|
4192 _LIT(KCmdArgAddress, "address"); |
|
4193 _LIT(KCmdArgSize, "size"); |
|
4194 _LIT(KCmdArgFileName, "file_name"); |
|
4195 |
|
4196 aArguments.AppendUintL(iAddress, KCmdArgAddress); |
|
4197 aArguments.AppendUintL(iSize, KCmdArgSize); |
|
4198 aArguments.AppendFileNameL(iFileName, KCmdArgFileName); |
|
4199 } |
|
4200 |
|
4201 |
|
4202 // |
|
4203 // CCmdE32Header. |
|
4204 // |
|
4205 |
|
4206 CCommandBase* CCmdE32Header::NewLC() |
|
4207 { |
|
4208 CCmdE32Header* self = new(ELeave) CCmdE32Header(); |
|
4209 CleanupStack::PushL(self); |
|
4210 self->BaseConstructL(); |
|
4211 return self; |
|
4212 } |
|
4213 |
|
4214 CCmdE32Header::~CCmdE32Header() |
|
4215 { |
|
4216 delete iFormatter; |
|
4217 } |
|
4218 |
|
4219 CCmdE32Header::CCmdE32Header() |
|
4220 { |
|
4221 } |
|
4222 |
|
4223 const TDesC& CCmdE32Header::Name() const |
|
4224 { |
|
4225 _LIT(KName, "e32header"); |
|
4226 return KName; |
|
4227 } |
|
4228 |
|
4229 #define CASE_LIT2(x, y) case x: { _LIT(KName, #y); return &KName; } |
|
4230 const TDesC* CompressionType(TUint aType) |
|
4231 { |
|
4232 switch (aType) |
|
4233 { |
|
4234 CASE_LIT2(0, KFormatNotCompressed) |
|
4235 CASE_LIT2(0x101F7AFC, KUidCompressionDeflate) |
|
4236 CASE_LIT2(0x102822AA, KUidCompressionBytePair) |
|
4237 default: |
|
4238 _LIT(KUnknown, "?"); |
|
4239 return &KUnknown; |
|
4240 } |
|
4241 } |
|
4242 |
|
4243 void CCmdE32Header::DoRunL() |
|
4244 { |
|
4245 if (iXip && iNotXip) |
|
4246 { |
|
4247 LeaveIfErr(KErrArgument, _L("--xip and --not-xip options are mutually exclusive")); |
|
4248 } |
|
4249 |
|
4250 RFile file; |
|
4251 CleanupClosePushL(file); |
|
4252 LeaveIfErr(file.Open(FsL(), iFileName, EFileRead), _L("Couldn't open \"%S\" for reading"), &iFileName); |
|
4253 |
|
4254 iFormatter = CTextFormatter::NewL(Stdout()); |
|
4255 IoUtils::CTextBuffer* buf = IoUtils::CTextBuffer::NewLC(0x100); |
|
4256 |
|
4257 if ((Fs().IsFileInRom(iFileName) || iXip) && !iNotXip) |
|
4258 { |
|
4259 TAny* ptr = Fs().IsFileInRom(iFileName); |
|
4260 if (ptr) |
|
4261 { |
|
4262 buf->AppendFormatL(_L("ROM file address:\t0x%08x\r\n"), ptr); |
|
4263 } |
|
4264 TRomImageHeader imageHeader; |
|
4265 TPckg<TRomImageHeader> pckg(imageHeader); |
|
4266 LeaveIfErr(file.Read(pckg, sizeof(TRomImageHeader)), _L("Couldn't read E32 image header")); |
|
4267 buf->AppendFormatL(_L("UIDs:\t0x%08x 0x%08x 0x%08x\r\n"), imageHeader.iUid1, imageHeader.iUid2, imageHeader.iUid3); |
|
4268 buf->AppendFormatL(_L("UID checksum:\t0x%08x\r\n"), imageHeader.iUidChecksum); |
|
4269 buf->AppendFormatL(_L("Entry point offset:\t0x%08x\r\n"), imageHeader.iEntryPoint); |
|
4270 buf->AppendFormatL(_L("Code address:\t0x%08x\r\n"), imageHeader.iCodeAddress); |
|
4271 buf->AppendFormatL(_L("Data address:\t0x%08x\r\n"), imageHeader.iDataAddress); |
|
4272 buf->AppendFormatL(_L("Code size:\t%d\r\n"), imageHeader.iCodeSize); |
|
4273 buf->AppendFormatL(_L("Text size:\t%d\r\n"), imageHeader.iTextSize); |
|
4274 buf->AppendFormatL(_L("Data size:\t%d\r\n"), imageHeader.iDataSize); |
|
4275 buf->AppendFormatL(_L("BSS size:\t%d\r\n"), imageHeader.iBssSize); |
|
4276 buf->AppendFormatL(_L("Minimum heap size:\t%d\r\n"), imageHeader.iHeapSizeMin); |
|
4277 buf->AppendFormatL(_L("Maximum heap size:\t%d\r\n"), imageHeader.iHeapSizeMax); |
|
4278 buf->AppendFormatL(_L("Stack size:\t%d\r\n"), imageHeader.iStackSize); |
|
4279 buf->AppendFormatL(_L("DLL ref table address:\t0x%08x\r\n"), imageHeader.iDllRefTable); |
|
4280 buf->AppendFormatL(_L("Export dir count:\t%d\r\n"), imageHeader.iExportDirCount); |
|
4281 buf->AppendFormatL(_L("Export dir address:\t0x%08x\r\n"), imageHeader.iExportDir); |
|
4282 buf->AppendFormatL(_L("Secure ID:\t0x%08x\r\n"), imageHeader.iS.iSecureId); |
|
4283 buf->AppendFormatL(_L("Vendor ID:\t0x%08x\r\n"), imageHeader.iS.iVendorId); |
|
4284 buf->AppendFormatL(_L("Capabilities:\t0x%08x 0x%08x\r\n"), imageHeader.iS.iCaps[0], imageHeader.iS.iCaps[1]); |
|
4285 TInt majorVersion = imageHeader.iToolsVersion.iMajor; |
|
4286 TInt minorVersion = imageHeader.iToolsVersion.iMinor; |
|
4287 TInt buildVersion = imageHeader.iToolsVersion.iBuild; |
|
4288 buf->AppendFormatL(_L("Tools version:\t%d.%d (%d)\r\n"), majorVersion, minorVersion, buildVersion); |
|
4289 buf->AppendFormatL(_L("Flags:\t0x%08x\r\n"), imageHeader.iFlags); |
|
4290 buf->AppendFormatL(_L("Process priority:\t%d\r\n"), imageHeader.iPriority); |
|
4291 buf->AppendFormatL(_L("Data BSS linear base:\t0x%08x\r\n"), imageHeader.iDataBssLinearBase); |
|
4292 buf->AppendFormatL(_L("Next extension:\t0x%08x\r\n"), imageHeader.iNextExtension); |
|
4293 buf->AppendFormatL(_L("Hardware variant:\t0x%08x\r\n"), imageHeader.iHardwareVariant); |
|
4294 buf->AppendFormatL(_L("Total data size:\t%d\r\n"), imageHeader.iTotalDataSize); |
|
4295 buf->AppendFormatL(_L("Module version:\t0x%08x (%d.%d)\r\n"), imageHeader.iModuleVersion, imageHeader.iModuleVersion>>16, imageHeader.iModuleVersion&0xFFFF); |
|
4296 buf->AppendFormatL(_L("Exception descriptor:\t0x%08x\r\n"), imageHeader.iExceptionDescriptor); |
|
4297 } |
|
4298 else |
|
4299 { |
|
4300 E32ImageHeaderV* imageHeader = new(ELeave) E32ImageHeaderV; |
|
4301 CleanupStack::PushL(imageHeader); |
|
4302 TPckg<E32ImageHeaderV> pckg(*imageHeader); |
|
4303 LeaveIfErr(file.Read(pckg, sizeof(E32ImageHeaderV)), _L("Couldn't read E32 image header")); |
|
4304 buf->AppendFormatL(_L("UIDs:\t0x%08x 0x%08x 0x%08x\r\n"), imageHeader->iUid1, imageHeader->iUid2, imageHeader->iUid3); |
|
4305 buf->AppendFormatL(_L("UID checksum:\t0x%08x\r\n"), imageHeader->iUidChecksum); |
|
4306 buf->AppendFormatL(_L("Header CRC:\t0x%08x\r\n"), imageHeader->iHeaderCrc); |
|
4307 buf->AppendFormatL(_L("Module version:\t0x%08x (%d.%d)\r\n"), imageHeader->iModuleVersion, imageHeader->iModuleVersion>>16, imageHeader->iModuleVersion&0xFFFF); |
|
4308 buf->AppendFormatL(_L("Compression type:\t0x%08x (%S)\r\n"), imageHeader->iCompressionType, CompressionType(imageHeader->iCompressionType)); |
|
4309 TInt majorVersion = imageHeader->iToolsVersion.iMajor; |
|
4310 TInt minorVersion = imageHeader->iToolsVersion.iMinor; |
|
4311 TInt buildVersion = imageHeader->iToolsVersion.iBuild; |
|
4312 buf->AppendFormatL(_L("Tools version:\t%d.%d (%d)\r\n"), majorVersion, minorVersion, buildVersion); |
|
4313 buf->AppendFormatL(_L("Build time:\t0x%08x 0x%08x\r\n"), imageHeader->iTimeLo, imageHeader->iTimeHi); |
|
4314 buf->AppendFormatL(_L("Flags:\t0x%08x\r\n"), imageHeader->iFlags); |
|
4315 buf->AppendFormatL(_L("Code size:\t%d\r\n"), imageHeader->iCodeSize); |
|
4316 buf->AppendFormatL(_L("Minimum heap size:\t%d\r\n"), imageHeader->iHeapSizeMin); |
|
4317 buf->AppendFormatL(_L("Maximum heap size:\t%d\r\n"), imageHeader->iHeapSizeMax); |
|
4318 buf->AppendFormatL(_L("Stack size:\t%d\r\n"), imageHeader->iStackSize); |
|
4319 buf->AppendFormatL(_L("BSS size:\t%d\r\n"), imageHeader->iBssSize); |
|
4320 buf->AppendFormatL(_L("Entry point offset:\t0x%08x\r\n"), imageHeader->iEntryPoint); |
|
4321 buf->AppendFormatL(_L("Code base:\t0x%08x\r\n"), imageHeader->iCodeBase); |
|
4322 buf->AppendFormatL(_L("Data base:\t0x%08x\r\n"), imageHeader->iDataBase); |
|
4323 buf->AppendFormatL(_L("DLL ref table count:\t%d\r\n"), imageHeader->iDllRefTableCount); |
|
4324 buf->AppendFormatL(_L("Export dir offset:\t0x%08x\r\n"), imageHeader->iExportDirOffset); |
|
4325 buf->AppendFormatL(_L("Export dir count:\t%d\r\n"), imageHeader->iExportDirCount); |
|
4326 buf->AppendFormatL(_L("Text size:\t%d\r\n"), imageHeader->iTextSize); |
|
4327 buf->AppendFormatL(_L("Code offset:\t0x%08x\r\n"), imageHeader->iCodeOffset); |
|
4328 buf->AppendFormatL(_L("Data offset:\t0x%08x\r\n"), imageHeader->iDataOffset); |
|
4329 buf->AppendFormatL(_L("Import offset:\t0x%08x\r\n"), imageHeader->iImportOffset); |
|
4330 buf->AppendFormatL(_L("Code reloc offset:\t0x%08x\r\n"), imageHeader->iCodeRelocOffset); |
|
4331 buf->AppendFormatL(_L("Data reloc offset:\t0x%08x\r\n"), imageHeader->iDataRelocOffset); |
|
4332 TInt temp; // Why use a temp here? |
|
4333 temp = imageHeader->iProcessPriority; |
|
4334 buf->AppendFormatL(_L("Process priority:\t%d\r\n"), temp); |
|
4335 temp = imageHeader->iCpuIdentifier; |
|
4336 buf->AppendFormatL(_L("CPU identifier:\t%d\r\n"), temp); |
|
4337 buf->AppendFormatL(_L("Uncompressed size:\t%d\r\n"), imageHeader->iUncompressedSize); |
|
4338 buf->AppendFormatL(_L("Secure ID:\t0x%08x\r\n"), imageHeader->iS.iSecureId); |
|
4339 buf->AppendFormatL(_L("Vendor ID:\t0x%08x\r\n"), imageHeader->iS.iVendorId); |
|
4340 buf->AppendFormatL(_L("Capabilities:\t0x%08x 0x%08x\r\n"), imageHeader->iS.iCaps[0], imageHeader->iS.iCaps[1]); |
|
4341 buf->AppendFormatL(_L("Exception descriptor:\t0x%08x\r\n"), imageHeader->iExceptionDescriptor); |
|
4342 buf->AppendFormatL(_L("Spare2:\t0x%08x\r\n"), imageHeader->iSpare2); |
|
4343 temp = imageHeader->iExportDescSize; |
|
4344 buf->AppendFormatL(_L("Export description size:\t%d\r\n"), temp); |
|
4345 temp = imageHeader->iExportDescType; |
|
4346 buf->AppendFormatL(_L("Export description type:\t%d\r\n"), temp); |
|
4347 temp = imageHeader->iExportDesc[0]; |
|
4348 buf->AppendFormatL(_L("Export description:\t%d\r\n"), temp); |
|
4349 CleanupStack::PopAndDestroy(imageHeader); |
|
4350 } |
|
4351 |
|
4352 iFormatter->TabulateL(0, 2, buf->Descriptor()); |
|
4353 Write(iFormatter->Descriptor()); |
|
4354 CleanupStack::PopAndDestroy(2, &file); |
|
4355 } |
|
4356 |
|
4357 void CCmdE32Header::OptionsL(RCommandOptionList& aOptions) |
|
4358 { |
|
4359 _LIT(KCmdOptXip, "xip"); |
|
4360 _LIT(KCmdOptNotXip, "not-xip"); |
|
4361 |
|
4362 aOptions.AppendBoolL(iXip, KCmdOptXip); |
|
4363 aOptions.AppendBoolL(iNotXip, KCmdOptNotXip); |
|
4364 } |
|
4365 |
|
4366 void CCmdE32Header::ArgumentsL(RCommandArgumentList& aArguments) |
|
4367 { |
|
4368 _LIT(KCmdArgFileName, "file_name"); |
|
4369 aArguments.AppendFileNameL(iFileName, KCmdArgFileName); |
|
4370 } |
|
4371 |
|
4372 |
|
4373 // |
|
4374 // CCmdObjInfo. |
|
4375 // |
|
4376 |
|
4377 CCommandBase* CCmdObjInfo::NewLC() |
|
4378 { |
|
4379 CCmdObjInfo* self = new(ELeave) CCmdObjInfo(); |
|
4380 CleanupStack::PushL(self); |
|
4381 self->BaseConstructL(); |
|
4382 return self; |
|
4383 } |
|
4384 |
|
4385 CCmdObjInfo::~CCmdObjInfo() |
|
4386 { |
|
4387 } |
|
4388 |
|
4389 CCmdObjInfo::CCmdObjInfo() |
|
4390 { |
|
4391 } |
|
4392 |
|
4393 const TDesC& CCmdObjInfo::Name() const |
|
4394 { |
|
4395 _LIT(KName, "objinfo"); |
|
4396 return KName; |
|
4397 } |
|
4398 |
|
4399 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
4400 |
|
4401 #define CASE_RETURN_LIT(XXX) case XXX: { _LIT(_KLit, #XXX); return &_KLit; } |
|
4402 #define DEFAULT_RETURN_LIT(XXX) default: { _LIT(_KLit, XXX); return &_KLit; } |
|
4403 |
|
4404 EXPORT_C const TDesC* StringifyObjectType(TObjectType aObjectType) |
|
4405 { |
|
4406 switch (aObjectType) |
|
4407 { |
|
4408 CASE_RETURN_LIT(EThread); |
|
4409 CASE_RETURN_LIT(EProcess); |
|
4410 CASE_RETURN_LIT(EChunk); |
|
4411 CASE_RETURN_LIT(ELibrary); |
|
4412 CASE_RETURN_LIT(ESemaphore); |
|
4413 CASE_RETURN_LIT(EMutex); |
|
4414 CASE_RETURN_LIT(ETimer); |
|
4415 CASE_RETURN_LIT(EServer); |
|
4416 CASE_RETURN_LIT(ESession); |
|
4417 CASE_RETURN_LIT(ELogicalDevice); |
|
4418 CASE_RETURN_LIT(EPhysicalDevice); |
|
4419 CASE_RETURN_LIT(ELogicalChannel); |
|
4420 CASE_RETURN_LIT(EChangeNotifier); |
|
4421 CASE_RETURN_LIT(EUndertaker); |
|
4422 CASE_RETURN_LIT(EMsgQueue); |
|
4423 CASE_RETURN_LIT(EPropertyRef); |
|
4424 CASE_RETURN_LIT(ECondVar); |
|
4425 CASE_RETURN_LIT(EIpcMessageD); |
|
4426 CASE_RETURN_LIT(EIpcMessage); |
|
4427 CASE_RETURN_LIT(EIpcClient); |
|
4428 DEFAULT_RETURN_LIT("*** OBJECT TYPE UNKNOWN ***"); |
|
4429 } |
|
4430 } |
|
4431 |
|
4432 void CCmdObjInfo::PrintObjectDetailsL(TUint aObjectAddress) |
|
4433 { |
|
4434 TObjectType objectType; |
|
4435 TInt err = iMemAccess.GetObjectType((TUint8*)aObjectAddress, objectType); |
|
4436 if (err == KErrNone) |
|
4437 { |
|
4438 TObjectKernelInfo objectInfo; |
|
4439 TPckg<TObjectKernelInfo> objectInfoPckg(objectInfo); |
|
4440 err = iMemAccess.GetObjectInfo(objectType, (TUint8*)(aObjectAddress), objectInfoPckg); |
|
4441 if (err == KErrNone) |
|
4442 { |
|
4443 TFullName fullName; |
|
4444 fullName.Copy(objectInfo.iFullName); |
|
4445 Printf(_L("0x%08x %2d %S (type=%d) %S\r\n"), aObjectAddress, objectInfo.iAccessCount, StringifyObjectType(objectType), objectType, &fullName); |
|
4446 } |
|
4447 else |
|
4448 { |
|
4449 PrintWarning(_L("Couldn't read details of %S 0x%08x : %S(%d)"), StringifyObjectType(objectType), aObjectAddress, Stringify::Error(err), err); |
|
4450 } |
|
4451 } |
|
4452 else |
|
4453 { |
|
4454 PrintWarning(_L("Couldn't find type of object 0x%08x : %S(%d)"), aObjectAddress, Stringify::Error(err), err); |
|
4455 } |
|
4456 |
|
4457 if (iReferencers) |
|
4458 { |
|
4459 PrintObjectReferencersL(aObjectAddress); |
|
4460 } |
|
4461 } |
|
4462 |
|
4463 void CCmdObjInfo::PrintObjectReferencersL(TUint aObjectAddress) |
|
4464 { |
|
4465 TInt err = KErrNone; |
|
4466 TInt bufSize = 256; |
|
4467 HBufC8* idBuf; |
|
4468 do |
|
4469 { |
|
4470 idBuf = HBufC8::NewLC(bufSize); |
|
4471 TPtr8 idPtr(idBuf->Des()); |
|
4472 err = iMemAccess.GetHandleOwners((TUint8*)aObjectAddress, idPtr); |
|
4473 if (err == KErrOverflow) |
|
4474 { |
|
4475 CleanupStack::PopAndDestroy(idBuf); |
|
4476 bufSize *= 2; |
|
4477 } |
|
4478 } |
|
4479 while (err == KErrOverflow); |
|
4480 |
|
4481 const TInt numIds = idBuf->Length() / sizeof(TUint); |
|
4482 if (numIds > 0) |
|
4483 { |
|
4484 Write(_L("Referenced by:\r\n")); |
|
4485 } |
|
4486 for (TInt i = 0; i < numIds; i++) |
|
4487 { |
|
4488 TUint id = ((TUint*)idBuf->Ptr())[i]; |
|
4489 TBool isThread = ETrue; |
|
4490 RHandleBase h; |
|
4491 TInt err = ((RThread&)h).Open(TThreadId(id)); |
|
4492 if (err) |
|
4493 { |
|
4494 // Maybe it's a process id instead. |
|
4495 isThread = EFalse; |
|
4496 err = ((RProcess&)h).Open(TProcessId(id)); |
|
4497 } |
|
4498 |
|
4499 if (err) |
|
4500 { |
|
4501 PrintWarning(_L("Unable to open thread or process for id %d: %S (%d)"), id, Stringify::Error(err), err); |
|
4502 } |
|
4503 else |
|
4504 { |
|
4505 TFullName name = h.FullName(); |
|
4506 _LIT(KThread, "\tthread: "); |
|
4507 _LIT(KProcess, "\tprocess: "); |
|
4508 Printf(_L("%S%u\t%S\r\n"), isThread ? &KThread : &KProcess, id, &name); |
|
4509 } |
|
4510 } |
|
4511 |
|
4512 CleanupStack::PopAndDestroy(idBuf); |
|
4513 } |
|
4514 |
|
4515 void CCmdObjInfo::PrintReferencedObjectDetailsL(TOwnerType aOwnerType, TUint aId) |
|
4516 { |
|
4517 TInt err = KErrNone; |
|
4518 TInt bufSize = 256; |
|
4519 |
|
4520 HBufC8* addressesBuf; |
|
4521 do |
|
4522 { |
|
4523 addressesBuf = HBufC8::NewLC(bufSize); |
|
4524 TPtr8 addressesPtr(addressesBuf->Des()); |
|
4525 if (aOwnerType == EOwnerProcess) |
|
4526 { |
|
4527 err = iMemAccess.GetProcessHandles(aId, addressesPtr); |
|
4528 } |
|
4529 else |
|
4530 { |
|
4531 err = iMemAccess.GetThreadHandles(aId, addressesPtr); |
|
4532 } |
|
4533 if (err == KErrOverflow) |
|
4534 { |
|
4535 CleanupStack::PopAndDestroy(addressesBuf); |
|
4536 bufSize *= 2; |
|
4537 } |
|
4538 } |
|
4539 while (err == KErrOverflow); |
|
4540 |
|
4541 const TInt numAddresses = addressesBuf->Length() / sizeof(TUint32*); |
|
4542 if (numAddresses == 0) |
|
4543 { |
|
4544 Write(_L("No objects found.\r\n")); |
|
4545 } |
|
4546 else |
|
4547 { |
|
4548 TUint32* p = (TUint32*)addressesBuf->Ptr(); |
|
4549 TInt offset = 0; |
|
4550 while (offset < numAddresses) |
|
4551 { |
|
4552 TUint32* ptr = p + offset++; |
|
4553 PrintObjectDetailsL(*ptr); |
|
4554 } |
|
4555 } |
|
4556 |
|
4557 CleanupStack::PopAndDestroy(addressesBuf); |
|
4558 } |
|
4559 |
|
4560 #endif // FSHELL_MEMORY_ACCESS_SUPPORT |
|
4561 |
|
4562 void CCmdObjInfo::DoRunL() |
|
4563 { |
|
4564 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
4565 LoadMemoryAccessL(); |
|
4566 |
|
4567 if (iObjectAddress) |
|
4568 { |
|
4569 PrintObjectDetailsL(iObjectAddress); |
|
4570 } |
|
4571 else if (iProcessId) |
|
4572 { |
|
4573 if (iAll) |
|
4574 { |
|
4575 RProcess process; |
|
4576 LeaveIfErr(process.Open(iProcessId), _L("Couldn't open process with id \"%u\""), iProcessId); |
|
4577 TFullName processName(process.Name()); |
|
4578 Printf(_L("Objects owned by process \"%S\":\r\n"), &processName); |
|
4579 PrintReferencedObjectDetailsL(EOwnerProcess, iProcessId); |
|
4580 Write(_L("\r\n")); |
|
4581 |
|
4582 processName.Append(_L("*")); |
|
4583 TFindThread threadFinder(processName); |
|
4584 RThread thread; |
|
4585 TFullName threadName; |
|
4586 while (threadFinder.Next(threadName) == KErrNone) |
|
4587 { |
|
4588 TInt err = thread.Open(threadFinder); |
|
4589 if (err) |
|
4590 { |
|
4591 continue; |
|
4592 } |
|
4593 Printf(_L("Objects owned by thread \"%S\":\r\n"), &threadName); |
|
4594 PrintReferencedObjectDetailsL(EOwnerThread, thread.Id()); |
|
4595 Write(_L("\r\n")); |
|
4596 } |
|
4597 } |
|
4598 else |
|
4599 { |
|
4600 PrintReferencedObjectDetailsL(EOwnerProcess, iProcessId); |
|
4601 } |
|
4602 } |
|
4603 else if (iThreadId) |
|
4604 { |
|
4605 PrintReferencedObjectDetailsL(EOwnerThread, iThreadId); |
|
4606 } |
|
4607 |
|
4608 #else |
|
4609 PrintError(KErrNotSupported, _L("Unable to fetch object information because fshell was not built with FSHELL_MEMORY_ACCESS_SUPPORT defined. That probably means this plaform doesn't support the MemoryAccess device driver.")); |
|
4610 User::Leave(KErrNotSupported); |
|
4611 #endif |
|
4612 } |
|
4613 |
|
4614 void CCmdObjInfo::OptionsL(RCommandOptionList& aOptions) |
|
4615 { |
|
4616 _LIT(KCmdOptReferencers, "referencers"); |
|
4617 _LIT(KCmdOptProcessId, "process-id"); |
|
4618 _LIT(KCmdOptThreadId, "thread-id"); |
|
4619 _LIT(KCmdOptAll, "all"); |
|
4620 |
|
4621 aOptions.AppendBoolL(iReferencers, KCmdOptReferencers); |
|
4622 aOptions.AppendUintL(iProcessId, KCmdOptProcessId); |
|
4623 aOptions.AppendUintL(iThreadId, KCmdOptThreadId); |
|
4624 aOptions.AppendBoolL(iAll, KCmdOptAll); |
|
4625 } |
|
4626 |
|
4627 void CCmdObjInfo::ArgumentsL(RCommandArgumentList& aArguments) |
|
4628 { |
|
4629 _LIT(KCmdArgObjectAddress, "object_address"); |
|
4630 aArguments.AppendUintL(iObjectAddress, KCmdArgObjectAddress); |
|
4631 } |
|
4632 |
|
4633 // |
|
4634 // CCmdTouch. |
|
4635 // |
|
4636 |
|
4637 CCommandBase* CCmdTouch::NewLC() |
|
4638 { |
|
4639 CCmdTouch* self = new(ELeave) CCmdTouch(); |
|
4640 CleanupStack::PushL(self); |
|
4641 self->BaseConstructL(); |
|
4642 return self; |
|
4643 } |
|
4644 |
|
4645 CCmdTouch::~CCmdTouch() |
|
4646 { |
|
4647 } |
|
4648 |
|
4649 CCmdTouch::CCmdTouch() |
|
4650 { |
|
4651 } |
|
4652 |
|
4653 const TDesC& CCmdTouch::Name() const |
|
4654 { |
|
4655 _LIT(KName, "touch"); |
|
4656 return KName; |
|
4657 } |
|
4658 |
|
4659 void CCmdTouch::ArgumentsL(RCommandArgumentList& aArguments) |
|
4660 { |
|
4661 _LIT(KCmdArgFile, "file"); |
|
4662 aArguments.AppendFileNameL(iFileName, KCmdArgFile); |
|
4663 } |
|
4664 |
|
4665 void CCmdTouch::DoRunL() |
|
4666 { |
|
4667 TEntry e; |
|
4668 TInt err = FsL().Entry(iFileName, e); |
|
4669 |
|
4670 if (err == KErrNotFound || err == KErrPathNotFound) |
|
4671 { |
|
4672 RFile file; |
|
4673 err = file.Create(Fs(), iFileName, EFileWrite); |
|
4674 LeaveIfErr(err, _L("Couldn't create file %S"), &iFileName); |
|
4675 file.Close(); |
|
4676 } |
|
4677 else |
|
4678 { |
|
4679 LeaveIfErr(err, _L("Couldn't get file info for %S"), &iFileName); |
|
4680 TTime now; |
|
4681 now.UniversalTime(); |
|
4682 err = Fs().SetEntry(iFileName, now, 0, 0); |
|
4683 LeaveIfErr(err, _L("Couldn't update last-modified date for %S"), &iFileName); |
|
4684 } |
|
4685 } |
|
4686 |
|
4687 |
|
4688 // |
|
4689 // CCmdDialog. |
|
4690 // |
|
4691 |
|
4692 CCommandBase* CCmdDialog::NewLC() |
|
4693 { |
|
4694 CCmdDialog* self = new(ELeave) CCmdDialog(); |
|
4695 CleanupStack::PushL(self); |
|
4696 self->BaseConstructL(); |
|
4697 return self; |
|
4698 } |
|
4699 |
|
4700 CCmdDialog::~CCmdDialog() |
|
4701 { |
|
4702 delete iTitle; |
|
4703 delete iBody; |
|
4704 delete iButton1; |
|
4705 delete iButton2; |
|
4706 } |
|
4707 |
|
4708 CCmdDialog::CCmdDialog() : CCommandBase(EManualComplete) |
|
4709 { |
|
4710 } |
|
4711 |
|
4712 const TDesC& CCmdDialog::Name() const |
|
4713 { |
|
4714 _LIT(KName, "dialog"); |
|
4715 return KName; |
|
4716 } |
|
4717 |
|
4718 CCmdDialog::TMode CCmdDialog::ModeL() const |
|
4719 { |
|
4720 _LIT(KDialogImpl, "DIALOG_IMPL"); |
|
4721 _LIT(KImplNotifier, "notifier"); |
|
4722 _LIT(KImplConsole, "console"); |
|
4723 _LIT(KImplNull, "null"); |
|
4724 |
|
4725 TMode mode = EModeNotifier; |
|
4726 if (Env().IsDefined(KDialogImpl)) |
|
4727 { |
|
4728 const TDesC& impl = Env().GetAsDesL(KDialogImpl); |
|
4729 if (impl == KImplNotifier) |
|
4730 { |
|
4731 mode = EModeNotifier; |
|
4732 } |
|
4733 else if (impl == KImplConsole) |
|
4734 { |
|
4735 mode = EModeConsole; |
|
4736 } |
|
4737 else if (impl == KImplNull) |
|
4738 { |
|
4739 mode = EModeNull; |
|
4740 } |
|
4741 } |
|
4742 |
|
4743 return mode; |
|
4744 } |
|
4745 |
|
4746 void CCmdDialog::DoRunL() |
|
4747 { |
|
4748 if (iTitle == NULL) |
|
4749 { |
|
4750 iTitle = _L("Attention").AllocL(); |
|
4751 } |
|
4752 if ((iButton1 == NULL) && (iButton2 == NULL)) |
|
4753 { |
|
4754 iButton1 = _L("OK").AllocL(); |
|
4755 iButton2 = _L("Cancel").AllocL(); |
|
4756 } |
|
4757 else if (iButton2 == NULL) |
|
4758 { |
|
4759 iButton2 = KNullDesC().AllocL(); |
|
4760 } |
|
4761 else if (iButton1 == NULL) |
|
4762 { |
|
4763 LeaveIfErr(KErrArgument, _L("First button not specified")); |
|
4764 } |
|
4765 |
|
4766 if (iBody == NULL) |
|
4767 { |
|
4768 iBody = HBufC::NewL(0x200); |
|
4769 Stdin().SetReadMode(RIoReadHandle::EFull); |
|
4770 TPtr ptr(iBody->Des()); |
|
4771 Stdin().ReadL(ptr); |
|
4772 } |
|
4773 |
|
4774 switch (ModeL()) |
|
4775 { |
|
4776 case EModeNotifier: |
|
4777 { |
|
4778 RNotifier notifier; |
|
4779 User::LeaveIfError(notifier.Connect()); |
|
4780 CleanupClosePushL(notifier); |
|
4781 |
|
4782 TInt buttonValue; |
|
4783 TRequestStatus status; |
|
4784 notifier.Notify(*iTitle, *iBody, *iButton1, *iButton2, buttonValue, status); |
|
4785 User::WaitForRequest(status); |
|
4786 Complete(buttonValue); |
|
4787 |
|
4788 CleanupStack::PopAndDestroy(¬ifier); |
|
4789 break; |
|
4790 } |
|
4791 case EModeConsole: |
|
4792 { |
|
4793 RIoConsole console; |
|
4794 console.OpenL(IoSession(), Stdin()); |
|
4795 CleanupClosePushL(console); |
|
4796 |
|
4797 RIoConsoleWriteHandle consWriter; |
|
4798 consWriter.CreateL(IoSession()); |
|
4799 CleanupClosePushL(consWriter); |
|
4800 console.AttachL(consWriter); |
|
4801 |
|
4802 RIoConsoleReadHandle consReader; |
|
4803 consReader.CreateL(IoSession()); |
|
4804 CleanupClosePushL(consReader); |
|
4805 console.AttachL(consReader, RIoEndPoint::EForeground); |
|
4806 |
|
4807 consWriter.Write(*iTitle); |
|
4808 consWriter.Write(KNewLine); |
|
4809 consWriter.Write(KNewLine); |
|
4810 consWriter.Write(*iBody); |
|
4811 consWriter.Write(KNewLine); |
|
4812 consWriter.Write(KNewLine); |
|
4813 { |
|
4814 TBuf<0x100> buf; |
|
4815 buf.AppendFormat(_L("%S <enter / select> or %S <any other key> "), iButton1, iButton2); |
|
4816 consWriter.Write(buf); |
|
4817 } |
|
4818 TBuf<1> buf; |
|
4819 consReader.ReadL(buf); |
|
4820 ClearLineL(consWriter); |
|
4821 CleanupStack::PopAndDestroy(3); // consReader, consWriter, console |
|
4822 switch (buf[0]) |
|
4823 { |
|
4824 case EKeyEnter: |
|
4825 #ifdef FSHELL_PLATFORM_S60 |
|
4826 case EKeyDevice3: |
|
4827 #endif |
|
4828 Complete(0); |
|
4829 break; |
|
4830 default: |
|
4831 Complete(1); |
|
4832 break; |
|
4833 } |
|
4834 break; |
|
4835 } |
|
4836 case EModeNull: |
|
4837 { |
|
4838 Complete(0); |
|
4839 break; |
|
4840 } |
|
4841 } |
|
4842 } |
|
4843 |
|
4844 void CCmdDialog::ClearLineL(RIoConsoleWriteHandle& aWriteHandle) |
|
4845 { |
|
4846 if (aWriteHandle.AttachedToConsole()) |
|
4847 { |
|
4848 TPoint cursorPos; |
|
4849 LeaveIfErr(aWriteHandle.GetCursorPos(cursorPos), _L("Couldn't get cursor position")); |
|
4850 cursorPos.iX = 0; |
|
4851 LeaveIfErr(aWriteHandle.SetCursorPosAbs(cursorPos), _L("Couldn't set cursor position to beginning of line")); |
|
4852 LeaveIfErr(aWriteHandle.ClearToEndOfLine(), _L("Couldn't clear to end of line")); |
|
4853 } |
|
4854 else |
|
4855 { |
|
4856 aWriteHandle.Write(KNewLine); |
|
4857 } |
|
4858 } |
|
4859 |
|
4860 void CCmdDialog::OptionsL(RCommandOptionList& aOptions) |
|
4861 { |
|
4862 _LIT(KOptTitle, "title"); |
|
4863 _LIT(KOptButton1, "first-button"); |
|
4864 _LIT(KOptButton2, "second-button"); |
|
4865 |
|
4866 aOptions.AppendStringL(iTitle, KOptTitle); |
|
4867 aOptions.AppendStringL(iButton1, KOptButton1); |
|
4868 aOptions.AppendStringL(iButton2, KOptButton2); |
|
4869 } |
|
4870 |
|
4871 void CCmdDialog::ArgumentsL(RCommandArgumentList& aArguments) |
|
4872 { |
|
4873 _LIT(KArgBody, "body"); |
|
4874 aArguments.AppendStringL(iBody, KArgBody); |
|
4875 } |
|
4876 |
|
4877 |
|
4878 // |
|
4879 // CCmdJit. |
|
4880 // |
|
4881 |
|
4882 #ifdef __WINS__ |
|
4883 |
|
4884 CCommandBase* CCmdJit::NewLC() |
|
4885 { |
|
4886 CCmdJit* self = new(ELeave) CCmdJit(); |
|
4887 CleanupStack::PushL(self); |
|
4888 self->BaseConstructL(); |
|
4889 return self; |
|
4890 } |
|
4891 |
|
4892 CCmdJit::~CCmdJit() |
|
4893 { |
|
4894 } |
|
4895 |
|
4896 CCmdJit::CCmdJit() |
|
4897 { |
|
4898 } |
|
4899 |
|
4900 const TDesC& CCmdJit::Name() const |
|
4901 { |
|
4902 _LIT(KName, "jit"); |
|
4903 return KName; |
|
4904 } |
|
4905 |
|
4906 void CCmdJit::DoRunL() |
|
4907 { |
|
4908 switch (iOperation) |
|
4909 { |
|
4910 case EStatus: |
|
4911 if (User::JustInTime()) |
|
4912 { |
|
4913 Write(_L("on\r\n")); |
|
4914 } |
|
4915 else |
|
4916 { |
|
4917 Write(_L("off\r\n")); |
|
4918 } |
|
4919 break; |
|
4920 case EOn: |
|
4921 User::SetJustInTime(ETrue); |
|
4922 break; |
|
4923 case EOff: |
|
4924 User::SetJustInTime(EFalse); |
|
4925 break; |
|
4926 default: |
|
4927 LeaveIfErr(KErrArgument, _L("Unrecognised operation")); |
|
4928 } |
|
4929 } |
|
4930 |
|
4931 void CCmdJit::ArgumentsL(RCommandArgumentList& aArguments) |
|
4932 { |
|
4933 _LIT(KArgOperation, "operation"); |
|
4934 aArguments.AppendEnumL((TInt&)iOperation, KArgOperation); |
|
4935 } |
|
4936 |
|
4937 #endif // __WINS__ |
|
4938 |
|
4939 |
|
4940 // |
|
4941 // CCmdConsole. |
|
4942 // |
|
4943 |
|
4944 CCommandBase* CCmdConsole::NewLC() |
|
4945 { |
|
4946 CCmdConsole* self = new(ELeave) CCmdConsole(); |
|
4947 CleanupStack::PushL(self); |
|
4948 self->BaseConstructL(); |
|
4949 return self; |
|
4950 } |
|
4951 |
|
4952 CCmdConsole::~CCmdConsole() |
|
4953 { |
|
4954 } |
|
4955 |
|
4956 CCmdConsole::CCmdConsole() |
|
4957 { |
|
4958 } |
|
4959 |
|
4960 const TDesC& CCmdConsole::Name() const |
|
4961 { |
|
4962 _LIT(KName, "console"); |
|
4963 return KName; |
|
4964 } |
|
4965 |
|
4966 _LIT(KPersistentConsole, " (persistent console)"); |
|
4967 |
|
4968 void CCmdConsole::DoRunL() |
|
4969 { |
|
4970 if (iIsRemote && iIsNull) |
|
4971 { |
|
4972 LeaveIfErr(KErrArgument, _L("-r and -n options are mutually exclusive")); |
|
4973 } |
|
4974 |
|
4975 RIoConsole console; |
|
4976 LeaveIfErr(console.Open(IoSession(), Stdout()), _L("Couldn't open handle to console")); |
|
4977 CleanupClosePushL(console); |
|
4978 |
|
4979 TFileName name; |
|
4980 if (console.IsTypeL(RIoHandle::EPersistentConsole)) |
|
4981 { |
|
4982 TInt err = console.ObjectName(name); |
|
4983 if (err!=KErrOverflow) User::LeaveIfError(err); |
|
4984 name.SetLength(Min(name.Length(), name.MaxLength()-KPersistentConsole().Length())); |
|
4985 name.Append(KPersistentConsole); |
|
4986 } |
|
4987 else |
|
4988 { |
|
4989 LeaveIfErr(console.Implementation(name), _L("Couldn't read console implemenation name")); |
|
4990 } |
|
4991 if (iIsRemote) |
|
4992 { |
|
4993 _LIT(KRconsPattern, "rcons*"); |
|
4994 _LIT(KVt100Pattern, "vt100*"); |
|
4995 Complete(!((name.MatchF(KRconsPattern) == 0) || (name.MatchF(KVt100Pattern) == 0))); |
|
4996 } |
|
4997 else if (iIsNull) |
|
4998 { |
|
4999 _LIT(KNullPattern, "nullcons*"); |
|
5000 Complete(!(name.MatchF(KNullPattern) == 0)); |
|
5001 } |
|
5002 else if (iVerbose) |
|
5003 { |
|
5004 TSize size; |
|
5005 LeaveIfErr(Stdout().GetScreenSize(size), _L("Couldn't get screen size")); |
|
5006 Printf(_L("Name: %S\r\n"), &name); |
|
5007 Printf(_L("Size: %dx%d\r\n"), size.iWidth, size.iHeight); |
|
5008 } |
|
5009 else |
|
5010 { |
|
5011 Write(name); |
|
5012 } |
|
5013 CleanupStack::PopAndDestroy(&console); |
|
5014 } |
|
5015 |
|
5016 void CCmdConsole::OptionsL(RCommandOptionList& aOptions) |
|
5017 { |
|
5018 _LIT(KOptIsRemote, "remote"); |
|
5019 _LIT(KOptIsNull, "null"); |
|
5020 |
|
5021 aOptions.AppendBoolL(iVerbose, KOptVerbose); |
|
5022 aOptions.AppendBoolL(iIsRemote, KOptIsRemote); |
|
5023 aOptions.AppendBoolL(iIsNull, KOptIsNull); |
|
5024 } |
|
5025 |
|
5026 |
|
5027 // |
|
5028 // CCmdPcons. |
|
5029 // |
|
5030 |
|
5031 CCommandBase* CCmdPcons::NewLC() |
|
5032 { |
|
5033 CCmdPcons* self = new(ELeave) CCmdPcons(); |
|
5034 CleanupStack::PushL(self); |
|
5035 self->BaseConstructL(); |
|
5036 return self; |
|
5037 } |
|
5038 |
|
5039 CCmdPcons::~CCmdPcons() |
|
5040 { |
|
5041 delete iName; |
|
5042 delete iCommand; |
|
5043 delete iCommandArgs; |
|
5044 } |
|
5045 |
|
5046 CCmdPcons::CCmdPcons() |
|
5047 { |
|
5048 } |
|
5049 |
|
5050 const TDesC& CCmdPcons::Name() const |
|
5051 { |
|
5052 _LIT(KName, "pcons"); |
|
5053 return KName; |
|
5054 } |
|
5055 |
|
5056 _LIT(KNone, "-"); |
|
5057 _LIT(KDefaultCommand, "fshell"); |
|
5058 _LIT(KCurrentConsMarker, "(*)"); |
|
5059 _LIT(KNew, "new"); |
|
5060 _LIT(KExisting, "existing"); |
|
5061 |
|
5062 void CCmdPcons::DoRunL() |
|
5063 { |
|
5064 RIoPersistentConsole pcons; |
|
5065 CleanupClosePushL(pcons); |
|
5066 if ((iOperation != ENew) && (iOperation != EStart) && iCommand) |
|
5067 { |
|
5068 TPtrC operation(iArguments.AsString(&iOperation)); |
|
5069 PrintWarning(_L("'command' argument being ignored for operation %S"), &operation); |
|
5070 } |
|
5071 |
|
5072 switch (iOperation) |
|
5073 { |
|
5074 case EList: |
|
5075 { |
|
5076 RIoConsole thisCons; |
|
5077 LeaveIfErr(thisCons.Open(IoSession(), Stdout()), _L("Couldn't open handle to current console")); |
|
5078 CleanupClosePushL(thisCons); |
|
5079 |
|
5080 const TDesC& matchStr = iName ? *iName : KMatchAll(); |
|
5081 TInt foundHandle; |
|
5082 TName foundName; |
|
5083 TBool foundCurrent = EFalse; |
|
5084 |
|
5085 CTextBuffer* buf = CTextBuffer::NewLC(0x20); |
|
5086 _LIT(KColumnHeadings, "Name\tCreator\tReader\tWriter\r\n"); |
|
5087 buf->AppendL(KColumnHeadings); |
|
5088 TInt err = IoSession().FindFirstHandle(RIoHandle::EConsole, matchStr, foundHandle, foundName); |
|
5089 TInt count = 0; |
|
5090 while (err==KErrNone) |
|
5091 { |
|
5092 RIoPersistentConsole pcons; |
|
5093 pcons.OpenFoundHandleL(IoSession(), foundHandle); |
|
5094 CleanupClosePushL(pcons); |
|
5095 if (pcons.IsTypeL(RIoHandle::EPersistentConsole)) |
|
5096 { |
|
5097 count++; |
|
5098 buf->AppendL(foundName); |
|
5099 if (pcons.EqualsL(thisCons)) |
|
5100 { |
|
5101 buf->AppendL(KCurrentConsMarker); |
|
5102 foundCurrent = ETrue; |
|
5103 } |
|
5104 buf->AppendL(KTab); |
|
5105 |
|
5106 { |
|
5107 TThreadId creatorId = pcons.GetCreatorL(); |
|
5108 RThread creator; |
|
5109 if (creator.Open(creatorId)==KErrNone) |
|
5110 { |
|
5111 TFullName name; |
|
5112 LtkUtils::GetFriendlyThreadName(creator, name); |
|
5113 creator.Close(); |
|
5114 buf->AppendL(name); |
|
5115 buf->AppendL(KTab); |
|
5116 } |
|
5117 else |
|
5118 { |
|
5119 buf->AppendFormatL(_L("(%Ld)\t"), creatorId.Id()); |
|
5120 } |
|
5121 } |
|
5122 |
|
5123 { |
|
5124 TName readerName; |
|
5125 TName writerName; |
|
5126 pcons.GetAttachedReaderAndWriterNamesL(readerName, writerName); |
|
5127 |
|
5128 buf->AppendL(readerName.Length() ? readerName : KNone()); |
|
5129 buf->AppendL(KTab); |
|
5130 buf->AppendL(writerName.Length() ? writerName : KNone()); |
|
5131 buf->AppendL(KNewLine); |
|
5132 } |
|
5133 } |
|
5134 CleanupStack::PopAndDestroy(&pcons); |
|
5135 err = IoSession().FindNextHandle(foundHandle, foundName); |
|
5136 } |
|
5137 if (err!=KErrNotFound) User::LeaveIfError(err); |
|
5138 if (count) |
|
5139 { |
|
5140 CTextFormatter* tf = CTextFormatter::NewLC(Stdout()); |
|
5141 // if this fails, it's probably just because the console is too narrow; just print it |
|
5142 // untabulated in this case. |
|
5143 TRAP(err, tf->TabulateL(0, 2, buf->Descriptor())); |
|
5144 if (err==KErrNone) |
|
5145 { |
|
5146 Write(tf->Descriptor()); |
|
5147 } |
|
5148 else |
|
5149 { |
|
5150 Write(buf->Descriptor()); |
|
5151 } |
|
5152 CleanupStack::PopAndDestroy(tf); |
|
5153 } |
|
5154 if (foundCurrent) |
|
5155 { |
|
5156 Write(KCurrentConsMarker); |
|
5157 Write(_L(" indicates current console")); |
|
5158 } |
|
5159 CleanupStack::PopAndDestroy(2, &thisCons); |
|
5160 break; |
|
5161 } |
|
5162 case EStart: |
|
5163 { |
|
5164 if (!iName) |
|
5165 { |
|
5166 PrintError(KErrArgument, _L("A persistent console name to start to must be specified")); |
|
5167 DisplayHelp(); |
|
5168 break; |
|
5169 } |
|
5170 TInt err = pcons.OpenByName(IoSession(), *iName); |
|
5171 const TDesC* newOrExisting; |
|
5172 if (err==KErrNone) |
|
5173 { |
|
5174 newOrExisting = &KExisting; |
|
5175 if (iCommand) |
|
5176 { |
|
5177 PrintWarning(_L("Ignoring 'command' argument as console already exists.")); |
|
5178 } |
|
5179 } |
|
5180 else |
|
5181 { |
|
5182 newOrExisting = &KNew; |
|
5183 CreateL(pcons); |
|
5184 } |
|
5185 AttachL(pcons, *newOrExisting, ETrue); |
|
5186 break; |
|
5187 } |
|
5188 case EConnect: |
|
5189 { |
|
5190 if (!iName) |
|
5191 { |
|
5192 PrintError(KErrArgument, _L("A persistent console name to connect to must be specified")); |
|
5193 DisplayHelp(); |
|
5194 break; |
|
5195 } |
|
5196 LeaveIfErr(pcons.OpenByName(IoSession(), *iName), _L("Couldn't open persistent console with name %S"), iName); |
|
5197 AttachL(pcons, KExisting, EFalse); |
|
5198 break; |
|
5199 } |
|
5200 case EDisconnect: |
|
5201 { |
|
5202 if (iName) |
|
5203 { |
|
5204 LeaveIfErr(pcons.OpenByName(IoSession(), *iName), _L("Couldn't open persistent console with name %S"), iName); |
|
5205 } |
|
5206 else |
|
5207 { |
|
5208 LeaveIfErr(pcons.Open(IoSession(), Stdout()), _L("Couldn't open handle to console")); |
|
5209 if (!pcons.IsTypeL(RIoHandle::EPersistentConsole)) |
|
5210 { |
|
5211 LeaveIfErr(KErrNotSupported, _L("Not connected to a persistent console")); |
|
5212 } |
|
5213 } |
|
5214 pcons.DetachReader(); |
|
5215 pcons.DetachWriter(); |
|
5216 break; |
|
5217 } |
|
5218 case ENew: |
|
5219 { |
|
5220 if (!iName) |
|
5221 { |
|
5222 PrintError(KErrArgument, _L("A name for the new persistent console must be specified")); |
|
5223 DisplayHelp(); |
|
5224 break; |
|
5225 } |
|
5226 CreateL(pcons); |
|
5227 break; |
|
5228 } |
|
5229 } |
|
5230 CleanupStack::PopAndDestroy(&pcons); |
|
5231 } |
|
5232 |
|
5233 void CCmdPcons::CreateL(RIoPersistentConsole& aPcons) |
|
5234 { |
|
5235 const TDesC& command(iCommand ? *iCommand : KDefaultCommand()); |
|
5236 const TDesC& args(iCommandArgs ? *iCommandArgs : KNullDesC()); |
|
5237 |
|
5238 LeaveIfErr(aPcons.Create(IoSession(), *iName, *iName), _L("Could not create persistent console '%S'"), iName); |
|
5239 |
|
5240 RChildProcess proc; |
|
5241 TRAPL(proc.CreateL(command, args, IoSession(), aPcons, &Env()), _L("Could not create process %S"), &command); |
|
5242 |
|
5243 proc.Detach(); |
|
5244 proc.Close(); |
|
5245 } |
|
5246 |
|
5247 TInt CCmdPcons::DoAttach(RIoPersistentConsole& aPcons, RIoConsole& aNew, RIoPersistentConsole::TCloseBehaviour aOnClose) |
|
5248 { |
|
5249 TInt err = aPcons.AttachWriter(aNew, aOnClose); |
|
5250 if (err==KErrNone) |
|
5251 { |
|
5252 err = aPcons.AttachReader(aNew, aOnClose); |
|
5253 if (err!=KErrNone) |
|
5254 { |
|
5255 aPcons.DetachWriter(); |
|
5256 } |
|
5257 } |
|
5258 return err; |
|
5259 } |
|
5260 |
|
5261 void CCmdPcons::AttachL(RIoPersistentConsole& aPcons, const TDesC& aNewOrExisting, TBool aForce) |
|
5262 { |
|
5263 RIoConsole thisCons; |
|
5264 LeaveIfErr(thisCons.Open(IoSession(), Stdout()), _L("Couldn't open handle to current console")); |
|
5265 CleanupClosePushL(thisCons); |
|
5266 |
|
5267 TBool usingExistingConsole = !ConsoleImplementation(); |
|
5268 RIoPersistentConsole::TCloseBehaviour onClose = |
|
5269 usingExistingConsole ? |
|
5270 RIoPersistentConsole::EDetachOnHandleClose : |
|
5271 RIoPersistentConsole::EKeepAttachedOnHandleClose; |
|
5272 |
|
5273 if (usingExistingConsole) |
|
5274 { |
|
5275 Printf(_L("pcons: connecting to %S console %S.\r\n"), &aNewOrExisting, iName); |
|
5276 } |
|
5277 TInt err = DoAttach(aPcons, thisCons, onClose); |
|
5278 if ((err == KErrInUse) && (aForce)) |
|
5279 { |
|
5280 if (iVerbose) Printf(_L("Detaching existing connection from %S"), iName); |
|
5281 aPcons.DetachReader(); |
|
5282 aPcons.DetachWriter(); |
|
5283 err = DoAttach(aPcons, thisCons, onClose); |
|
5284 } |
|
5285 LeaveIfErr(err, _L("Could not connect to persistent console %S"), iName); |
|
5286 |
|
5287 if (usingExistingConsole) |
|
5288 { |
|
5289 // we've not been a custom console implementation |
|
5290 // so we need to wait until the persistent side is disconnected. |
|
5291 TRequestStatus readerDetach; |
|
5292 TRequestStatus writerDetach; |
|
5293 aPcons.NotifyReaderDetach(readerDetach); |
|
5294 aPcons.NotifyWriterDetach(writerDetach); |
|
5295 User::WaitForRequest(readerDetach); |
|
5296 if (iVerbose) Printf(_L("Persistent console reader detached; waiting for writer to detach\r\n")); |
|
5297 User::WaitForRequest(writerDetach); |
|
5298 if (iVerbose) Printf(_L("Persistent console writer detached\r\n")); |
|
5299 if (Stdout().GetCursorPosL().iX != 0) Printf(KNewLine); |
|
5300 Printf(_L("pcons: disconnected from %S\r\n"), iName); |
|
5301 } |
|
5302 |
|
5303 CleanupStack::PopAndDestroy(&thisCons); |
|
5304 } |
|
5305 |
|
5306 void CCmdPcons::ArgumentsL(RCommandArgumentList& aArguments) |
|
5307 { |
|
5308 _LIT(KOperationName, "operation"); |
|
5309 _LIT(KNameName, "name"); |
|
5310 _LIT(KArgCommand, "command"); |
|
5311 _LIT(KCommandArgs, "command_args"); |
|
5312 |
|
5313 aArguments.AppendEnumL((TInt&)iOperation, KOperationName); |
|
5314 aArguments.AppendStringL(iName, KNameName); |
|
5315 aArguments.AppendStringL(iCommand, KArgCommand); |
|
5316 aArguments.AppendStringL(iCommandArgs, KCommandArgs); |
|
5317 } |
|
5318 |
|
5319 void CCmdPcons::OptionsL(RCommandOptionList& aOptions) |
|
5320 { |
|
5321 aOptions.AppendBoolL(iVerbose, KOptVerbose); |
|
5322 } |
|
5323 |
|
5324 |
|
5325 // |
|
5326 // CCmdIoInfo. |
|
5327 // |
|
5328 |
|
5329 CCommandBase* CCmdIoInfo::NewLC() |
|
5330 { |
|
5331 CCmdIoInfo* self = new(ELeave) CCmdIoInfo(); |
|
5332 CleanupStack::PushL(self); |
|
5333 self->BaseConstructL(); |
|
5334 return self; |
|
5335 } |
|
5336 |
|
5337 CCmdIoInfo::~CCmdIoInfo() |
|
5338 { |
|
5339 delete iMatchString; |
|
5340 } |
|
5341 |
|
5342 CCmdIoInfo::CCmdIoInfo() |
|
5343 { |
|
5344 } |
|
5345 |
|
5346 const TDesC& CCmdIoInfo::Name() const |
|
5347 { |
|
5348 _LIT(KName, "ioinfo"); |
|
5349 return KName; |
|
5350 } |
|
5351 |
|
5352 void CCmdIoInfo::DoRunL() |
|
5353 { |
|
5354 TInt foundHandle; |
|
5355 TName name; |
|
5356 TInt err = IoSession().FindFirstHandle(iObjectType, iMatchString ? *iMatchString : KMatchAll(), foundHandle, name); |
|
5357 while (err==KErrNone) |
|
5358 { |
|
5359 Write(name); |
|
5360 Write(KNewLine); |
|
5361 err = IoSession().FindNextHandle(foundHandle, name); |
|
5362 } |
|
5363 if (err!=KErrNotFound) User::LeaveIfError(err); |
|
5364 } |
|
5365 |
|
5366 void CCmdIoInfo::ArgumentsL(RCommandArgumentList& aArguments) |
|
5367 { |
|
5368 _LIT(KObjectType, "object_type"); |
|
5369 aArguments.AppendEnumL((TInt&)iObjectType, KObjectType); |
|
5370 } |
|
5371 |
|
5372 void CCmdIoInfo::OptionsL(RCommandOptionList& aOptions) |
|
5373 { |
|
5374 _LIT(KMatch, "match"); |
|
5375 aOptions.AppendStringL(iMatchString, KMatch); |
|
5376 } |
|
5377 |
|
5378 |
|
5379 // |
|
5380 // CCmdReattach. |
|
5381 // |
|
5382 |
|
5383 CCommandBase* CCmdReattach::NewLC() |
|
5384 { |
|
5385 CCmdReattach* self = new(ELeave) CCmdReattach(); |
|
5386 CleanupStack::PushL(self); |
|
5387 self->BaseConstructL(); |
|
5388 return self; |
|
5389 } |
|
5390 |
|
5391 CCmdReattach::~CCmdReattach() |
|
5392 { |
|
5393 delete iJobSpec; |
|
5394 delete iStdinEndPointName; |
|
5395 delete iStdoutEndPointName; |
|
5396 delete iStderrEndPointName; |
|
5397 } |
|
5398 |
|
5399 CCmdReattach::CCmdReattach() : CCommandBase(EManualComplete) |
|
5400 { |
|
5401 } |
|
5402 |
|
5403 const TDesC& CCmdReattach::Name() const |
|
5404 { |
|
5405 _LIT(KName, "reattach"); |
|
5406 return KName; |
|
5407 } |
|
5408 |
|
5409 void CCmdReattach::OpenEndPointLC(RIoEndPoint& aEndPoint, const TDesC& aName) |
|
5410 { |
|
5411 TInt foundHandle; |
|
5412 TName name; |
|
5413 LeaveIfErr(IoSession().FindFirstHandle(RIoHandle::EEndPoint, aName, foundHandle, name), _L("Couldn't find and end point named \"%S\""), &aName); |
|
5414 aEndPoint.OpenFoundHandleL(IoSession(), foundHandle); |
|
5415 CleanupClosePushL(aEndPoint); |
|
5416 } |
|
5417 |
|
5418 void CCmdReattach::DoRunL() |
|
5419 { |
|
5420 TInt jobId = -1; |
|
5421 ParseJobSpecL(*iJobSpec, jobId); |
|
5422 RIoEndPoint stdinEndPoint; |
|
5423 RIoEndPoint stdoutEndPoint; |
|
5424 RIoEndPoint stderrEndPoint; |
|
5425 if (iStdinEndPointName) |
|
5426 { |
|
5427 OpenEndPointLC(stdinEndPoint, *iStdinEndPointName); |
|
5428 } |
|
5429 else |
|
5430 { |
|
5431 static_cast<RIoNull&>(stdinEndPoint).CreateL(IoSession()); |
|
5432 CleanupClosePushL(stdinEndPoint); |
|
5433 } |
|
5434 TInt numCleanupPushes = 1; |
|
5435 if (iStdoutEndPointName) |
|
5436 { |
|
5437 OpenEndPointLC(stdoutEndPoint, *iStdoutEndPointName); |
|
5438 ++numCleanupPushes; |
|
5439 } |
|
5440 else |
|
5441 { |
|
5442 stdoutEndPoint = stdinEndPoint; |
|
5443 } |
|
5444 if (iStderrEndPointName) |
|
5445 { |
|
5446 OpenEndPointLC(stderrEndPoint, *iStderrEndPointName); |
|
5447 ++numCleanupPushes; |
|
5448 } |
|
5449 else |
|
5450 { |
|
5451 stderrEndPoint = stdoutEndPoint; |
|
5452 } |
|
5453 |
|
5454 gShell->ClaimJobsLockLC(); |
|
5455 CJob* job = gShell->Job(jobId); |
|
5456 if (job) |
|
5457 { |
|
5458 TInt err = job->Reattach(stdinEndPoint, stdoutEndPoint, stderrEndPoint); |
|
5459 CleanupStack::PopAndDestroy(); // jobs lock. |
|
5460 if (err) |
|
5461 { |
|
5462 Complete(err, _L("Couldn't reattach job %S"), iJobSpec); |
|
5463 } |
|
5464 else |
|
5465 { |
|
5466 Complete(); |
|
5467 } |
|
5468 } |
|
5469 else |
|
5470 { |
|
5471 CleanupStack::PopAndDestroy(); // jobs lock. |
|
5472 Complete(KErrNotFound, _L("Job %S not found"), iJobSpec); |
|
5473 } |
|
5474 |
|
5475 CleanupStack::PopAndDestroy(numCleanupPushes); |
|
5476 } |
|
5477 |
|
5478 void CCmdReattach::ArgumentsL(RCommandArgumentList& aArguments) |
|
5479 { |
|
5480 _LIT(KArgJobSpec, "job"); |
|
5481 _LIT(KArgStdinEndPointName, "stdin"); |
|
5482 _LIT(KArgStdoutEndPointName, "stdout"); |
|
5483 _LIT(KArgStderrEndPointName, "stderr"); |
|
5484 |
|
5485 aArguments.AppendStringL(iJobSpec, KArgJobSpec); |
|
5486 aArguments.AppendStringL(iStdinEndPointName, KArgStdinEndPointName); |
|
5487 aArguments.AppendStringL(iStdoutEndPointName, KArgStdoutEndPointName); |
|
5488 aArguments.AppendStringL(iStderrEndPointName, KArgStderrEndPointName); |
|
5489 } |
|
5490 |
|
5491 |
|
5492 // |
|
5493 // CCmdDisown. |
|
5494 // |
|
5495 |
|
5496 CCommandBase* CCmdDisown::NewLC() |
|
5497 { |
|
5498 CCmdDisown* self = new(ELeave) CCmdDisown(); |
|
5499 CleanupStack::PushL(self); |
|
5500 self->BaseConstructL(); |
|
5501 return self; |
|
5502 } |
|
5503 |
|
5504 CCmdDisown::~CCmdDisown() |
|
5505 { |
|
5506 delete iJobSpec; |
|
5507 } |
|
5508 |
|
5509 CCmdDisown::CCmdDisown() : CCommandBase(EManualComplete) |
|
5510 { |
|
5511 } |
|
5512 |
|
5513 const TDesC& CCmdDisown::Name() const |
|
5514 { |
|
5515 _LIT(KName, "disown"); |
|
5516 return KName; |
|
5517 } |
|
5518 |
|
5519 void CCmdDisown::DoRunL() |
|
5520 { |
|
5521 TInt jobId = -1; |
|
5522 ParseJobSpecL(*iJobSpec, jobId); |
|
5523 gShell->ClaimJobsLockLC(); |
|
5524 TInt err = gShell->DisownJob(jobId); |
|
5525 CleanupStack::PopAndDestroy(); // jobs lock. |
|
5526 if (err) |
|
5527 { |
|
5528 Complete(err, _L("Couldn't disown job %S"), iJobSpec); |
|
5529 } |
|
5530 else |
|
5531 { |
|
5532 Complete(); |
|
5533 } |
|
5534 } |
|
5535 |
|
5536 void CCmdDisown::ArgumentsL(RCommandArgumentList& aArguments) |
|
5537 { |
|
5538 _LIT(KArgJobSpec, "job_spec"); |
|
5539 aArguments.AppendStringL(iJobSpec, KArgJobSpec); |
|
5540 } |
|
5541 |
|
5542 |
|
5543 // |
|
5544 // CCmdDebugPort |
|
5545 // |
|
5546 |
|
5547 CCommandBase* CCmdDebugPort::NewLC() |
|
5548 { |
|
5549 CCmdDebugPort* self = new(ELeave) CCmdDebugPort(); |
|
5550 CleanupStack::PushL(self); |
|
5551 self->BaseConstructL(); |
|
5552 return self; |
|
5553 } |
|
5554 |
|
5555 CCmdDebugPort::~CCmdDebugPort() |
|
5556 { |
|
5557 } |
|
5558 |
|
5559 CCmdDebugPort::CCmdDebugPort() |
|
5560 { |
|
5561 } |
|
5562 |
|
5563 const TDesC& CCmdDebugPort::Name() const |
|
5564 { |
|
5565 _LIT(KName, "debugport"); |
|
5566 return KName; |
|
5567 } |
|
5568 |
|
5569 void CCmdDebugPort::DoRunL() |
|
5570 { |
|
5571 if (iArguments.IsPresent(0)) |
|
5572 { |
|
5573 if (iForce) |
|
5574 { |
|
5575 LoadMemoryAccessL(); |
|
5576 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
5577 LeaveIfErr(iMemAccess.SetDebugPort(iPort), _L("Couldn't set debug port")); |
|
5578 #endif |
|
5579 } |
|
5580 else |
|
5581 { |
|
5582 LeaveIfErr(HAL::Set(HAL::EDebugPort, iPort), _L("Couldn't set debug port (Try --force).")); |
|
5583 } |
|
5584 } |
|
5585 else |
|
5586 { |
|
5587 TInt debugport = 0; |
|
5588 TInt err = HAL::Get(HAL::EDebugPort, debugport); |
|
5589 LeaveIfErr(err, _L("Couldn't read debug port.")); |
|
5590 Printf(_L("Debug port: %d\r\n"), debugport); |
|
5591 } |
|
5592 } |
|
5593 |
|
5594 void CCmdDebugPort::ArgumentsL(RCommandArgumentList& aArguments) |
|
5595 { |
|
5596 _LIT(KArgPort, "port"); |
|
5597 aArguments.AppendIntL(iPort, KArgPort); |
|
5598 } |
|
5599 |
|
5600 void CCmdDebugPort::OptionsL(RCommandOptionList& aOptions) |
|
5601 { |
|
5602 _LIT(KOptForce, "force"); |
|
5603 aOptions.AppendBoolL(iForce, KOptForce); |
|
5604 } |
|
5605 |
|
5606 |
|
5607 // |
|
5608 // CCmdRom |
|
5609 // |
|
5610 |
|
5611 CCommandBase* CCmdRom::NewLC() |
|
5612 { |
|
5613 CCmdRom* self = new(ELeave) CCmdRom(); |
|
5614 CleanupStack::PushL(self); |
|
5615 self->BaseConstructL(); |
|
5616 return self; |
|
5617 } |
|
5618 |
|
5619 CCmdRom::~CCmdRom() |
|
5620 { |
|
5621 delete iBuffer; |
|
5622 } |
|
5623 |
|
5624 CCmdRom::CCmdRom() |
|
5625 { |
|
5626 } |
|
5627 |
|
5628 const TDesC& CCmdRom::Name() const |
|
5629 { |
|
5630 _LIT(KName, "rom"); |
|
5631 return KName; |
|
5632 } |
|
5633 |
|
5634 void CCmdRom::PrintIntL(TInt32 aInt32, const TDesC& aLabel, const TDesC& aDescription) |
|
5635 { |
|
5636 _LIT(KFormat, "%S:\t%d (0x%08x)\t%S\r\n"); |
|
5637 iBuffer->AppendFormatL(KFormat, &aLabel, aInt32, aInt32, &aDescription); |
|
5638 } |
|
5639 |
|
5640 void CCmdRom::PrintIntL(TInt64 aInt64, const TDesC& aLabel, const TDesC& aDescription) |
|
5641 { |
|
5642 _LIT(KFormat, "%S:\t%Ld\t%S\r\n"); |
|
5643 iBuffer->AppendFormatL(KFormat, &aLabel, aInt64, &aDescription); |
|
5644 } |
|
5645 |
|
5646 void CCmdRom::PrintUintL(TUint32 aUint32, const TDesC& aLabel, const TDesC& aDescription) |
|
5647 { |
|
5648 _LIT(KFormat, "%S:\t%u (0x%08x)\t%S\r\n"); |
|
5649 iBuffer->AppendFormatL(KFormat, &aLabel, aUint32, aUint32, &aDescription); |
|
5650 } |
|
5651 |
|
5652 void CCmdRom::PrintUintL(TUint64 aUint64, const TDesC& aLabel, const TDesC& aDescription) |
|
5653 { |
|
5654 _LIT(KFormat, "%S:\t%Lu\t%S\r\n"); |
|
5655 iBuffer->AppendFormatL(KFormat, &aLabel, aUint64, &aDescription); |
|
5656 } |
|
5657 |
|
5658 void CCmdRom::PrintAddressL(TLinAddr aAddress, const TDesC& aLabel, const TDesC& aDescription) |
|
5659 { |
|
5660 _LIT(KFormat, "%S:\t0x%08x\t%S\r\n"); |
|
5661 iBuffer->AppendFormatL(KFormat, &aLabel, aAddress, &aDescription, &aDescription); |
|
5662 } |
|
5663 |
|
5664 void CCmdRom::PrintSizeL(TInt32 aSize, const TDesC& aLabel, const TDesC& aDescription) |
|
5665 { |
|
5666 if (iHumanReadable) |
|
5667 { |
|
5668 _LIT(KFormat1, "%S:\t"); |
|
5669 iBuffer->AppendFormatL(KFormat1, &aLabel); |
|
5670 iBuffer->AppendHumanReadableSizeL((TInt)aSize, EUnaligned); |
|
5671 _LIT(KFormat2, "\t%S\r\n"); |
|
5672 iBuffer->AppendFormatL(KFormat2, &aDescription); |
|
5673 } |
|
5674 else |
|
5675 { |
|
5676 PrintIntL(aSize, aLabel, aDescription); |
|
5677 } |
|
5678 } |
|
5679 |
|
5680 void CCmdRom::PrintTimeL(TInt64 aTime, const TDesC& aLabel, const TDesC& aDescription) |
|
5681 { |
|
5682 if (iHumanReadable) |
|
5683 { |
|
5684 TTime time(aTime); |
|
5685 TDateTime dateTime(time.DateTime()); |
|
5686 _LIT(KFormat, "%S:\t%+02d/%+02d/%+04d %+02d:%+02d:%+02d.%+06d\t%S\r\n"); |
|
5687 iBuffer->AppendFormatL(KFormat, &aLabel, dateTime.Day() + 1, dateTime.Month() + 1, dateTime.Year(), dateTime.Hour(), dateTime.Minute(), dateTime.Second(), dateTime.MicroSecond(), &aDescription); |
|
5688 } |
|
5689 else |
|
5690 { |
|
5691 PrintIntL(aTime, aLabel, aDescription); |
|
5692 } |
|
5693 } |
|
5694 |
|
5695 void CCmdRom::PrintVersionL(TVersion aVersion, const TDesC& aLabel, const TDesC& aDescription) |
|
5696 { |
|
5697 _LIT(KFormat, "%S:\t%d.%d (build %d)\t%S\r\n"); |
|
5698 iBuffer->AppendFormatL(KFormat, &aLabel, aVersion.iMajor, aVersion.iMinor, aVersion.iBuild, &aDescription); |
|
5699 } |
|
5700 |
|
5701 void CCmdRom::DoRunL() |
|
5702 { |
|
5703 #ifdef __WINS__ |
|
5704 LeaveIfErr(KErrNotSupported, _L("This command is not supported on the emulator")); |
|
5705 #endif |
|
5706 |
|
5707 TRomHeader* header = (TRomHeader*)UserSvr::RomHeaderAddress(); |
|
5708 |
|
5709 iBuffer = CTextBuffer::NewL(0x100); |
|
5710 |
|
5711 PrintVersionL(header->iVersion, _L("iVersion"), _L("The ROM version number.")); |
|
5712 PrintTimeL(header->iTime, _L("iTime"), _L("The time and date that the ROM image was built.")); |
|
5713 PrintSizeL(header->iRomSize, _L("iRomSize"), _L("The size of the ROM image. This includes the second section for sectioned ROMs.")); |
|
5714 PrintUintL((TUint32)header->iCheckSum, _L("iCheckSum"), _L("A computed constant that causes the 32-bit checksum of the image to equal the value specified by the \"romchecksum\" keyword.")); |
|
5715 PrintUintL(header->iKernelConfigFlags, _L("iKernelConfigFlags"), _L("Contains the flags that define the security options in force. See TKernelConfigFlags for details.")); |
|
5716 |
|
5717 if (iVerbose) |
|
5718 { |
|
5719 PrintAddressL(header->iRestartVector, _L("iRestartVector"), _L("The restart vector")); |
|
5720 PrintUintL(header->iTimeHi, _L("iTimeHi"), _L("The high order 32 bits of the ROM image build time and date.")); |
|
5721 PrintAddressL(header->iRomBase, _L("iRomBase"), _L("The virtual address of the base of the ROM.")); |
|
5722 PrintAddressL(header->iRomRootDirectoryList, _L("iRomRootDirectoryList"), _L("The virtual address of the TRomRootDirectoryList structure.")); |
|
5723 PrintAddressL(header->iKernDataAddress, _L("iKernDataAddress"), _L("The virtual address of kernel data, when in RAM.")); |
|
5724 PrintAddressL(header->iKernelLimit, _L("iKernelLimit"), _L("The virtual address of the top of the kernel region, when in RAM.")); |
|
5725 PrintAddressL(header->iPrimaryFile, _L("iPrimaryFile"), _L("The virtual address of the primarys ROM file image header.")); |
|
5726 PrintAddressL(header->iSecondaryFile, _L("iSecondaryFile"), _L("The virtual address of the secondarys ROM file image header.")); |
|
5727 PrintUintL(header->iHardware, _L("iHardware"), _L("A unique number identifying the hardware for which this ROM image has been built. Note that this is only used for testing purposes.")); |
|
5728 PrintIntL(header->iLanguage, _L("iLanguage"), _L("A bitmask identifying which of the languages are supported by the ROM image, as specified by the \"languages\" keyword. Note that this is only used for testing purposes.")); |
|
5729 PrintAddressL(header->iRomExceptionSearchTable, _L("iRomExceptionSearchTable"), _L("The virtual address of the TRomExceptionSearchTable structure.")); |
|
5730 PrintUintL(header->iRomHeaderSize, _L("iRomHeaderSize"), _L("Current size of ROM header (previously iUnused3). If value is 0x69966996 then header size is 0x100.")); |
|
5731 PrintAddressL(header->iRomSectionHeader, _L("iRomSectionHeader"), _L("The virtual address of the ROM section header, if the ROM is sectioned. See TRomSectionHeader for details.")); |
|
5732 PrintSizeL(header->iTotalSvDataSize, _L("iTotalSvDataSize"), _L("The total supervisor data size, i.e. the amount of memory mapped for the kernel data chunk.")); |
|
5733 PrintAddressL(header->iVariantFile, _L("iVariantFile"), _L("The virtual address of the TRomEntry for the Variant file. See TRomEntry for details.")); |
|
5734 PrintAddressL(header->iExtensionFile, _L("iExtensionFile"), _L("The virtual address of TRomEntry for the first extension file, if it exists. If there is more than one extension, then the next extension field in the extensions TRomImageHeader points to the TRomEntry for that next extension. See TRomEntry and TRomImageHeader for details.")); |
|
5735 PrintAddressL(header->iRelocInfo, _L("iRelocInfo"), _L("The old position of the kernel trace mask, see iTraceMask.")); |
|
5736 PrintUintL(header->iOldTraceMask, _L("iOldTraceMask"), _L("Current size of ROM header (previously iUnused3). If value is 0x69966996 then header size is 0x100.")); |
|
5737 PrintAddressL(header->iUserDataAddress, _L("iUserDataAddress"), _L("The virtual address of the user data area.")); |
|
5738 PrintSizeL(header->iTotalUserDataSize, _L("iTotalUserDataSize"), _L("The total size of the user data.")); |
|
5739 PrintUintL(header->iDebugPort, _L("iDebugPort"), _L("A value that is interpreted by the Bootstrap and kernel as the debug port to be used.")); |
|
5740 PrintUintL(header->iCompressionType, _L("iCompressionType"), _L("The type of compression used for the image. This is a UID, or 0 if there is no compression.")); |
|
5741 PrintSizeL(header->iCompressedSize, _L("iCompressedSize"), _L("The size of the image after compression.")); |
|
5742 PrintSizeL(header->iUncompressedSize, _L("iUncompressedSize"), _L("The size of the image before compression.")); |
|
5743 PrintUintL(header->iDisabledCapabilities[0], _L("iDisabledCapabilities[0]"), _L("Disabled capabilities.")); |
|
5744 PrintUintL(header->iDisabledCapabilities[1], _L("iDisabledCapabilities[1]"), _L("Disabled capabilities.")); |
|
5745 for (TInt i = 0; i < TRomHeader::KNumTraceMask; ++i) |
|
5746 { |
|
5747 TBuf<16> buf; |
|
5748 _LIT(KFormat, "iTraceMask[%d]"); |
|
5749 buf.Format(KFormat, i); |
|
5750 PrintUintL(header->iTraceMask[i], buf, _L("The initial value for one of the kernel trace masks.")); |
|
5751 } |
|
5752 #ifdef FSHELL_BTRACE_SUPPORT |
|
5753 for (TInt i = 0; i < 9; ++i) |
|
5754 { |
|
5755 TBuf<32> buf; |
|
5756 _LIT(KFormat, "iInitialBTraceFilter[%d]"); |
|
5757 buf.Format(KFormat, i); |
|
5758 PrintUintL(header->iInitialBTraceFilter[i], buf, _L("Initial value for a btrace filter.")); |
|
5759 } |
|
5760 PrintSizeL(header->iInitialBTraceBuffer, _L("iInitialBTraceBuffer"), _L("The initial btrace buffer size.")); |
|
5761 PrintUintL((TUint32)header->iInitialBTraceMode, _L("iInitialBTraceMode"), _L("The initial btrace mode.")); |
|
5762 #endif |
|
5763 #ifndef FSHELL_9_1_SUPPORT |
|
5764 PrintIntL((TInt32)header->iPageableRomStart, _L("iPageableRomStart"), _L("An offset, in bytes from ROM start, for the start of the pageable ROM area.")); |
|
5765 PrintSizeL(header->iPageableRomSize, _L("iPageableRomSize"), _L("The size of the pageable ROM area.")); |
|
5766 PrintIntL((TInt32)header->iRomPageIndex, _L("iRomPageIndex"), _L("An offset in bytes from ROM start, for the page index. (Array of SRomPageInfo objects.)")); |
|
5767 PrintUintL((TUint32)header->iDemandPagingConfig.iMinPages, _L("iMinPages"), _L("The minimum number of demand pages.")); |
|
5768 PrintUintL((TUint32)header->iDemandPagingConfig.iMaxPages, _L("iMinPages"), _L("The maximum number of demand pages.")); |
|
5769 PrintUintL((TUint32)header->iDemandPagingConfig.iYoungOldRatio, _L("iYoungOldRatio"), _L("The young / old ration of demand pages.")); |
|
5770 #endif |
|
5771 } |
|
5772 |
|
5773 CTextFormatter* formatter = CTextFormatter::NewLC(Stdout()); |
|
5774 formatter->TabulateL(0, 2, iBuffer->Descriptor(), EWrapLastColumn); |
|
5775 formatter->Write(); |
|
5776 CleanupStack::PopAndDestroy(formatter); |
|
5777 } |
|
5778 |
|
5779 void CCmdRom::OptionsL(RCommandOptionList& aOptions) |
|
5780 { |
|
5781 aOptions.AppendBoolL(iVerbose, KOptVerbose); |
|
5782 aOptions.AppendBoolL(iHumanReadable, KOptHuman); |
|
5783 } |
|
5784 |
|
5785 CCommandBase* CCmdWhich::NewLC() |
|
5786 { |
|
5787 CCmdWhich* self = new(ELeave) CCmdWhich(); |
|
5788 CleanupStack::PushL(self); |
|
5789 self->BaseConstructL(); |
|
5790 return self; |
|
5791 } |
|
5792 |
|
5793 CCmdWhich::~CCmdWhich() |
|
5794 { |
|
5795 delete iCommand; |
|
5796 } |
|
5797 |
|
5798 CCmdWhich::CCmdWhich() |
|
5799 { |
|
5800 } |
|
5801 |
|
5802 const TDesC& CCmdWhich::Name() const |
|
5803 { |
|
5804 _LIT(KName, "which"); |
|
5805 return KName; |
|
5806 } |
|
5807 |
|
5808 void CCmdWhich::ArgumentsL(RCommandArgumentList& aArguments) |
|
5809 { |
|
5810 _LIT(KCommand, "command"); |
|
5811 aArguments.AppendStringL(iCommand, KCommand); |
|
5812 } |
|
5813 |
|
5814 void CCmdWhich::DoRunL() |
|
5815 { |
|
5816 LtkUtils::RLtkBuf desc; |
|
5817 CleanupClosePushL(desc); |
|
5818 TRAPD(err, gShell->CommandFactory().GetCommandInfoL(*iCommand, desc)); |
|
5819 _LIT(KFmt, "%S: %S\r\n"); |
|
5820 _LIT(KFailed, "%S not a built-in or an exe in \\sys\\bin\r\n"); |
|
5821 if (err == KErrNotFound) |
|
5822 { |
|
5823 // Must be an external non-fshell exe |
|
5824 TFindFile find(FsL()); |
|
5825 TInt err = find.FindByDir(*iCommand, _L("Y:\\sys\\bin\\")); // Specify Y: to prevent it from checking the session path first |
|
5826 if (err == KErrNone) |
|
5827 { |
|
5828 Printf(KFmt, iCommand, &find.File()); |
|
5829 } |
|
5830 else if (err == KErrPermissionDenied) |
|
5831 { |
|
5832 // FShell must be built without AllFiles - try just creating it and getting its path |
|
5833 RProcess proc; |
|
5834 err = proc.Create(*iCommand, KNullDesC); |
|
5835 if (err == KErrNone) |
|
5836 { |
|
5837 TFileName path = proc.FileName(); |
|
5838 Printf(KFmt, iCommand, &path); |
|
5839 proc.Kill(KErrCancel); |
|
5840 proc.Close(); |
|
5841 } |
|
5842 else |
|
5843 { |
|
5844 Printf(KFailed, iCommand); |
|
5845 } |
|
5846 } |
|
5847 else |
|
5848 { |
|
5849 Printf(KFailed, iCommand); |
|
5850 } |
|
5851 } |
|
5852 else |
|
5853 { |
|
5854 LeaveIfErr(err, _L("Error finding command %S"), iCommand); |
|
5855 Printf(_L("%S: %S\r\n"), iCommand, &desc); |
|
5856 } |
|
5857 CleanupStack::PopAndDestroy(&desc); |
|
5858 } |
|
5859 |
|
5860 CCommandBase* CCmdTee::NewLC() |
|
5861 { |
|
5862 CCmdTee* self = new(ELeave) CCmdTee(); |
|
5863 CleanupStack::PushL(self); |
|
5864 self->BaseConstructL(); |
|
5865 return self; |
|
5866 } |
|
5867 |
|
5868 CCmdTee::~CCmdTee() |
|
5869 { |
|
5870 iFileNames.Close(); |
|
5871 for (TInt i = 0; i < iFiles.Count(); i++) |
|
5872 { |
|
5873 iFiles[i].Close(); |
|
5874 } |
|
5875 iFiles.Close(); |
|
5876 } |
|
5877 |
|
5878 CCmdTee::CCmdTee() |
|
5879 { |
|
5880 } |
|
5881 |
|
5882 const TDesC& CCmdTee::Name() const |
|
5883 { |
|
5884 _LIT(KName, "tee"); |
|
5885 return KName; |
|
5886 } |
|
5887 |
|
5888 void CCmdTee::ArgumentsL(RCommandArgumentList& aArguments) |
|
5889 { |
|
5890 aArguments.AppendFileNameL(iFileNames, _L("file")); |
|
5891 } |
|
5892 |
|
5893 void CCmdTee::OptionsL(RCommandOptionList& aOptions) |
|
5894 { |
|
5895 aOptions.AppendBoolL(iAppend, _L("append")); |
|
5896 aOptions.AppendBoolL(iRdebug, _L("rdebug")); |
|
5897 } |
|
5898 |
|
5899 void CCmdTee::DoRunL() |
|
5900 { |
|
5901 TUint filemode = EFileWrite | EFileShareAny | EFileStream; // Allow someone else to read it while we're writing |
|
5902 for (TInt i = 0; i < iFileNames.Count(); i++) |
|
5903 { |
|
5904 RFile f; |
|
5905 TInt err = KErrNone; |
|
5906 if (iAppend) |
|
5907 { |
|
5908 err = f.Open(FsL(), iFileNames[i], filemode); // First try append |
|
5909 if (err) err = f.Create(FsL(), iFileNames[i], filemode); // Then just create |
|
5910 TInt whatDoesThisArgumentForSeekEndDoDoesAnybodyKnow = 0; |
|
5911 f.Seek(ESeekEnd, whatDoesThisArgumentForSeekEndDoDoesAnybodyKnow); |
|
5912 } |
|
5913 else |
|
5914 { |
|
5915 err = f.Replace(FsL(), iFileNames[i], filemode); |
|
5916 } |
|
5917 LeaveIfErr(err, _L("Couldn't open file %S"), &iFileNames[i]); |
|
5918 iFiles.AppendL(f); |
|
5919 } |
|
5920 |
|
5921 RBuf readBuf; |
|
5922 CleanupClosePushL(readBuf); |
|
5923 readBuf.CreateL(512); |
|
5924 LtkUtils::RLtkBuf8 writeBuf; |
|
5925 CleanupClosePushL(writeBuf); |
|
5926 writeBuf.CreateL(readBuf.MaxSize() * 4); |
|
5927 Stdin().SetReadModeL(RIoReadHandle::EOneOrMore); |
|
5928 while (Stdin().Read(readBuf) == KErrNone) |
|
5929 { |
|
5930 writeBuf.CopyAsUtf8L(readBuf); |
|
5931 for (TInt i = 0; i < iFiles.Count(); i++) |
|
5932 { |
|
5933 TInt err = iFiles[i].Write(writeBuf); |
|
5934 if (err) PrintWarning(_L("Failed to write to file %d: %d"), i, err); |
|
5935 } |
|
5936 if (iRdebug) LtkUtils::RawPrint(writeBuf); |
|
5937 Stdout().Write(readBuf); |
|
5938 } |
|
5939 |
|
5940 CleanupStack::PopAndDestroy(2, &readBuf); |
|
5941 } |
|
5942 |
|
5943 CCommandBase* CCmdError::NewLC() |
|
5944 { |
|
5945 CCmdError* self = new(ELeave) CCmdError(); |
|
5946 CleanupStack::PushL(self); |
|
5947 self->BaseConstructL(); |
|
5948 return self; |
|
5949 } |
|
5950 |
|
5951 CCmdError::~CCmdError() |
|
5952 { |
|
5953 delete iErrorText; |
|
5954 } |
|
5955 |
|
5956 CCmdError::CCmdError() |
|
5957 : iErrorVal(KErrAbort) |
|
5958 { |
|
5959 } |
|
5960 |
|
5961 const TDesC& CCmdError::Name() const |
|
5962 { |
|
5963 _LIT(KName, "error"); |
|
5964 return KName; |
|
5965 } |
|
5966 |
|
5967 void CCmdError::DoRunL() |
|
5968 { |
|
5969 if (iErrorVal >= 0) LeaveIfErr(KErrArgument, _L("Non-negative value %d passed to error command"), iErrorVal); |
|
5970 |
|
5971 if (iErrorText) |
|
5972 { |
|
5973 LeaveIfErr(iErrorVal, *iErrorText); |
|
5974 } |
|
5975 else |
|
5976 { |
|
5977 User::Leave(iErrorVal); |
|
5978 } |
|
5979 } |
|
5980 |
|
5981 void CCmdError::ArgumentsL(RCommandArgumentList& aArguments) |
|
5982 { |
|
5983 aArguments.AppendIntL(iErrorVal, _L("error-number")); |
|
5984 aArguments.AppendStringL(iErrorText, _L("text")); |
|
5985 } |
|
5986 |
|
5987 |
|
5988 // |
|
5989 // CCmdReboot |
|
5990 // |
|
5991 |
|
5992 CCommandBase* CCmdReboot::NewLC() |
|
5993 { |
|
5994 CCmdReboot* self = new(ELeave) CCmdReboot(); |
|
5995 CleanupStack::PushL(self); |
|
5996 self->BaseConstructL(); |
|
5997 return self; |
|
5998 } |
|
5999 |
|
6000 CCmdReboot::~CCmdReboot() |
|
6001 { |
|
6002 } |
|
6003 |
|
6004 CCmdReboot::CCmdReboot() |
|
6005 { |
|
6006 } |
|
6007 |
|
6008 const TDesC& CCmdReboot::Name() const |
|
6009 { |
|
6010 _LIT(KName, "reboot"); |
|
6011 return KName; |
|
6012 } |
|
6013 |
|
6014 void CCmdReboot::DoRunL() |
|
6015 { |
|
6016 if (!iArguments.IsPresent(0)) |
|
6017 { |
|
6018 iReason = 0x40000000; // On most baseports this represents 'soft reboot' |
|
6019 } |
|
6020 |
|
6021 LoadMemoryAccessL(); |
|
6022 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT |
|
6023 iMemAccess.Reboot(iReason); |
|
6024 #endif |
|
6025 } |
|
6026 |
|
6027 void CCmdReboot::ArgumentsL(RCommandArgumentList& aArguments) |
|
6028 { |
|
6029 _LIT(KArgReason, "reason"); |
|
6030 aArguments.AppendUintL(iReason, KArgReason); |
|
6031 } |
|
6032 |
|
6033 |
|
6034 // |
|
6035 // CCmdForEach |
|
6036 // |
|
6037 |
|
6038 CCommandBase* CCmdForEach::NewLC() |
|
6039 { |
|
6040 CCmdForEach* self = new(ELeave) CCmdForEach(); |
|
6041 CleanupStack::PushL(self); |
|
6042 self->BaseConstructL(); |
|
6043 return self; |
|
6044 } |
|
6045 |
|
6046 CCmdForEach::~CCmdForEach() |
|
6047 { |
|
6048 iDir.Close(); |
|
6049 } |
|
6050 |
|
6051 CCmdForEach::CCmdForEach() |
|
6052 : iDirName(TFileName2::EDirectory) |
|
6053 { |
|
6054 } |
|
6055 |
|
6056 void CCmdForEach::DoNextL(TBool aFirstTime) |
|
6057 { |
|
6058 if (!aFirstTime) Env().RemoveAll(); // Remove all only does locals |
|
6059 |
|
6060 delete iScriptData; |
|
6061 iScriptData = NULL; |
|
6062 delete iParser; |
|
6063 iParser = NULL; |
|
6064 |
|
6065 TEntry entry; |
|
6066 TInt err = iDir.Read(entry); |
|
6067 if (err == KErrEof) |
|
6068 { |
|
6069 Complete(iLastError); |
|
6070 } |
|
6071 else |
|
6072 { |
|
6073 LeaveIfErr(err, _L("Couldn't read directory '%S'"), &iDirName); |
|
6074 // Update the first element of the argument array with the full name of the file we just found. |
|
6075 TFileName2 fileName(iDirName); |
|
6076 fileName.AppendComponentL(entry.iName, TFileName2::EFile); |
|
6077 |
|
6078 RPointerArray<HBufC> extraArgs; |
|
6079 LtkUtils::CleanupResetAndDestroyPushL(extraArgs); |
|
6080 extraArgs.AppendL(fileName.AllocLC()); |
|
6081 CleanupStack::Pop(); // hbufc |
|
6082 |
|
6083 TIoHandleSet ioHandles(IoSession(), Stdin(), Stdout(), Stderr()); |
|
6084 TBool helpPrinted; |
|
6085 iScriptData = CShell::ReadScriptL(iFileName, iArgs, Env(), FsL(), ioHandles, helpPrinted, &extraArgs); |
|
6086 CleanupStack::PopAndDestroy(&extraArgs); |
|
6087 if (helpPrinted) |
|
6088 { |
|
6089 Complete(); |
|
6090 } |
|
6091 else |
|
6092 { |
|
6093 TUint mode = CParser::EExportLineNumbers; |
|
6094 if (iKeepGoing) |
|
6095 { |
|
6096 mode |= CParser::EKeepGoing; |
|
6097 } |
|
6098 iParser = CParser::NewL(mode, *iScriptData, IoSession(), Stdin(), Stdout(), Stderr(), Env(), gShell->CommandFactory(), this); |
|
6099 iParser->Start(); |
|
6100 } |
|
6101 } |
|
6102 } |
|
6103 |
|
6104 const TDesC& CCmdForEach::Name() const |
|
6105 { |
|
6106 _LIT(KName, "foreach"); |
|
6107 return KName; |
|
6108 } |
|
6109 |
|
6110 void CCmdForEach::DoRunL() |
|
6111 { |
|
6112 LeaveIfFileNotFound(iDirName); |
|
6113 if (!iDirName.IsDirL(FsL())) |
|
6114 { |
|
6115 LeaveIfErr(KErrArgument, _L("'%S' is not a directory"), &iDirName); |
|
6116 } |
|
6117 LeaveIfErr(iDir.Open(FsL(), iDirName, KEntryAttNormal | KEntryAttDir), _L("Couldn't open directory '%S'"), &iDirName); |
|
6118 |
|
6119 DoNextL(ETrue); |
|
6120 } |
|
6121 |
|
6122 void CCmdForEach::ArgumentsL(RCommandArgumentList& aArguments) |
|
6123 { |
|
6124 _LIT(KArgDirectoryName, "directory_name"); |
|
6125 aArguments.AppendFileNameL(iDirName, KArgDirectoryName); |
|
6126 |
|
6127 CCmdSource::ArgumentsL(aArguments); |
|
6128 } |
|
6129 |
|
6130 void CCmdForEach::HandleParserComplete(CParser&, const TError& aError) |
|
6131 { |
|
6132 TInt err = aError.Error(); |
|
6133 if (err < 0) |
|
6134 { |
|
6135 aError.Report(); |
|
6136 PrintError(err, _L("Aborted \"%S\" at line %d"), &aError.ScriptFileName(), aError.ScriptLineNumber()); |
|
6137 iLastError = err; |
|
6138 } |
|
6139 |
|
6140 if ((err < 0) && !iKeepGoing) |
|
6141 { |
|
6142 Complete(iLastError); |
|
6143 } |
|
6144 else |
|
6145 { |
|
6146 TRAPD(err, DoNextL()); |
|
6147 if (err) |
|
6148 { |
|
6149 Complete(err); |
|
6150 } |
|
6151 } |
|
6152 } |