Xref: utzoo comp.lang.c:8206 comp.unix.questions:6076 comp.unix.wizards:7087 Path: utzoo!mnetor!uunet!husc6!mailrus!nrl-cmf!ames!ucsd!ncr-sd!laman From: laman@ncr-sd.SanDiego.NCR.COM (Mike Laman) Newsgroups: comp.lang.c,comp.unix.questions,comp.unix.wizards Subject: Re: keypressed()--- and the answer is: Message-ID: <2098@ncr-sd.SanDiego.NCR.COM> Date: 15 Mar 88 18:51:10 GMT References: <136@forty2.UUCP> <3961@galbp.LBP.HARRIS.COM> <303@wsccs.UUCP> Reply-To: laman@ncr-sd.SanDiego.NCR.COM (0000-Mike Laman) Organization: NCR Corporation, Rancho Bernardo Lines: 112 In article <303@wsccs.UUCP> terry@wsccs.UUCP (terry) writes: >In article <3961@galbp.LBP.HARRIS.COM>, phil@galbp.LBP.HARRIS.COM (Phil McDonald) writes: >> In article <136@forty2.UUCP> eschle@forty2.UUCP (Patrik Eschle) writes: >> >How do I write a function keypressed(), that returns 0 if no >> >char is in the input queue and returns the character otherwise? >> >Keypressed() should not block, and should leave the terminal in its >> >initial state after returning. Stuff deleted >2) This isn't breif, so implimentation is left up to the student: > > A. Define a shared memory segment. > B. Make sure the shared memory segment has room for 2 characters. > C. Zero the first character. > D. Fork a child process to hang on a single character read. > E. When the read completes, the child process puts the character > into the second character position of the shared memory, then > sets the first to one. > F. The child process buzz-loops on the first character position, > and loops back up to the 'hang-on-read' when the first character > is returned to zero. > > meanwhile... > > G. The main program occasionally looks at the first character. > H. When the first character is non-zero, it moves the second to a > local buffer, then zeroes it. > >3) Same as #2, except the child process is another program, which is > popen()'ed. > > Instead of a fork, a popen( "program", "r") is done, where the > purpose of the child is to hang on the read and signal the parent > (via a signal, semaphore, or shared memory) when the read completes, ^^^^^^ BE VERY CAREFUL! On System V and V.2 this won't work if the parent process gets too far behind the reading child process. If a signal is "posted" (i.e. generated) from the child process before the parent process gets a chance to handle an outstanding signal (including reseting the signal catcher to itself for the next signal), the signal is lost since the (I believe) the process's (kernel level) signal bit flag for that particular signal is already set and ORing it "on" again has no effect. When the bit is already set and another signal event for that same signal exists, the ORing makes no internal state changes in the process's (kernel level) signal bit flag and is thus "lost". The good news is that one has to generate the stuff pretty fast. This causes the child to generate signals for each character, and if the parent gets behind on handling the signal then the signal can get "lost". If your machine is slow, I'd suggest being VERY parinoid if you use this scheme. You might also consider what may happen if the system gets busy. Remember that if you lose ONE signal, your parent will be "forever" out of sync, unless you make some arrangement in the parent to make sure at certain times that you have gotten all of the input. But then that reverts you back to what you were trying to get around. > then the child writes the character read to the pipe. A better method > whold be to write the character to the pipe first. In the signal case this would even help the parent lag behind the child. > When the parent realizes that a character there, via whatever method, > it reads *from the pipe* the character read by the child. ^^^^^^^^^^^^^ This assumes that your process will receive one signal per character. > All of the methods described above are not the fastest, but they >will work. Which one you should use depends on your situation, and your >operating system. ...... And if the system is slow enough signals will get "lost", and the parent process will not read get behind on reading characters since the parent assumes only one read per signal. Also note that if this situation occurs, you have degenerated back to the situation in which your proposition occurs. [ Text deleted ] > Some systems do NOT support semaphores, or support them such that >you wouldn't want to use them, even if you trusted them, which you don't. >The same goes for shared memory. Signals are reliable, but can be slow, ^^^^^^^^^^^^^^^^^^^^ Not if you push enough of them through before they can be serviced. >depending on the kernal implimentation. ... > > Flame at will. I have working code for all the above, and I *love* ^^^^^^^^^^^^^ I'm just adding my experiences to the proposal. >it when someone sticks their foot in their mouth so I can give compileable ^^^^^^^^^^^ Compileable doesn't mean it will have the semantics that he needs. >examples of why they are a fool. :-) (In the voice of Curly of the three stooges) "I resemble that" :-). For what it's worth, the problems I had with the signals on System V and System V.2 with "losing" signal, made me very wary of them when one approaches pushing them too hard. Sigh... I just thought I'd save you some time/trouble if you get into this situation. I don't know if there are any problems with BSD signals. Off hand they would seem to be better, but I know of them from a few of the user interface routines. I'm only speaking of System V and System V.2. Mike Laman UUCP: ncr-sd!laman