libraries/iosrv/client/command_base.cpp
changeset 45 534b01198c2d
parent 23 092bcc217d9d
child 63 ea6622dea85a
equal deleted inserted replaced
43:698ccde15713 45:534b01198c2d
    12 
    12 
    13 #include "iocons.h"
    13 #include "iocons.h"
    14 #include "ioutils.h"
    14 #include "ioutils.h"
    15 #include "command_base.h"
    15 #include "command_base.h"
    16 #include <fshell/ltkutils.h>
    16 #include <fshell/ltkutils.h>
    17 
    17 #include <fshell/line_editor.h> // for definition of CTRL()
    18 using namespace IoUtils;
    18 using namespace IoUtils;
    19 
    19 
    20 #define RETURN_IF_ERROR(x) {TInt _err = (x); if (_err<0) return _err;}
    20 #define RETURN_IF_ERROR(x) {TInt _err = (x); if (_err<0) return _err;}
    21 
    21 
    22 //
    22 //
  1521 EXPORT_C void CCommandBase::SetFlags(TUint aFlags)
  1521 EXPORT_C void CCommandBase::SetFlags(TUint aFlags)
  1522 	{
  1522 	{
  1523 	TUint privateFlags = (iFlags & KPrivateFlagsMask);
  1523 	TUint privateFlags = (iFlags & KPrivateFlagsMask);
  1524 	iFlags = (aFlags & KPublicFlagsMask);
  1524 	iFlags = (aFlags & KPublicFlagsMask);
  1525 	iFlags |= privateFlags;
  1525 	iFlags |= privateFlags;
       
  1526 	// Make sure implied flags are set
  1526 	if (iFlags & ECompleteOnRunL)
  1527 	if (iFlags & ECompleteOnRunL)
  1527 		{
  1528 		{
  1528 		iFlags |= EManualComplete;
  1529 		iFlags |= EManualComplete;
       
  1530 		}
       
  1531 	if (iFlags & ECaptureCtrlC)
       
  1532 		{
       
  1533 		iFlags |= ENotifyKeypresses;
  1529 		}
  1534 		}
  1530 	}
  1535 	}
  1531 
  1536 
  1532 EXPORT_C void CCommandBase::SetCif(const CCommandInfoFile& aCif)
  1537 EXPORT_C void CCommandBase::SetCif(const CCommandInfoFile& aCif)
  1533 	{
  1538 	{
  1584 	else
  1589 	else
  1585 		{
  1590 		{
  1586 		if (iConsoleImplementation || iPersistentConsoleName)
  1591 		if (iConsoleImplementation || iPersistentConsoleName)
  1587 			{
  1592 			{
  1588 			UpdateHandlesL();
  1593 			UpdateHandlesL();
       
  1594 			}
       
  1595 
       
  1596 		if (iFlags & ENotifyKeypresses)
       
  1597 			{
       
  1598 			__ASSERT_ALWAYS(iExtension && iExtension->ExtensionVersion() >= ECommandExtensionV2, IoUtils::Panic(EENotifyKeypressesSpecifiedWithoutExtensionBeingSet));
       
  1599 			iKeypressWatcher = new(ELeave) CKeypressWatcher(*static_cast<MCommandExtensionsV2*>(iExtension), Stdin());
       
  1600 			if (iFlags & ECaptureCtrlC)
       
  1601 				{
       
  1602 				User::LeaveIfError(Stdin().CaptureKey(CTRL('c'), 0, 0));
       
  1603 				}
       
  1604 			iKeypressWatcher->Notify();
  1589 			}
  1605 			}
  1590 
  1606 
  1591 		TBool deleted(EFalse);
  1607 		TBool deleted(EFalse);
  1592 		iDeleted = &deleted;	
  1608 		iDeleted = &deleted;	
  1593 		// Note, commands that manually complete may call CCommandBase::Complete from their DoRunL, which in the case 
  1609 		// Note, commands that manually complete may call CCommandBase::Complete from their DoRunL, which in the case 
  1624 		iFlags |= ETlsSet;
  1640 		iFlags |= ETlsSet;
  1625 		}
  1641 		}
  1626 	}
  1642 	}
  1627 
  1643 
  1628 EXPORT_C CCommandBase::CCommandBase(TUint aFlags)
  1644 EXPORT_C CCommandBase::CCommandBase(TUint aFlags)
  1629 	: CActive(CActive::EPriorityStandard), iFlags(aFlags)
  1645 	: CActive(CActive::EPriorityStandard)
  1630 	{
  1646 	{
  1631 	CActiveScheduler::Add(this);
  1647 	CActiveScheduler::Add(this);
  1632 	if (Dll::Tls() == NULL)
  1648 	if (Dll::Tls() == NULL)
  1633 		{
  1649 		{
  1634 		Dll::SetTls(this);
  1650 		Dll::SetTls(this);
  1635 		iFlags |= ETlsSet;
  1651 		iFlags |= ETlsSet;
  1636 		}
  1652 		}
  1637 
  1653 
  1638 	// Ensure EManualComplete is set if ECompleteOnRunL is.
  1654 	// Don't initialise iFlags directly - SetFlags checks that private flags aren't being set
  1639 	SetFlags(Flags());
  1655 	SetFlags(aFlags);
  1640 	}
  1656 	}
  1641 
  1657 
  1642 EXPORT_C CCommandBase::~CCommandBase()
  1658 EXPORT_C CCommandBase::~CCommandBase()
  1643 	{
  1659 	{
  1644 	delete iReadChangeNotifier;
  1660 	delete iReadChangeNotifier;
  1645 	delete iCompleter;
  1661 	delete iCompleter;
       
  1662 	delete iKeypressWatcher;
  1646 	iFs.Close();
  1663 	iFs.Close();
  1647 	if (iFlags & EOwnsHandles)
  1664 	if (iFlags & EOwnsHandles)
  1648 		{
  1665 		{
  1649 		iStderr.Close();
  1666 		iStderr.Close();
  1650 		iStdout.Close();
  1667 		iStdout.Close();
  1777 	}
  1794 	}
  1778 
  1795 
  1779 EXPORT_C void CCommandBase::Write(const TDesC& aData)
  1796 EXPORT_C void CCommandBase::Write(const TDesC& aData)
  1780 	{
  1797 	{
  1781 	iStdout.Write(aData); // Ignore error.
  1798 	iStdout.Write(aData); // Ignore error.
       
  1799 	}
       
  1800 
       
  1801 EXPORT_C TUint CCommandBase::ReadKey()
       
  1802 	{
       
  1803 	// Make sure keypresswatcher doesn't get in the way (some commands do some synchronous ReadKeys followed by use of async ENotifyKeypresses callbacks)
       
  1804 	if (iKeypressWatcher) iKeypressWatcher->Cancel();
       
  1805 	TUint result = iStdin.ReadKey();
       
  1806 	if (iKeypressWatcher) iKeypressWatcher->Notify();
       
  1807 	return result;
  1782 	}
  1808 	}
  1783 
  1809 
  1784 EXPORT_C void CCommandBase::Printf(TRefByValue<const TDesC> aFmt, ...)
  1810 EXPORT_C void CCommandBase::Printf(TRefByValue<const TDesC> aFmt, ...)
  1785 	{
  1811 	{
  1786 	VA_LIST list;
  1812 	VA_LIST list;
  3536 
  3562 
  3537 	// Make the newly created handles duplicates of the ones that were passed in.
  3563 	// Make the newly created handles duplicates of the ones that were passed in.
  3538 	// This makes them attached to the same I/O end-points (consoles, files, etc)
  3564 	// This makes them attached to the same I/O end-points (consoles, files, etc)
  3539 	// as the passed in handles.
  3565 	// as the passed in handles.
  3540 	User::LeaveIfError(iStdin.Duplicate(aStdin));
  3566 	User::LeaveIfError(iStdin.Duplicate(aStdin));
  3541 	User::LeaveIfError(iStdin.SetToForeground());
  3567 	// iStdin.SetToForeground() moved to Run() so the child doesn't steal foreground until it actually runs
  3542 	User::LeaveIfError(iStdout.Duplicate(aStdout));
  3568 	User::LeaveIfError(iStdout.Duplicate(aStdout));
  3543 	User::LeaveIfError(iStderr.Duplicate(aStderr));
  3569 	User::LeaveIfError(iStderr.Duplicate(aStderr));
  3544 
  3570 
  3545 	// Create the process.
  3571 	// Create the process.
  3546 	ProcessCreateL(aExecutableName, aCommandLine, aEnv);
  3572 	ProcessCreateL(aExecutableName, aCommandLine, aEnv);
  3577 	User::LeaveIfError(iStderr.SetOwner(threadId));
  3603 	User::LeaveIfError(iStderr.SetOwner(threadId));
  3578 	}
  3604 	}
  3579 
  3605 
  3580 EXPORT_C void RChildProcess::Run(TRequestStatus& aStatus)
  3606 EXPORT_C void RChildProcess::Run(TRequestStatus& aStatus)
  3581 	{
  3607 	{
       
  3608 	iStdin.SetToForeground();
  3582 	iProcess.Logon(aStatus);
  3609 	iProcess.Logon(aStatus);
  3583 	if (aStatus != KRequestPending)
  3610 	if (aStatus != KRequestPending)
  3584 		{
  3611 		{
  3585 		iProcess.Kill(KErrAbort);
  3612 		iProcess.Kill(KErrAbort);
  3586 		}
  3613 		}
  3806 void CReaderChangeNotifier::DoCancel()
  3833 void CReaderChangeNotifier::DoCancel()
  3807 	{
  3834 	{
  3808 	iReadHandle.CancelNotifyChange();
  3835 	iReadHandle.CancelNotifyChange();
  3809 	}
  3836 	}
  3810 
  3837 
       
  3838 //
       
  3839 // CKeypressWatcher
  3811 // 
  3840 // 
  3812 
  3841 
       
  3842 CKeypressWatcher::CKeypressWatcher(IoUtils::MCommandExtensionsV2& aCmd, RIoConsoleReadHandle& aReadHandle)
       
  3843 	: CActive(CActive::EPriorityStandard), iCmd(aCmd), iReadHandle(aReadHandle)
       
  3844 	{
       
  3845 	CActiveScheduler::Add(this);
       
  3846 	}
       
  3847 
       
  3848 CKeypressWatcher::~CKeypressWatcher()
       
  3849 	{
       
  3850 	Cancel();
       
  3851 	}
       
  3852 
       
  3853 void CKeypressWatcher::Notify()
       
  3854 	{
       
  3855 	iReadHandle.WaitForKey(iStatus);
       
  3856 	SetActive();
       
  3857 	}
       
  3858 
       
  3859 void CKeypressWatcher::RunL()
       
  3860 	{
       
  3861 	TUint code = iReadHandle.KeyCode();
       
  3862 	TUint modifiers = iReadHandle.KeyModifiers();
       
  3863 	Notify();
       
  3864 	iCmd.KeyPressed(code, modifiers);
       
  3865 	if (code == CTRL('c'))
       
  3866 		{
       
  3867 		iCmd.CtrlCPressed();
       
  3868 		}
       
  3869 	}
       
  3870 
       
  3871 void CKeypressWatcher::DoCancel()
       
  3872 	{
       
  3873 	iReadHandle.WaitForKeyCancel();
       
  3874 	}
       
  3875 
       
  3876 //
       
  3877 
  3813 EXPORT_C TCommandExtensionVersion MCommandExtensionsV1::ExtensionVersion() const
  3878 EXPORT_C TCommandExtensionVersion MCommandExtensionsV1::ExtensionVersion() const
  3814 	{
  3879 	{
  3815 	return ECommandExtensionV1;
  3880 	return ECommandExtensionV1;
  3816 	}
  3881 	}
  3817 
  3882 
  3822 
  3887 
  3823 EXPORT_C void CCommandBase::SetExtension(MCommandExtensionsV1* aExtension)
  3888 EXPORT_C void CCommandBase::SetExtension(MCommandExtensionsV1* aExtension)
  3824 	{
  3889 	{
  3825 	iExtension = aExtension;
  3890 	iExtension = aExtension;
  3826 	}
  3891 	}
       
  3892 
       
  3893 EXPORT_C TCommandExtensionVersion MCommandExtensionsV2::ExtensionVersion() const
       
  3894 	{
       
  3895 	return ECommandExtensionV2;
       
  3896 	}
       
  3897 
       
  3898 EXPORT_C void MCommandExtensionsV2::KeyPressed(TUint /*aKeyCode*/, TUint /*aModifiers*/)
       
  3899 	{
       
  3900 	// Default is to do nothing
       
  3901 	}
       
  3902 
       
  3903 EXPORT_C void MCommandExtensionsV2::CtrlCPressed()
       
  3904 	{
       
  3905 	// Default is to do nothing
       
  3906 	}