diff --git a/tools/c2e/c2e_instr.cpp b/tools/c2e/c2e_instr.cpp
index b78e10caab6626a97d7efe9454c9b91714599471..9d04d7a7da31493bda2c85b72fb42dc166c3254c 100644
--- a/tools/c2e/c2e_instr.cpp
+++ b/tools/c2e/c2e_instr.cpp
@@ -231,21 +231,70 @@ Instruction_t* Cgc2Elf_Instrument::insertTransmit(Instruction_t* after, int sysn
 	return after; 
 }
 
-Instruction_t* Cgc2Elf_Instrument::insertReceive(Instruction_t* after, bool force_stdin) 
+Instruction_t* Cgc2Elf_Instrument::insertReadExitOnEOF(Instruction_t* after)
+{  
+	Instruction_t *jmp2return=NULL, *jmp2error=NULL, *success=NULL, *error=NULL;
+	char buf[100];
+	sprintf(buf, "mov eax, %d", SYS_read);
+	after=insertAssemblyAfter(firp, after, "push esi");	 	// push tx_bytes
+	after=insertAssemblyAfter(firp, after, buf);			// set eax to syscall #
+	after=insertAssemblyAfter(firp, after, "int 0x80");		// make syscall
+
+	after = insertAssemblyAfter(firp, after, "cmp eax, 0");
+	Instruction_t* jmp2terminate=insertAssemblyAfter(firp, after, "je 0x0");	 // jmp to terminate
+
+	after=insertAssemblyAfter(firp, jmp2terminate, "pop esi");	 	// pop tx_bytes
+	after=insertAssemblyAfter(firp, after, "cmp eax, -1");	 	// if return == -1
+	jmp2error=after=insertAssemblyAfter(firp, after, "je 0x0");	 // jmp to error
+	after=insertAssemblyAfter(firp, after, "cmp esi, 0");	 		// if tx_bytes == 0 
+	jmp2return=after=insertAssemblyAfter(firp, after, "je 0x0");	 	// jmp to success
+	after=insertAssemblyAfter(firp, after, "mov [esi], eax");			// store tx_bytes
+	success=after=insertAssemblyAfter(firp, after, "mov eax, 0");	// return success
+	error=after=insertAssemblyAfter(firp, after, "mov eax, 25");	// return error
+	after=insertAssemblyAfter(firp, after, "nop");			// sync point.
+
+	jmp2error->SetTarget(error);
+	jmp2return->SetTarget(success);
+	success->SetFallthrough(after);
+	
+        // terminate sequence
+        Instruction_t* n = addNewAssembly(firp, NULL, "nop"); 
+        n->SetFallthrough(after); // pick anything here, it doesn't matter as we're terminating
+	Instruction_t* term = insertTerminate(n);
+	jmp2terminate->SetTarget(n);
+
+	return after; 
+}
+
+Instruction_t* Cgc2Elf_Instrument::insertReceive(Instruction_t* after, bool force_stdin, bool exit_on_eof) 
 {  
 	if (force_stdin)
 	{
 		// force read from file descriptor 0
 		after = insertAssemblyAfter(firp, after, "push ebx");		// save original fd
 		after = insertAssemblyAfter(firp, after, "xor ebx, ebx");	// fd = 0
-		after = insertTransmit(after, SYS_read);			// invoke SYS_read
+		if (exit_on_eof)
+			after = insertReadExitOnEOF(after);
+		else
+			after = insertTransmit(after, SYS_read);
 		after = insertAssemblyAfter(firp, after, "pop ebx");		// restore
 		return after;
 	}
 	else
-		return insertTransmit(after, SYS_read);
+	{
+		if (exit_on_eof)
+			return insertReadExitOnEOF(after);
+		else
+			return insertTransmit(after, SYS_read);
+	}
 }
 
+// eax          ebx          ecx              edx               esi                        edi
+// int fdwait(int nfds, fd_set *readfds, fd_set *writefds, const struct timeval *timeout, int *readyfds)
+// int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
+
+// %ebx, %ecx, %edx, %esi, %edi, %ebp
+// force_no_timeout: set %edi to 0
 Instruction_t* Cgc2Elf_Instrument::insertFdwait(Instruction_t* after)
 {  
 	Instruction_t *jmp2return=NULL, *jmp2error=NULL, *success=NULL, *error=NULL;
diff --git a/tools/c2e/c2e_instr.hpp b/tools/c2e/c2e_instr.hpp
index 30ac9346299bc57ecd7d94ae7a3bd0ba2c28f4e7..de9782e21bfb591b67c8db483670fee6e9cd8176 100644
--- a/tools/c2e/c2e_instr.hpp
+++ b/tools/c2e/c2e_instr.hpp
@@ -16,8 +16,9 @@ class Cgc2Elf_Instrument
 	private:
 
 		libIRDB::Instruction_t* insertTerminate(libIRDB::Instruction_t* after) ;
-		libIRDB::Instruction_t* insertTransmit(libIRDB::Instruction_t* after, int sysno=SYS_write) ;
-		libIRDB::Instruction_t* insertReceive(libIRDB::Instruction_t* after, bool force_stdin=true) ;
+		libIRDB::Instruction_t* insertTransmit(libIRDB::Instruction_t* after, int sysno=SYS_write);
+		libIRDB::Instruction_t* insertReadExitOnEOF(libIRDB::Instruction_t* after);
+		libIRDB::Instruction_t* insertReceive(libIRDB::Instruction_t* after, bool force_stdin=true, bool forceExitOnEOF=true) ;
 		libIRDB::Instruction_t* insertFdwait(libIRDB::Instruction_t* after) ;
 		libIRDB::Instruction_t* insertAllocate(libIRDB::Instruction_t* after) ;
 		libIRDB::Instruction_t* insertDeallocate(libIRDB::Instruction_t* after) ;