Added --no-write to gobble, fixed crash in start --timeout.
authorTom Sutcliffe <thomas.sutcliffe@accenture.com>
Tue, 14 Sep 2010 09:49:39 +0100
changeset 58 377ac716dabb
parent 57 683f4b1f08ce
child 59 c9dfb364c2d1
Added --no-write to gobble, fixed crash in start --timeout. Also changed help to output one command per line (instead of columnizing) if not attached to a console. It's the same as what ls does.
core/builtins/gobble.cif
core/builtins/gobble.cpp
core/builtins/gobble.h
core/builtins/help.cif
core/builtins/sleep.cif
core/src/commands.cpp
documentation/change_history.pod
libraries/iosrv/client/command_base.cpp
--- a/core/builtins/gobble.cif	Thu Sep 09 15:47:34 2010 +0100
+++ b/core/builtins/gobble.cif	Tue Sep 14 09:49:39 2010 +0100
@@ -14,11 +14,11 @@
 
 ==short-description
 
-A tool for purposefully wasting persistent storage space.
+A tool for purposefully wasting disk space.
 
 ==long-description
 
-If the specified file does not already exist, it will be created. If it does exist, it will be grown.
+If the specified file does not already exist, it will be created. If it does exist, it will be grown by the amount specified.
 
 ==see-also
 
@@ -28,13 +28,17 @@
 
 Display more detailed output.
 
+==option bool n no-write
+
+By default the file is filled with a pattern of 'x' characters. Specify this option to only set the file size and not to actually write to it. Useful if you want to test low disk space without introducing delays (and wear to the disk) of actually writing lots of data.
+
 ==argument filename file_name
 
 The file to create or to append to.
 
-==argument uint amount
+==argument uint amount optional
 
-The total number of bytes to consume.
+The total number of bytes to consume. If zero or not specified, the file size is set to fill the free space on the disk.
 
 ==argument uint block_size optional
 
--- a/core/builtins/gobble.cpp	Thu Sep 09 15:47:34 2010 +0100
+++ b/core/builtins/gobble.cpp	Tue Sep 14 09:49:39 2010 +0100
@@ -11,6 +11,7 @@
 //
 
 #include "gobble.h"
+#include <fshell/ltkutils.h>
 
 
 CCommandBase* CCmdGobble::NewLC()
