How to peek at STDIN with Delphi 7? - delphi

In a Delphi 7 console application, how can I check whether stdin holds a character, without blocking until one is entered?
My plan is that this console program will be executed by a GUI program, and its stdin will be written to by the GUI program.
So I want my console app to periodically check stdin, but I can't find a way of doing this without blocking.
I have looked at this answer, which gets me a stream pointing to stdin, but there's still no way to "peek" as far as I can see.

I think you have already found the right way to read stdin. It is meant to block when there's nothing more to be read.
The standard way to handle this is to use a separate thread to handle the pipe. When it receives new data from stdin it signals this to the processing thread, for example with a message passing mechanism.
Having said all that, if you really want to poll you can call PeekNamedPipe to check if there is data in the pipe.

You could as the other answer says use threads, but even then you might have problems (using the threading method) unless you also investigate overlapped IO.
I normally use overlapped IO with serial ports rather than stdin, where "read a character if one is ready" is commonly needed, and where non-blocking IO is a usual way of working. You should be able to adapt the technique shown here. However, if I was writing an application that was keyboard driven (instead of purely driven by say, a file redirected to standard input) I would let go of StdIN, and use a CRT type unit. So, if you don't mind letting go of StdIn, and simply want to have a keyboard-driven input model, you could look at console based APIs and abandon the very limiting StdIn capabilities. For an example of a "kbhit" function that uses the Win32 Console APIs see here.

There is no other way (as far as i know), as reading from a pipe inside a separate thread. Otherwise as you already have seen, the readfile operation will block. I wrote an example how to do this, an example project is also available: redirect stdoutput
Edit: Well, reading your question another time, i understand that your problem lies within the console program, not the calling application. I wonder what your console application expects, normally a console application knows when it needs input and cannot proceede until the user enters this information. Do you need to check for an exit?

For a Stream if you .Read() the function result is the number of bytes read which will be zero if there was nothing there even if you asked for more. From the Delphi help for Classes.TStream.Read:
Read is used in cases where the number of bytes to read from the stream is not necessarily fixed. It attempts to read up to Count bytes into buffer and returns the number of bytes actually read.

Related

Is there a way to have a future complete when a Stream is "done" without actually draining the messages, in Dart?

