Linux Serial Port Programming problem - ioctl -

Linux Serial Port Programming problem - ioctl -

Post by Grahame M. Kell » Thu, 11 Jul 1996 04:00:00


I am trying to talk to my UPS via a serial port under Linux.
I have a problem talking to it under Linux. I am unsure why the
problem exists because the same program works to a dumb terminal
(/dev/ttyS0) and is OK with a self generated DOS driver.  

/dev/UPS is a symbolic link to /dev/cua1 (Com2 for ya DOS'ies).  UPS
expects 1200 baud, 8 bit data, 2 stop bits and no parity.
I am using the termios.h file, and I have read and re-read the HOWTO's
and other available info on the Net.  I know the port, UPS, and its
cable is OK as I am able to talk correctly to the UPS via a comms
program (Mirror) without changing any hardware.

Any help will be most appreciated.
Thanks & cheers Grahame.

------------------------- program starts here -------------------------
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>

#define TIMEOUT 10
#define FALSE 0
#define TRUE 1
#define MAX 80
#define MYPORT "/dev/UPS"

static int timeout = FALSE;
static char *termname, *name;
static int mfd, wcount = 0, rcount = 0;
char *Mess = "OK", line[MAX];  /* Note No cr/lf needed */
struct termio tsaved, tmp;

static int settimeout()
        fprintf(stderr, "TIMEOUT: on opening %s\n", name);
        timeout = TRUE;


ttyopen(filename, flags)
char *filename;
int flags;
        int (* sigfn)(), mfd = -1;

        termname = filename;

        /*set the timeout flag*/
        timeout = FALSE;

        /*set SIGALRM action*/
        sigfn = signal(SIGALRM, settimeout);

        mfd = open(filename, flags);

        /*reset things*/
        signal(SIGALRM, sigfn);

        return (timeout ? -1: mfd);


int main()
        int (* sigfn)(), status;

        mfd = ttyopen (MYPORT, O_RDWR);
        if (mfd > 0) {
                fprintf(stdout, "TTY Device opened OK\n");
                name = ttyname(mfd);
                if(isatty(mfd)) {
                        fprintf(stderr, "fd %d =>> %s\n", mfd, name);
                        fprintf(stderr, "fd %d =>> Line is not a
terminal!\n", mfd);

                ioctl(mfd, TCGETA, &tsaved);    /* Get the current IOCTL
                tmp = tsaved;                   /* Copied current to
future */

                tmp.c_cflag &= ~CBAUD;          /* Set Buad Rate */
                tmp.c_cflag |= B1200;           /* Baud Rate = 1200 */
                tmp.c_cflag &= ~CSIZE;          /* Set Code Size */
                tmp.c_cflag |= CS8;             /* Codesize = 8 */
                tmp.c_cflag |= CSTOPB;          /* 2 Stop Bits */
                tmp.c_cflag &= ~PARENB;         /* Disable Parity */
                tmp.c_cc[VMIN] = 10;            /* Get char as they come
                tmp.c_cc[VTIME] = 0;
                tmp.c_lflag &= ~ICANON;         /* Raw Mode */

                status = ioctl(mfd, TCSETA, &tmp);
                if (status < 0) {
                        fprintf(stderr, "Error in set ioctl\n");

                wcount = write(mfd, Mess, sizeof(Mess));
                if (wcount != sizeof(Mess)) {
                        fprintf(stderr, "Error: Outputing Mess to %s\n",
                        fprintf(stderr, "%s updated\n", name);

                        /*set the timeout flag*/
                        timeout = FALSE;

                        /*set SIGALRM action*/
                        sigfn = signal(SIGALRM, settimeout);

                        rcount = read(mfd, &line[0], 1);

                        /*reset things*/
                        signal(SIGALRM, sigfn);

                        line[++rcount] = '\x00';
                        fprintf(stderr, "The number of characters read
-> %d\n\n", rcount);
                        fprintf(stderr, "Input %s data ==>> %s\n", name,
                ioctl(mfd, TCSETA, &tsaved);
                fprintf(stderr, "Invalid %s file descriptor - Error\n",



1. Q: serial port programming with ioctl

Hi netlanders,

I've got some really strange problems while programming the serial port
with ioctls.

I want to turn on DTR with a TIOCMSET-ioctl, but it always takes about
3 seconds to finish the system-call.

Turning off the DTR-Line is no problem at all.....
Fiddling around with the other port lines works also fine...

Hmmmmmhhhhhh.....any solutions to make this a little bit faster ?

The effect is independent of the actual used OS (same for SunOS & Solaris).

(I've appended a few lines of pseudo-code for documentation issues)
#include <termios.h>
#define DEVICE "/dev/ttya"
int state;
device = open(DEVICE, O_RDWR );
res = ioctl(device, TIOCMGET, &state);  /* no problem */

res = ioctl(device, TIOCMSET, &state);  /* needs about 3 seconds ??? */

/* res returns 0 =SUCCESS)

Comments appreciated.....

Thanks in advance,




Computer Science Department , IRB    
University of Dortmund,            voice : +49 231 755 2422  
44221 Dortmund, Germany               fax: +49 231 755 2386

2. Can Linux use 16 bit colors ??

3. advice on ioctl and serial ports; creating port monitor

4. My ppp server work fine but ...

5. Parallel Port programming question, was "Serial Port Programming"

6. Xvfb argument problem

7. Compiling a linux program, missing ioctl.h and serial.h

8. netscape 1.0 hangs the complete system

9. How to set up serial port when programming serial communication

10. Programming help with TTY IOCTL SERIAL

11. SunOS 5.6, Serial ports, ioctl(), and C vs. C++

12. ioctl(fd, TIOCGSERIAL, &serinfo) fails for USB serial ports?