From: jdawson@ccwf.cc.utexas.edu (John Dawson)
Newsgroups: comp.sys.next.programmer
Subject: Re: Serial port communication difficulties
Date: 15 Nov 92 19:10:12 GMT
	<1992Nov11.091546.5251@urz.unibas.ch>
	<1992Nov11.224715.12841@cs.tu-berlin.de>
Organization: The University of Texas at Austin
In-reply-to: marcel@opal.cs.tu-berlin.de's message of 11 Nov 92 22:47:15 GMT

Victor White writes:

> But on the Next, it seems much harder.  I simply thought by
> opening a file being /dev/cua, I could check the ports status
> via feof().  But alas, it always says theres more data there,
> and so it continially gets hung on reading after the lasst
> charachter is read.  I tried all sorts of variations with the
> cable, conecting various permutaions of RTS/CTS and so on, but
> to no avail.
>
> In sum, the Next has no trouble reading the data from the port.
> But its only problem is that it can not find a correct answer
> for the status of the port.
>
> Is there a simple solution or a better way?

I believe that the problem you're having is simply that you're
expecting to find an EOF from a device that is a non-closing stream.
feof() works "funny" on sockets and certain devices.  You will never
get an EOF unless the stream gets broken.  I don't know much about
your problem here, but I suspect that a fix would be to code your
loops differently.  Instead of having a loop that looks like this ...

    FILE *fp;

    fp = fopen("/dev/cua", "rb");
    while (!feof(fp)) {
        /* ... */
    }

... or maybe like this ...

    FILE *fp;
    int nread;
    char buf[BUFSIZE];

    fp = fopen("/dev/cua", "rb");

    for (;;) {
        nread = fread(buf, BUFSIZE, 1, fp);
        if (nread == 0)
            break;  /* No more input ... */
    }

, try a poll like this:

    FILE *fp;
    int fd;
    int nfound;
    fd_set fdset;
    fd_set readfds;
    struct timeval timeout = { 0L, 0L };
    BOOL input_waiting_on_cua;

    fp = fopen("/dev/cua", "rb");
    fd = fileno(fp);

    FD_ZERO(&fdset);
    FD_SET(fd, &fdset);
    nfound = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
    input_waiting_on_cua = nfound == 1 ? YES : NO;

I had a problem with fread() and feof() myself a while back that took
a terribly long time to figure out.  fread() is nice sometimes, but it
oversimplifies the picture of what files really are, file descriptors.
To write code that deals with asynchronous I/O without blocking, there
really isn't any way around using open(), read(), write(), and
select().  Actually, that's a lie.  You could do something like this:

    int fd_flags;
    int fd;

    fd = /* ... */

    fd_flags = fcntl(fd, F_GETFL, 0);
    fd_flags |= FASYNC;
    fcntl(fd, F_SETFL, fd_flags);
    signal(SIGIO, sigio_fn);

    /* ... */

    int sigio_fn(int signal)
    {
        process_input();
    {

... but it's hard to get signal stuff to work robustly; and if your
program is an AppKit program, it is extremely difficult to write code
that works; The AppKit and signals don't mix well at all.

If NeXT were running on a real version of UNIX, you'd have more
options available.  For example, on a Sun, you could use fcntl() to
set a flag called FNDELAY on an open file descriptor that would mark
it as non-blocking.  Then, you could use fread(); it would just return
0 when there was no more input waiting on your stream.  But NOOOOOOOO
... If NeXT were even POSIX-compliant, which they said they were going
to be come 3.0, they'd have a similar facility.

I'll shut up now.  Your message is several days old anyway; you
probably have already figured out how to solve your problem by
yourself!  :-)

...jkd

P.S. -- Email to you bounced for me, too.  I tried sending this mail a
couple of days ago.
--
jdawson@ccwf.cc.utexas.edu (John Dawson)
Newsgroups: comp.sys.next.programmer