sah9577@ritcv.UUCP (Scott Hossler) (02/25/85)
I am working an a very simple game using graphics text with a GiGi terminal. I am having a big problem with the input. When I get to a read, or any input statment, in C, everything stops and waits for the input. I want to be able to have the program check for keyboard input, and if it is there to act upon it, otherwise to continue processing. Is there an easy way to do this in C. I am doing this on a VAX runnung 4.2 if that makes a difference. I have played around with the low leval input described in a V7 manual, but couldn't get any where. My next thought is to fork off a process for the background and one for the user's charactor and then use a semaphore to allow access to the graphics cursor. Is this nessassary, and if it is, any hints on what to watch out for? Thanks to all. scott hossler rochester!ritcv!sah9577
jlup@cci-bdc.UUCP (John Lupien ) (02/27/85)
> I am working an a very simple game using graphics text with a > GiGi terminal. I am having a big problem with the input. When > I get to a read, or any input statment, in C, everything stops > and waits for the input. > [text cut for brevity. Scott wants non-blocking I/O, that is "read if data, but don't wait for data.] > > Is there an easy way to do this in C. > I am doing this on a VAX running 4.2 if that makes a difference. > > scott hossler > rochester!ritcv!sah9577 Scott, your big problem lies in the use of a V7 manual. Read the 4.2 manual on tty(4) and fcntl(2) for the right way read without blocking. In brief; stty cbreak /* use ioctl, stty(2), whatever */ #include <sys/types.h> #include <sys/uio.h> #include <fcntl.h> res = fcntl (stdin, F_SETFL, FNDELAY); if (res == -1) { printf("Can't set up terminal. Goodbye\n"); exit(1); } if (read (stdin, buf, bytes) == -1) { if (errno != EWOULDBLOCK) { printf ("Screwy I/O error: errno = %d. Bombing...\n", errno); exit(1); } noread = TRUE; } else { noread = FALSE; } if (noread) { /* do processing for *no input* condition */ } else { /* process input in buf. */ } Although the above is not in any sense a legal program, this is the kind of thing you need to do on 4.2 to get the functionality you describe. I hope I understood your needs, but this should be of general interest to BSD users anyway. -John Lupien CCI Boston Development Center 222 Third St. Cambridge,MA 02142 <imaginary data>
mroddy@enmasse.UUCP (Mark Roddy) (02/28/85)
[ bug me not ] { use nodelay mode to solve reading from empty terminal input file } But if you don't have 4.2, V3(5): alarm(x); read(0,buf,1); alarm(0); /* and set up a signal routine for SIGALARM */ x is the number of seconds your read will time out in. There is a problem here, if you lose the cpu at alarm(x), you may get alarmed before read. You could lock yourself in before the alarm call, but that's rather rude. I was reading Creative Computing when I saw the most bogus C programming example. The author was comparing C to Basic- Basic: if A=1 and B=1 goto 104950393040 [:-> C: if (A==1 & B==1) foobar(); Which works, of course, but it was clear from the context that the author thought that '&' and logical AND were identical!!!! Boy is he in for a surprise. Don't they have editors at that mag? -- Mark Roddy Net working, Just reading the news. (harvard!talcott!panda!enmasse!mroddy)
ndiamond@watdaisy.UUCP (Norman Diamond) (03/04/85)
> I was reading Creative Computing when I saw the most bogus C programming > example. The author was comparing C to Basic- > Basic: if A=1 and B=1 goto 104950393040 [:-> > C: if (A==1 & B==1) foobar(); > Which works, of course, but it was clear from the context that the author > thought that '&' and logical AND were identical!!!! -- Mark Roddy It doesn't work if A == 1 and B == 3. It calls foobar when it shouldn't. -- Norman Diamond UUCP: {decvax|utzoo|ihnp4|allegra}!watmath!watdaisy!ndiamond CSNET: ndiamond%watdaisy@waterloo.csnet ARPA: ndiamond%watdaisy%waterloo.csnet@csnet-relay.arpa "Opinions are those of the keyboard, and do not reflect on me or higher-ups."
meister@faron.UUCP (Philip W. Servita) (03/04/85)
>> I am working an a very simple game using graphics text with a >> GiGi terminal. I am having a big problem with the input. When >> I get to a read, or any input statment, in C, everything stops >> and waits for the input. >> >[text cut for brevity. Scott wants non-blocking I/O, that is "read if >data, but don't wait for data.] >> >> Is there an easy way to do this in C. >> I am doing this on a VAX running 4.2 if that makes a difference. >> >> scott hossler >> rochester!ritcv!sah9577 i did this once i a game program also. try the following: #include <sgtty.h> ... char inkey() { long charwaiting; char getchar(); ioctl(0,FIONREAD,&charwaiting); if(charwaiting) return(getchar()); return((char) 0); } returns the next character on the stdin stream if there is one, 0 otherwise. this will only work in cbreak or raw mode. look up tty(4) for details. -the venn buddhist -- --------------------------------------------------------------------- is anything really trash before you throw it away? ---------------------------------------------------------------------
tim@callan.UUCP (Tim Smith) (03/09/85)
In article <7026@watdaisy.UUCP> ndiamond@watdaisy.UUCP (Norman Diamond) writes: >> I was reading Creative Computing when I saw the most bogus C programming >> example. The author was comparing C to Basic- >> Basic: if A=1 and B=1 goto 104950393040 [:-> >> C: if (A==1 & B==1) foobar(); >> Which works, of course, but it was clear from the context that the author >> thought that '&' and logical AND were identical!!!! -- Mark Roddy > >It doesn't work if A == 1 and B == 3. It calls foobar when it shouldn't. Mr. Roddy is correct. I think Mr. Diamond is forgetting that the range of the '==' operator is {0,1}. -- Duty Now for the Future Tim Smith ihnp4!wlbr!callan!tim or ihnp4!cithep!tim
dave@lsuc.UUCP (David Sherman) (03/19/85)
In article <247@faron.UUCP> meister@faron.UUCP (Philip W. Servita) writes: ||>[text cut for brevity. Scott wants non-blocking I/O, that is "read if ||>data, but don't wait for data.] || || ioctl(0,FIONREAD,&charwaiting); That's fine for BSD (which was the system the questioner wanted it for). Anyone have an easy way of doing this for v7? I'm willing to do a limited amount of kernel hacking. Dave Sherman The Law Society of Upper Canada -- {utzoo pesnta nrcaero utcs hcr}!lsuc!dave {allegra decvax ihnp4 linus}!utcsri!lsuc!dave
sjoerd@tjalk.UUCP (Sjoerd Mullender) (03/21/85)
In article <522@lsuc.UUCP> dave@lsuc.UUCP (David Sherman) writes: >In article <247@faron.UUCP> meister@faron.UUCP (Philip W. Servita) writes: >||>[text cut for brevity. Scott wants non-blocking I/O, that is "read if >||>data, but don't wait for data.] >|| >|| ioctl(0,FIONREAD,&charwaiting); > >That's fine for BSD (which was the system the questioner wanted it for). >Anyone have an easy way of doing this for v7? I'm willing to do a >limited amount of kernel hacking. Here is a C routine that returns non-zero if there was any input pending. This is for a V7 PDP 11 system. The only requirement is that /dev/kmem is readable (which it should NOT be for security). #include <sys/param.h> #include <sys/dir.h> #include <sys/user.h> inputpending() { static int fd = -2; unsigned c; if (fd == -2) /* uninitialized */ if ((fd = open("/dev/kmem", 0)) >= 0) { /* If the open fails, fd will be -1, so we won't * try again. * Close the file descriptor on exec. */ ioctl(fd, FIOCLEX, (struct sgttyb *) 0); /* 0140000 is the beginning of the u area * u_ttyp is the pointer to the tty struct */ lseek(fd, (long) &((struct user *) 0140000)->u_ttyp, 0); read(fd, &c, sizeof c); /* seek to the beginning of the tty struct */ lseek(fd, (long) c, 0); } if (fd < 0) return 0; /* the first 2 byte of the tty struct is a pointer to the clist */ if (read(fd, &c, sizeof c) < sizeof c) return 0; lseek(fd, - (long) sizeof c, 1); /* there is input when the pointer to the clist is != 0 */ return c != 0; } -- Sjoerd Mullender ...!{decvax,philabs,seismo}!mcvax!vu44!sjoerd
alexis@reed.UUCP (Alexis Dimitriadis) (03/24/85)
In article <522@lsuc.UUCP> dave@lsuc.UUCP (David Sherman) writes: >||>[text cut for brevity. Scott wants non-blocking I/O, that is "read if >||>data, but don't wait for data.] >|| >|| ioctl(0,FIONREAD,&charwaiting); > >That's fine for BSD (which was the system the questioner wanted it for). >Anyone have an easy way of doing this for v7? I'm willing to do a >limited amount of kernel hacking. I have gotten the same effect without using non-blocking I/O at all. I used it to write a real-time "game", so the following is in that context. If you have the equivalent of setitimer(), which arranges for a signal to be sent to your process after a specified amount of time, then you can set the signal handler to be the routine that makes things happen with time. (e.g., advances the killer ships) The same routine should also reset the timer if it cannot automatically be set to repeat. (And the handler, if it gets reset!) Then the main thread of your program can block waiting for input to process, and things will happen in `real time' by repeated calls to the handler. You have to be careful not to confuse the main thread by altering things while it is processing input, (e.g. by ignoring the alarm for a while), and to make sure alarms do not come so often that the input never gets read at all, as will be the case if the handler takes a while. (You can discard pending alarms or whatever). It is fairly straightforward, but may be difficult to debug, since the control flow is strange. The safest course is probably to block alarms while processing input, and unblock them just before a read. The approach needs a fairly sophisticated interrupt handler, but can be used where non- blocking I/O is not implemented. Alexis Dimitriadis -- _______________________________________________ alexis @ reed ...ihnp4!{harvard|tektronix}!reed ...decvax!tektronix!reed ...teneron!reed