I want to see if the other side gave up and closed the sink of a StreamChannel, without actually reading the messages yet.
(I'm going to be handing the stream to someone else, so i can't listen() to it, since you're only allowed to listen once per stream.)
[posting for a friend, credit to them for asking the question]
In short, no.
There is no concept of "giving up". If you put events into a non-broadcast stream, they'll stay there until someone listens to the stream (which is why you shouldn't put data there until someone listens, you're just wasting memory).
That includes the done event, and you won't get to the done event without first reading all the preceding events. That's the core abstraction of a stream - a source of events accessed in order, it's not done until it's actually done.
What I think you are looking for is a "side channel" that can communicate information about the stream without going through the stream (that is, out-of-band).
Something like that can surely be built - in about one gazillion different ways, depending on what you want, but it's just not something that a Stream supports by default, nor does a StreamChannel, if I read it correctly (I have never used a StreamChannel myself).

Receiving data using aux cable on GNU RADIO

I am transmitting and receiving data using aux cable and GNU RADIO between two laptops.
I have implemented DQPSK using PSK mod block.
The problem is that while receiving I have to provide a delay, some integer value e.g 0,1,2 etc.
It is different every time.
Is there a way to dynamically check for the right delay value or any other workaround to this situation?
I have written 'start.' at the start of data being transmitted and 'end.' at the end.
I have to give a demo for this project and I dont want to manually change the delay at runtime.
I cannot find the .cc file of file sink in GNU RADIO, I can change the C++ code according my requirement but there is no such file.
Below is the screenshot of the grc file on the receive side.
Any help will be appreciated.
Since there's no way for the receiver to know when the transmitter started transmitting, it decodes stuff before there's actually anything to decode.
In essence, you need some kind of preamble or so to tell your receiver when to start – side effect of having something like that would be that you could correct some things (the two sound cards don't share the same oscillator, which leads to a symbol rate offset, and a center frequency offset).
You basically added that framing - your start. and end. strings.
I cannot find the .cc file of file sink in GNU RADIO, I can change the C++ code according my requirement but there is no such file.
It's in gr-blocks/lib; however, you shouldn't modify the file sink. Really,
I'd recommend you take the time to go through the guided tutorials, use gr_modtool to generate a general block which has a state machine that looks for the bits of your start string and drops everything before and including those, and then passes everything till it sees the stop string. That all can be done with a single state machine, and a bit of python or C++ code.

What can cause CICS transaction to write out of CICS allocated memory?

I'm using CICS in Cobol program and I've noticed that sometimes data are written out of the CICS memory. It cause a data corruption and my application stop. I don't know where it append, so I'm creating a parser to analyse my Cobol code to look for possible corruption in COMMAREA used by CICS. Now I checked following statements :
EXEC CICS XCTL
EXEC CICS LINK
EXEC CICS RETURN TRANSID
For each, I check if sent length (declared in LENGTH parameter) is not greater than sent COMMAREA. Then I check if DFHCOMMAREA, in the receiving program is not greater than sent COMMAREA (according to this doc http://publib.boulder.ibm.com/infocenter/cicsts/v3r1/index.jsp?topic=%2Fcom.ibm.cics.ts31.doc%2Fdfhp3%2Fdfhp37t.htm) :
The receiving data area need not be of the same length as the original communication area; if access is required only to the first part of the data, the new data area can be shorter. However, it must not be longer than the length of the communication area being passed. If it is, your transaction may inadvertently attempt to read data outside the area that has been passed. It may also overwrite data outside the area, which could cause CICS to abend.
Now, I'm wondering what other things should I parse in order to detect memory overwritting?
As you are using Micro Focus COBOL, you could set the memory_strategy tunable (or the CBL_MEM_STRATEGY API) to help you analysis where the error is occurring by allowing the runtime to protect memory in various different ways.
Memory can also be validate via the "CBL_MEM_VALIDATE" call.
Another thing can do is use the tracing support... lookup CTF (Consolidated Tracing Facility). This will give you an idea where you code is at the time of the error.
Some References that will help you;
http://kb.microfocus.com/display/4/kb/article.aspx?aid=31645
http://documentation.microfocus.com/help/index.jsp?topic=%2Fcom.microfocus.eclipse.infocenter.studee60win.sp02ws01%2FHRRTRHRTCF0O.html
http://documentation.microfocus.com/help/index.jsp?topic=%2Fcom.microfocus.eclipse.infocenter.studee60ux.sp02ws01%2FGUID-762085AC-8396-4D71-9CC1-6231551D3AEE.html
For the passing-of-data bounds checking, always use transclusion, which in COBOL is called a COPYCODE or COPYBOOK. Pass the root data element in the copycode, and compile the same version in the caller and called program. This COPYCODE is sortof the contract for the called program, so it is a good idea to have a naming convention tying them together. To make sure they are in-sync, whenever you change the COPYCODE, recompile all programs that reference it.
Also, the use of SSRANGE is great (but someone already mentioned that).
NealB has a good idea. I suggest you also look into the STGPROT and RENTPGM CICS system initialization parameters.
When a CICS program starts writing all over memory it will not only "stop working" but possibly
crash the CICS region as well!
If you are sure that the LENGTH is set properly on LINKs and XCTLs and that you are
receiving the COMMAREA into a linkage record of that size (EIBCALEN), then you should
be fine.
Rather than trying to parse your COBOL programs I suggest that you set compiler
bounds checking options on. The problem you are having is most likely related to
indexing or subscripting beyond the bounds of a working storage table. Attempting to detect
this class of programming error through static analysis is generally not very
effective.
Setting bounds
checking on should detect out of range memory references, issue a diagnostic message to
the log, and then and terminate your program
before it crashes the whole CICS region. The logged message should point you the the
source line where the out of bounds reference occured.
Check out the SSRANGE compile time option. Make sure it is set and that your CICS region
runs LE enabled programs with CHECK(ON).
This should nail out of bounds memory
references pretty quickly.

moving data between processes

The reason I ask this is widows do not support a good method to communicate between processes. So I want to create a DLL for a communications point between windows processes. A thread is owned by a process and cannot be given to another process.
Each thread has a stack of its own.
If a DLL is loaded (loadlibray) and a DLL function is called that asks windows for memory. Am I write to think the thread is still being owned by the same process and allocates memory into that same process.
So I’m thinking can I turn to assembly to reallocate a small memory block to another process. Create a critical section, copy the data over to another (already created) memory block and return to the original block to its original process with out up setting windows. Has any one done that before. Or is thier a better way.
Best regards,
Lex Dean.
I see other methods that mite be quite fast but I would like a very fast method that has little over head. Pipes and internet will obviously work but are not the best option yet simple to implement (thanks to offer such suggestions guys). I want to send quite a few 500 byte blocks at quite regular intervals sometimes. I like WM_COPYDATA because it looks fast, my biggest question that I have been looking all over the internet is:- GetCurrentProcess and DuplicateHandle to get the real handle. Finding the other process. And using messages to set up memory and then use WM_COPYDATA. I only need two messages a) the pointer and size b) the data has been copied.
I get my application process easy ‘GetCurrentProcess’ except it’s a pseudo handle, that’s always $FFFFFFE. I need the real process handle and no body on the internet gives an example of DuplicateHandle. That’s what’s got me stumped. Can you show me an example of DuplicateHandle as that’s what’s got me stumped?
I do not like turning to a form to get a handle as one application dose not always have a current form.
I do not like turning to a form to get a handle as one application dose not always have a current form.
In Delphi I have seen message sending with TSpeedButton to set up a simple fast communication methods between applications that most probably uses about 80 instructions I guess. And so I still thinking to think dll’s. The example Mads Elvheim sent is on that same line as what I already know.
I'm still willing to understand any other options of using my own *.Dll
Because my applications important to me can simply register/unregister on the *.DLL its own process rather than searching all the time to see if a process is current.
It’s how I manage memory with a *.DLL between process but I’m not told about.
To me DLL’s are not hard to implement to me as I already have one of my own in operation.
The real bottom line is access to windows to create a good option. As I’m very open to idea’s. Even the assembly instructions for between processes or a windows call. But I do not what to get court crashing windows ether by doing things illegal.
So please show an example of what you have done that is to my needs. That is fast and I’m interested as I most probably will use it anyway.
I have a very fast IPC (interprocess communication) solution based on named pipes. It is very fast and very easy to use (It hides the actual implementation from you. You just work with data packets). Also tested and proven. You can find the code and the demo here.
http://www.cromis.net/blog/downloads/cromis-ipc/
It also works across computers in the same LAN.
If your processes have message loops (with windows), you can send/receive serialized data with the WM_COPYDATA message: http://msdn.microsoft.com/en-us/library/ms649011(VS.85).aspx
Just remember that only the allocated memory for the COPYDATASTRUCT::lpData member is allowed to be read. Again, you can not pass a structure that has pointers. The data must be serialized instead. And the receiving side can only read this structure, it can not write to it. Example:
/* Both are conceptual windows procedures. */
/* For sending : */
{
...
TCHAR msg[] = _T("This is a test\r\n");
HWND target;
COPYDATASTRUCT cd = {0};
cd.lpData = _tcsdup(msg); // We allocate and copy a string, which is fine.
cd.cbData = _tcsclen(msg) + 1; //The size of our data. Windows needs to know this.
target = FindWindow(..); //or EnumProcesses
SendMessage(target, WM_COPYDATA, (LPARAM)hwnd, (WPARAM)&cd);
}
/* For receiving */
{
...
case WM_COPYDATA:
{
TCHAR* msg;
COPYDATASTRUCT* cb = (COPYDATASTRUCT*)wParam;
sender = FindWindow(..); //or EnumProcesses
//check if this message is sent from the window/process we want
if(sender == (HWND)lParam){
msg = _tcsdup(cb->ldData);
...
}
break;
}
}
Otherwise, use memory mapped files, or network sockets.
I currently use Mailslots in Delphi to do it and it is very efficient.
"Win32 DLLs are mapped into the address space of the calling process. By default, each process using a DLL has its own instance of all the DLLs global and static variables. If your DLL needs to share data with other instances of it loaded by other applications, you can use either of the following approaches:
•Create named data sections using the data_seg pragma.
•Use memory mapped files. See the Win32 documentation about memory mapped files."
http://msdn.microsoft.com/en-us/library/h90dkhs0(VS.80).aspx
You cannot share pointers between processes, they only make sense to the process that alloc'd it. You're likely to run into issues.
Win32 is not different from any other modern OS in this aspect. There are plenty IPC services at your disposal in Windows.
Try to describe, which task you want to solve - not the "...then I think that I need to copy that block of memory here...". It's not your task. Your customer didn't say you: "I want to transfer thread from one process to another".

Overlapped serial port and Blue Screen of Death

I created a class that handles serial port asynchronously. I use it to communicate with a modem. I have no idea why, but sometimes, when I close my application, I get the Blue Screen and my computer restarts. I logged my code step by step, but when the BSOD appeared, and my computer restarted, the file into which I was logging data contained only white spaces. Therefore I have no idea, what the reason of the BSOD could be.
I looked through my code carefully and I found several possible reasons of the problem (I was looking for all that could lead to accessing unallocated memory and causing AV exceptions).
When I rethought the idea of asynchronous operations, a few things came to my mind. Please verify whether these are right:
1) WaitCommEvent() takes a pointer to the overlapped structure. Therefore, if I call WaitCommEvent() inside a function and then leave the function, the overlapped structure cannot be a local variable, right? The event mask variable and event handle too, right?
2) ReadFile() and WriteFile() also take references or pointers to variables. Therefore all these variables have to be accessible until the overlapped read or write operations finish, right?
3) I call WaitCommEvent() only once and check for its result in a loop, in the mean time doing other things. Because I have no idea how to terminate asynchronous operations (is it possible?), when I destroy my class that keeps a handle to a serial port, I first close the handle, and then wait for the event in the overlapped structure that was used when calling the WaitCommEvent() function. I do this to be sure that the thread that waits asynchronously for a comm event does not access any fields of my class which is destroyed. Is it a good idea or is it stupid?
try
CloseHandle(FSerialPortHandle);
if Assigned(FWaitCommEvent) then
FWaitCommEvent.WaitFor(INFINITE);
finally
FSerialPortHandle := INVALID_HANDLE_VALUE;
FreeAndNil(FWaitCommEvent);
end;
Before I noticed all these, most of the variables mentioned in point one and two were local variables of the functions that called the three methods above. Could it be the reason of the BSOD or should I look for some other mistakes in my code?
When I corrected the code, the BSOD stopped occuring, but It might be a coincidence. How do you think?
Any ideas will be appreciated. Thanks in advance.
I read the CancelIo() function documentation and it states that this method cancells all I/O operations issued by the calling thread. Is it OK to wait for the FWaitCommEvent after calling CancelIo() if I know that WaitCommEvent() was issued by a different thread than the one that calls CancelIo()?
if Assigned(FWaitCommEvent) and CancelIo(FSerialPortHandle) then
begin
FWaitCommEvent.WaitFor(INFINITE);
FreeAndNil(FWaitCommEvent);
end;
I checked what happens in such case and the thread calling this piece of code didn't get deadlocked even though it did not issue WaitCommEvent(). I tested in on Windows 7 (if it matters). May I leave the code as is or is it dangerous? Maybe I misunderstood the documentation and this is the reason of my question. I apologize for asking so many questions, but I really need to be sure about that.
Thanks.
An application running as a standard user should never be able to cause a bug check (a.k.a. BSOD). (And an application running as an Administrator should have to go well out of its way to do so.) Either you ran into a driver bug or you have bad hardware.
By default, Windows is configured to save a minidump in %SystemRoot%\minidump whenever a bug check occurs. You may be able to determine more information about the crash by loading the minidump file in WinDbg, configuring WinDbg to use the Microsoft public symbol store, and running the !analyze -v command in WinDbg. At the very least, this should identify what driver is probably at fault (though I would guess it's your modem driver).
Yes, you do need to keep the TOverlapped structure available for the duration of the overlapped operation. You're going to call GetOverlappedResult at some point, and GetOverlappedResult says it should receive a pointer to a structure that was used when starting the overlapped operation. The event mask and handle can be stored in local variables if you want; you're going to have a copy of them in the TOverlapped structure anyway.
Yes, the buffers that ReadFile and WriteFile use must remain valid. They do not make their own local copies to use internally. The documentation for ReadFile even says so:
This buffer must remain valid for the duration of the read operation. The caller must not use this buffer until the read operation is completed.
If you weren't obeying that rule, then you were likely reading into unreserved stack space, which could easily cause all sorts of unexpected behavior.
To cancel an overlapped I/O operation, use CancelIo. It's essential that you not free the memory of your TOverlapped record until you're sure the associated operation has terminated. Likewise for the buffer you're reading or writing. CancelIo does not cancel the operation immediately, so your buffers might still be in use even after you call it.

Resources