@@ -38,9 +39,20 @@
 
 void CCmdGobble::DoRunL()
 	{
-	if (iAmount < iBlockSize)
+	RFs& fs = FsL();
+	if (iAmount == 0)
 		{
-		LeaveIfErr(KErrArgument, _L("The amount to consume must be less than the block size (%d)"), iBlockSize);
+		TInt drive = EDriveC;
+		if (iFileName.Length() == 0) LeaveIfErr(KErrBadName, _L("Bad file name"));
+		RFs::CharToDrive(iFileName[0], drive);
+		TVolumeInfo volInfo;
+		LeaveIfErr(fs.Volume(volInfo, drive), _L("Couldn't get volume information for drive %c"), iFileName[0]);
+		iAmount = volInfo.iFree;
+		}
+
+	if (!iNoWrite && iAmount < iBlockSize)
+		{
+		LeaveIfErr(KErrArgument, _L("The amount to consume must be greater than the block size (%d)"), iBlockSize);
 		}
 	if (iAmount & 0x80000000)
 		{
@@ -50,7 +62,6 @@
 		{
 		LeaveIfErr(KErrArgument, _L("The block size is too large (maximum is %d)"), KMaxTInt);
 		}
-	RFs& fs = FsL();
 	fs.MkDirAll(iFileName);
 	RFile file;
 	TInt err = file.Open(fs, iFileName, EFileWrite);
@@ -58,51 +69,64 @@
 		{
 		err = file.Create(fs, iFileName, EFileWrite);
 		}
-	User::LeaveIfError(err);
+	LeaveIfErr(err, _L("Couldn't create file %S"), &iFileName);
 	CleanupClosePushL(file);
-	TInt pos = 0;
-	User::LeaveIfError(file.Seek(ESeekEnd, pos));
 
-	HBufC8* buf = HBufC8::NewLC(iBlockSize);
-	TPtr8 ptr(buf->Des());
-	ptr.Fill(TChar('x'), iBlockSize);
-	
-	TInt toWrite = static_cast<TInt>(iAmount);
-	do
+	if (iNoWrite)
+		{
+		TInt size = 0;
+		LeaveIfErr(file.Size(size), _L("Couldn't get file size"));
+		size += iAmount;
+		LeaveIfErr(file.SetSize(size), _L("Couldn't set filesize to %d"), size);
+		}
+	else
 		{
-		TInt writeSize;
-		if (toWrite > static_cast<TInt>(iBlockSize))
+		TInt pos = 0;
+		User::LeaveIfError(file.Seek(ESeekEnd, pos));
+		HBufC8* buf = HBufC8::NewLC(iBlockSize);
+		TPtr8 ptr(buf->Des());
+		ptr.Fill(TChar('x'), iBlockSize);
+		
+		TInt toWrite = static_cast<TInt>(iAmount);
+		do
 			{
-			writeSize = static_cast<TInt>(iBlockSize);
-			}
-		else
-			{
-			writeSize = toWrite;
+			TInt writeSize;
+			if (toWrite > static_cast<TInt>(iBlockSize))
+				{
+				writeSize = static_cast<TInt>(iBlockSize);
+				}
+			else
+				{
+				writeSize = toWrite;
+				}
+			ptr.SetLength(writeSize);
+			err = file.Write(ptr);
+			if (err == KErrNone)
+				{
+				if (iVerbose)
+					{
+					Printf(_L("\rWrote %d"), iAmount - toWrite);
+					}
+				toWrite -= writeSize;
+				}
 			}
-		ptr.SetLength(writeSize);
-		err = file.Write(ptr);
-		if (err == KErrNone)
-			{
-			if (iVerbose)
-				{
-				Printf(_L("\rWrote %d"), iAmount - toWrite);
-				}
-			toWrite -= writeSize;
-			}
-		}
 		while ((err == KErrNone) && (toWrite > 0));
 		if (iVerbose)
 			{
 			Printf(_L("\rWrote %d"), iAmount - toWrite);
 			}
-		
-	CleanupStack::PopAndDestroy(2, &file);
+		CleanupStack::PopAndDestroy(buf);
+		}
+	CleanupStack::PopAndDestroy(&file);
 	}
 
 void CCmdGobble::OptionsL(RCommandOptionList& aOptions)
 	{
 	_LIT(KCmdOptVerbose, "verbose");
 	aOptions.AppendBoolL(iVerbose, KCmdOptVerbose);
+
+	_LIT(KCmdOptNoWrite, "no-write");
+	aOptions.AppendBoolL(iNoWrite, KCmdOptNoWrite);
 	}
 
 void CCmdGobble::ArgumentsL(RCommandArgumentList& aArguments)
--- a/core/builtins/gobble.h	Thu Sep 09 15:47:34 2010 +0100
+++ b/core/builtins/gobble.h	Tue Sep 14 09:49:39 2010 +0100
@@ -32,4 +32,5 @@
 	TUint iAmount;
 	TUint iBlockSize;
 	TBool iVerbose;
+	TBool iNoWrite;
 	};
--- a/core/builtins/help.cif	Thu Sep 09 15:47:34 2010 +0100
+++ b/core/builtins/help.cif	Tue Sep 14 09:49:39 2010 +0100
@@ -18,7 +18,7 @@
 
 ==long-description
 
-Lists fshell's built-in and alias commands (e.g. C<dir> is an alias for C<ls -l>). Also lists external commands, DLLs that have a UID2 of 0x102864C8 and EXEs that have a UID2 of 0x102835BE.
+Lists fshell's built-in and alias commands (e.g. C<dir> is an alias for C<ls -l>). Also lists external commands, that is EXEs that have a UID2 of 0x102835BE (FSHELL_UID2_FSHELL_EXE).
 
 ==option bool c count
 
--- a/core/builtins/sleep.cif	Thu Sep 09 15:47:34 2010 +0100
+++ b/core/builtins/sleep.cif	Tue Sep 14 09:49:39 2010 +0100
@@ -18,8 +18,7 @@
 
 ==argument uint duration optional
 
