home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.sys.sun.apps:2896 comp.sys.sun.hardware:6655 comp.sys.sun.misc:6144 comp.sys.sun.admin:9971
- Newsgroups: comp.sys.sun.apps,comp.sys.sun.hardware,comp.sys.sun.misc,comp.sys.sun.admin
- Path: sparky!uunet!wupost!zaphod.mps.ohio-state.edu!sdd.hp.com!network.ucsd.edu!scubed!scatter@scubed.com
- From: scatter@scubed.com (McLaughlin)
- Subject: ioctl() on the SPARC
- Message-ID: <1993Jan6.021151.7243@scubed.com>
- Followup-To: comp.sys.sun.misc
- Keywords: ioctl termio
- Sender: usenet@scubed.com (USENET News System)
- Nntp-Posting-Host: vulcan
- Reply-To: scatter@scubed.com
- Organization: S-CUBED Division of Maxwell Laboratories
- Date: Wed, 6 Jan 1993 02:11:51 GMT
- Lines: 179
-
- I am controling a device over one of an RS-232 line on an IPC.
- I am having difficulties.
-
- My problem is that ioctl() does not seem to be doing what the man
- page(s) advertise. Of coarse, it is a good possibility that I am
- screwed up and the problem is pilot error on my part. If there is
- some lore and wisdom out there in netland, I would gladly like to
- find out now before I spend more time beating my head against the
- wall. I have a version of the code working on an SGI, so I know that
- the "Non-Canonical Mode Input Processing" works on that machine.
-
- 1) Am I using ioctl() incorrectly?
- 2) Is ioctl() broken under SUNOS?
- 3) Will my code be broken again when we go to SOLARIS?
- 4) Was termio(4) and ioctl invented for some programmer's job security?
- 5) Am I going to have to write my own interupts?
-
- The root of my problem is that according to the termio(4) man page I should be
- able to use "Non-Canonical Mode Input Processing" and set MIN and TIME.
- I am interested in Case C: MIN = 0, TIME > 0 and Case D: MIN = 0, TIME = 0.
- The termio(4) man page says:
-
- ".....
- Case C: MIN = 0, TIME > 0
- In this case, since MIN = 0, TIME no longer represents an
- intercharacter timer. It now serves as a read timer that is
- activated as soon as a read() is done. A read is satisfied
- as soon as a single character is received or the read timer
- expires. Note: in this case if the timer expires, no char-
- acter will be returned. If the timer does not expire, the
- only way the read can be satisfied is if a character is
- received. In this case the read will not block indefinitely
- waiting for a character - if no character is received within
- TIME*.10 seconds after the read is initiated, the read will
- return with zero characters.
-
- Case D: MIN = 0, TIME = 0
- In this case return is immediate. The minimum of either the
- number of characters requested or the number of characters
- currently available will be returned without waiting for
- more characters to be input.
- ....."
-
- My problem is that no matter how long I wait, whether MIN=0 or 1, my read()
- never returns if the external device has not transmitted a character.
- It does not matter whether TIME = 0 or 1. It is working as if TIME = INFINITY.
-
- My routine, lvr_init(), for opening the port is listed below.
-
- /* a whole bunch of includes */
- #include <stdio.h>
- #include <string.h>
- #include <termios.h>
- #include <sgtty.h>
- #include <fcntl.h>
- #include <errno.h>
- /* Global Static Variables */
- static struct termios new_port_d2;
- static struct termios old_port_d2;
- static struct sgttyb old_port, new_port;
- static struct tchars new_tchars, old_tchars;
- static struct ltchars new_lchars, old_lchars;
- /* the pointer to the LVR tyy port */
- static int fdes;
- /* termio and sgtty stuff */
- int ldisc = NTTYDISC;
- int local_mode = 0;
-
- int lvr_init (tty) /* initialize communications with lvr */
- char * tty; /* device name such as /dev/ttyb */
- {
- extern int errno;
- int i;
- int ioctl_err;
-
- /* opening port */
- if ((fdes = open (tty, O_RDWR | O_NDELAY | O_NOCTTY )) == -1) {
- fprintf (stderr, "lvr_init error: cannot open tty port %s.\n", tty);
- return (-1);
- }
-
- /* get termio struct for device */
- if ((ioctl_err = ioctl (fdes, TCGETS, &old_port_d2)) == -1) {
- fprintf (stderr, "lvr_init error: old termio struct. fdes =%d\n", fdes);
- close (fdes);
- return (-1);
- }
-
- /* initialize new termio struct */
- new_port_d2.c_iflag = IGNPAR; /* input flag */
- new_port_d2.c_oflag = 0; /* output flag */
- new_port_d2.c_cflag = B9600 | CS8 | CLOCAL; /* 9600 Baud and 8 bits */
- new_port_d2.c_lflag = 0; /* local modes */
- new_port_d2.c_line = old_port_d2.c_line;
- for (i = 0; i < NCCS; i++)
- new_port_d2.c_cc[i] = old_port_d2.c_cc[i];
-
- /* required for non-cononical input mode processing */
- /* VMIN is minimum number of characters for the read to satisfy */
- /* VTIME is in units of 0.10 sec */
- /* setting VEOF or VMIN */
- new_port_d2.c_cc[4] = 0;
- /* setting VEOL or VTIME */
- /* this does not work,...... */
- new_port_d2.c_cc[5] = 1;
- /* this sort of works but is not what I want........ */
- new_port_d2.c_cc[5] = 0;
-
- if ((ioctl_err = ioctl (fdes, TCSETS, &new_port_d2)) == -1) {
- fprintf (stderr, "lvr_init: new termio struct. fdes =%d\n", fdes);
- close (fdes);
- return (-1);
- }
-
- /* Get current SGTTYB struct for /dev/tty* */
- if ((ioctl_err = ioctl (fdes, TIOCGETP, &old_port)) == -1) {
- fprintf (stderr, "LVR_IOCTL_SGTTY\n");
- return (-1);
- }
-
- /* Get current TCHARS struct for /dev/tty* */
- if ((ioctl_err = ioctl (fdes, TIOCGETC, &old_tchars)) == -1) {
- fprintf (stderr, "LVR_IOCTL_TCHARS\n");
- return (-1);
- }
-
- /* Initialize new SGTTYB struct */
- new_port.sg_ispeed = B9600; /* 9600 baud input */
- new_port.sg_ospeed = B9600; /* 9600 baud output */
- new_port.sg_flags = RAW; /* Raw mode */
-
- if ((ioctl_err = ioctl (fdes, TIOCSETP, &new_port)) == -1) {
- fprintf(stderr, "lvr_init: setting sgtty\n");
- close (fdes);
- return (-1);
- }
-
- /* Initialize new line discipline */
- if ((ioctl_err = ioctl (fdes, TIOCSETD, &ldisc)) == -1) {
- fprintf(stderr, "lvr_init: ldisc\n");
- close (fdes);
- return (-1);
- }
-
- /* Set special characters */
- if ((ioctl_err = ioctl (fdes, TIOCSETC, &new_tchars)) == -1) {
- fprintf(stderr, "lvr_init: spec chars\n");
- close (fdes);
- return (-1);
- }
-
- /* Set local modes */
- if ((ioctl_err = ioctl (fdes, TIOCLBIS, &local_mode)) == -1) {
- fprintf(stderr, "lvr_init: local mode\n");
- close (fdes);
- return (-1);
- }
-
- if ((ioctl_err = ioctl (fdes, TIOCSLTC, &new_lchars)) == -1) {
- fprintf(stderr, "lvr_init: local spec\n");
- close (fdes);
- return (-1);
- }
-
- /* Flush input and output buffers just for drill */
- if ((ioctl_err = ioctl (fdes, TIOCFLUSH, 0)) == -1) {
- fprintf(stderr, "lvr_init: FLUSH_PORT\n");
- return (-1);
- }
-
- return (0);
- } /* end lvr_init */
-
-
- --
- Keith L. McLaughlin (scatter)
- e-mail: scatter@vulcan.scubed.com, scatter@seismo.CSS.GOV
- phone: 619-587-8436, 619-453-0060, FAX 619-755-0474
- snail-mail: S-CUBED, Div. Maxwell Laboratories, POB 1620, La Jolla, CA 92038
-