commands/sudo/sudo.cpp
changeset 51 8dc858aede52
parent 45 534b01198c2d
equal deleted inserted replaced
44:da10798406fc 51:8dc858aede52
    16 #include <fshell/memoryaccesscmd.h>
    16 #include <fshell/memoryaccesscmd.h>
    17 #include <e32rom.h>
    17 #include <e32rom.h>
    18 
    18 
    19 using namespace IoUtils;
    19 using namespace IoUtils;
    20 
    20 
    21 class CCmdSudo : public CMemoryAccessCommandBase
    21 class CCmdSudo : public CMemoryAccessCommandBase, public MCommandExtensionsV2
    22 	{
    22 	{
    23 public:
    23 public:
    24 	static CCommandBase* NewLC();
    24 	static CCommandBase* NewLC();
    25 	~CCmdSudo();
    25 	~CCmdSudo();
    26 private:
    26 private:
    40 private: // From CCommandBase.
    40 private: // From CCommandBase.
    41 	virtual const TDesC& Name() const;
    41 	virtual const TDesC& Name() const;
    42 	virtual void DoRunL();
    42 	virtual void DoRunL();
    43 	virtual void ArgumentsL(RCommandArgumentList& aArguments);
    43 	virtual void ArgumentsL(RCommandArgumentList& aArguments);
    44 	virtual void OptionsL(RCommandOptionList& aOptions);
    44 	virtual void OptionsL(RCommandOptionList& aOptions);
       
    45 	virtual void RunL();
       
    46 
       
    47 private: // From MCommandExtensionsV2
       
    48 	virtual void CtrlCPressed();
    45 
    49 
    46 private:
    50 private:
    47 	HBufC* iCmd;
    51 	HBufC* iCmd;
    48 	HBufC* iArgs;
    52 	HBufC* iArgs;
    49 	RPointerArray<HBufC> iAdd;
    53 	RPointerArray<HBufC> iAdd;
    66 	TFileName iNewPath;
    70 	TFileName iNewPath;
    67 	CArrayPtrFlat<HBufC>* iPathsToCleanup;
    71 	CArrayPtrFlat<HBufC>* iPathsToCleanup;
    68 	// following 2 are temporaries needed during CopyExeLC
    72 	// following 2 are temporaries needed during CopyExeLC
    69 	TFileName iTempSrc;
    73 	TFileName iTempSrc;
    70 	TFileName iTempDest;
    74 	TFileName iTempDest;
       
    75 
       
    76 	RChildProcess iChildProcess;
    71 	};
    77 	};
    72 
    78 
    73 
    79 
    74 CCommandBase* CCmdSudo::NewLC()
    80 CCommandBase* CCmdSudo::NewLC()
    75 	{
    81 	{
    95 			Fs().Delete(*file);
   101 			Fs().Delete(*file);
    96 			delete file;
   102 			delete file;
    97 			}
   103 			}
    98 		}
   104 		}
    99 	delete iPathsToCleanup;
   105 	delete iPathsToCleanup;
       
   106 	iChildProcess.Close();
   100 	}
   107 	}
   101 
   108 
   102 CCmdSudo::CCmdSudo()
   109 CCmdSudo::CCmdSudo()
   103 	{
   110 	: CMemoryAccessCommandBase(EManualComplete | ECaptureCtrlC)
       
   111 	{
       
   112 	SetExtension(this);
   104 	}
   113 	}
   105 
   114 
   106 TCapability CapabilityFromString(const TDesC& aName)
   115 TCapability CapabilityFromString(const TDesC& aName)
   107 	{
   116 	{
   108 	TBuf<32> cap;
   117 	TBuf<32> cap;
   302 		CleanupStack::Pop(); // DeleteModifiedBinary
   311 		CleanupStack::Pop(); // DeleteModifiedBinary
   303 		return;
   312 		return;
   304 		}
   313 		}
   305 #endif
   314 #endif
   306 
   315 
   307 	RChildProcess childProcess;
   316 	TRAPL(iChildProcess.CreateL(iNewPath, iArgs ? *iArgs : KNullDesC(), IoSession(), Stdin(), Stdout(), Stderr(), Env()), _L("Failed to execute %S"), &iNewPath);
   308 	TRAPL(childProcess.CreateL(iNewPath, iArgs ? *iArgs : KNullDesC(), IoSession(), Stdin(), Stdout(), Stderr(), Env()), _L("Failed to execute %S"), &iNewPath);
       
   309 	if (iKeep)
   317 	if (iKeep)
   310 		{
   318 		{
   311 		Printf(_L("Executing %S...\r\n"), &iNewPath);
   319 		Printf(_L("Executing %S...\r\n"), &iNewPath);
   312 		CleanupStack::Pop(); // Don't delete if user asked for --keep
   320 		}
   313 		}
   321 	CleanupStack::Pop(); // DeleteModifiedBinary
   314 	else
   322 
   315 		{
   323 
   316 		CleanupStack::PopAndDestroy(); // DeleteModifiedBinary - remove the binary before we actually start running it, so it is guaranteed cleaned up even if the user kills us with ctrl-c
       
   317 		}
       
   318 	if (!iChangeBinaryOnDisk)
   324 	if (!iChangeBinaryOnDisk)
   319 		{
   325 		{
   320 		// Time to get memaccess involved
   326 		// Time to get memaccess involved
   321 		TRAPD(err, FixupExeInMemoryL(childProcess.Process()));
   327 		TRAPD(err, FixupExeInMemoryL(iChildProcess.Process()));
   322 		if (err)
   328 		if (err)
   323 			{
   329 			{
   324 			childProcess.Process().Kill(err);
   330 			iChildProcess.Process().Kill(err);
   325 			childProcess.Close();
   331 			iChildProcess.Close();
   326 			User::Leave(err);
   332 			User::Leave(err);
   327 			}
   333 			}
   328 		}
   334 		}
   329 
   335 
   330 	if (iWait)
   336 	if (iWait)
   331 		{
   337 		{
   332 		Printf(_L("Process is created but not yet resumed. Press a key to continue...\r\n"));
   338 		Printf(_L("Process is created but not yet resumed. Press a key to continue...\r\n"));
   333 		Stdin().ReadKey();
   339 		ReadKey();
   334 		}
   340 		Printf(_L("Resuming process...\r\n"));
   335 
   341 		}
   336 	TRequestStatus stat;
   342 
   337 	childProcess.Run(stat);
   343 	iChildProcess.Run(iStatus);
   338 	User::WaitForRequest(stat);
   344 	SetActive();
   339 	TInt err = stat.Int();
       
   340 	childProcess.Close();
       
   341 	User::LeaveIfError(err); // This gets translated to our exe's return code I hope
       
   342 	}
   345 	}
   343 
   346 
   344 const TDesC& CCmdSudo::Name() const
   347 const TDesC& CCmdSudo::Name() const
   345 	{
   348 	{
   346 	_LIT(KName, "sudo");
   349 	_LIT(KName, "sudo");
   533 	CleanupStack::PushL(TCleanupItem(&CCmdSudo::DeleteModifiedBinary, this));
   536 	CleanupStack::PushL(TCleanupItem(&CCmdSudo::DeleteModifiedBinary, this));
   534 #else
   537 #else
   535 	LeaveIfErr(KErrNotSupported, _L("Can't fixup an exe in Core image without memoryaccess"));
   538 	LeaveIfErr(KErrNotSupported, _L("Can't fixup an exe in Core image without memoryaccess"));
   536 #endif
   539 #endif
   537 	}
   540 	}
       
   541 
       
   542 void CCmdSudo::CtrlCPressed()
       
   543 	{
       
   544 	Printf(_L("Ctrl-C pressed, killing %S and cleaning up.\r\n"), &iNewPath);
       
   545 	SetErrorReported(ETrue);
       
   546 	iChildProcess.Process().Kill(KErrAbort);
       
   547 	}
       
   548 
       
   549 void CCmdSudo::RunL()
       
   550 	{
       
   551 	if (!iKeep)
       
   552 		{
       
   553 		DeleteModifiedBinary();
       
   554 		}
       
   555 	Complete(iStatus.Int());
       
   556 	}