-The length of time to sleep for in seconds. If not specified, sleeps indefinately.
-
+The length of time to sleep for in seconds. If not specified, sleeps indefinitely.
 
 ==copyright
 
--- a/core/src/commands.cpp	Thu Sep 09 15:47:34 2010 +0100
+++ b/core/src/commands.cpp	Tue Sep 14 09:49:39 2010 +0100
@@ -83,11 +83,24 @@
 		RArray<TPtrC> commands;
 		CleanupClosePushL(commands);
 		gShell->CommandFactory().ListCommandsL(commands);
-		iFormatter = CTextFormatter::NewL(Stdout());
-		iFormatter->ColumnizeL(0, 2, commands.Array());
+		if (!Stdout().AttachedToConsole())
+			{
+			// Print them one per line (like how ls does it when not attached to a console)
+			for (TInt i = 0; i < commands.Count(); i++)
+				{
+				// The async writing is a legacy from when help was a local command. We don't need to observe it now.
+				Printf(_L("%S\r\n"), &commands[i]);
+				}
+			Complete();
+			}
+		else
+			{
+			iFormatter = CTextFormatter::NewL(Stdout());
+			iFormatter->ColumnizeL(0, 2, commands.Array());
+			Stdout().Write(iFormatter->Descriptor(), iStatus);
+			SetActive();
+			}
 		CleanupStack::PopAndDestroy(&commands);
-		Stdout().Write(iFormatter->Descriptor(), iStatus);
-		SetActive();
 		}
 	}
 
@@ -3622,7 +3635,6 @@
 
 	if (iTimeout)
 		{
-		timer.After(timerStat, iTimeout * 1000 * 1000);
 		User::WaitForRequest(waitStatus, timerStat);
 		if (iMeasure) endTime = User::NTickCount();
 
--- a/documentation/change_history.pod	Thu Sep 09 15:47:34 2010 +0100
+++ b/documentation/change_history.pod	Tue Sep 14 09:49:39 2010 +0100
@@ -28,7 +28,7 @@
 
 =item *
 
-Fixed a defect in iosrv.exe that caused a panic if a foreground read object was attached to a different end point. This was due to the read object being notified of a change in foreground before its iEndPoint member was updated. This member is now updated before attempting the attach, and is set to NULL in the event of a leave (resulting in the read object being left in an unattached state).
+Fixed a defect in iosrv.exe that caused a panic if a foreground read object was attached to a different end point. This was due to the read object being notified of a change in foreground before its iEndPoint member was updated. This member is now updated before attempting the attach, and is set to NULL in the event of a leave (resulting in the read object being left in an unattached state). Fixed race condition and hang in C<pcons start>.
 
 =item *
 
@@ -36,7 +36,7 @@
 
 =item *
 
-Added C<--codesegs> option to L<ps|commands::ps>.
+Added C<--codesegs> option to L<ps|commands::ps> and C<--no-write> option to L<gobble|commands::gobble>.
 
 =item *
 
@@ -46,6 +46,10 @@
 
 fshell's current working directory is now normalised (via new TFileName2::Normalize function) so that the case matches what's on the filesystem).
 
+=item *
+
+Fixed crash in L<start's|commands::start> C<--timeout> option.
+
 =back
 
 =head2 Release 000.2-000.5
--- a/libraries/iosrv/client/command_base.cpp	Thu Sep 09 15:47:34 2010 +0100
+++ b/libraries/iosrv/client/command_base.cpp	Tue Sep 14 09:49:39 2010 +0100
@@ -1994,7 +1994,7 @@
 	_LIT(KFormFeed, "\f");
 	_LIT(KHorizontalTab, "\t");
 	_LIT(KVerticalTab, "\v");
-	_LIT(KNewLine, "\n");
+	_LIT(KLineFeed, "\n");
 	_LIT(KCarriageReturn, "\r");
 	if (!aLex.Eos())
 		{
@@ -2017,7 +2017,7 @@
 				aBuf.AppendL(KVerticalTab);
 				break;
 			case 'n':
-				aBuf.AppendL(KNewLine);
+				aBuf.AppendL(KLineFeed);
 				break;
 			case 'r':
 				aBuf.AppendL(KCarriageReturn);