LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Building a serial terminal "emulator" does not work outgoing (https://www.linuxquestions.org/questions/programming-9/building-a-serial-terminal-emulator-does-not-work-outgoing-879972/)

smeezekitty 05-11-2011 12:31 AM

Building a serial terminal "emulator" does not work outgoing
 
I am designing a program called "Microcom", a VERY tiny terminal "emulator" (more like a serial console).
I am making it specifically to work with uClibc to use as a serial console for my floppy disk distro.
Problem is, it works fine receiving data but it does not send any data.
I am stumped at why it does not send data!
Code:

/*Microcom - Very tiny terminal emulator v0.1
  Just passes escape sequences through so the terminal type == Linux
*/
#include <sys/select.h>
#include <sys/time.h>
#include <stdio.h>
#include <termios.h>


int ready(int fd)
{
        fd_set fdset;
        struct timeval timeout;
        FD_ZERO(&fdset);
        FD_SET(fd, &fdset);
        timeout.tv_sec = 0;
        timeout.tv_usec = 50;
        return select(1, &fdset, NULL, NULL, &timeout) == 1 ? 1 : 0;
}

char dev[64];
static int baud = 0;
void usage(char *av)
{
        printf("Usage: %s [-b baud] <device>\n", av);
        printf
            ("-b baud rate to use for serial communications - uses current if not given\n");
        printf("When running, use CTRL+C or killall to terminate\n");
}

void process_arguments(int iargc, char **iargv)
{
        int uhoh = 1;
        int counter;
        for (counter = 0; counter < iargc; counter++) {
                if (iargv[counter] != NULL) {
                        if (iargv[counter][0] == '-'
                            && iargv[counter][1] == 'b') {
                                baud = atoi(iargv[counter + 1]);
                                if (baud < 1) {
                                        printf("Error: Invalid baud rate\n");
                                        exit(1);
                                }
                                iargv[counter] = iargv[counter + 1] = NULL;
                                switch (baud) {
                                case 0:
                                        break;
                                case 300:
                                        baud = B300;
                                        break;
                                case 600:
                                        baud = B600;
                                        break;
                                case 1200:
                                        baud = B1200;
                                        break;
                                case 2400:
                                        baud = B2400;
                                        break;
                                case 4800:
                                        baud = B4800;
                                        break;
                                case 9600:
                                        baud = B9600;
                                        break;
                                case 19200:
                                        baud = B19200;
                                        break;
                                case 38400:
                                        baud = B38400;
                                        break;
                                case 57600:
                                        baud = B57600;
                                        break;
                                case 115200:
                                        baud = B115200;
                                        break;
                                default:
                                        printf("Error: Invalid baud rate\n");
                                        exit(1);
                                }
                        }
                }
        }
        for (counter = 1; counter < iargc; counter++) {
                if (iargv[counter] != NULL) {
                        if (strlen(iargv[counter]) > 65) {
                                printf("Device name too long!\n");
                                exit(1);
                        }
                        strcpy(dev, iargv[counter]);
                        uhoh = 0;
                }
        }
        if (uhoh) {
                usage(iargv[0]);
                exit(1);
        }
}

int main(int argc, char **argv)
{
        process_arguments(argc, argv);
        char c;
        char buf[170];
        struct termios xyz;
        int stream = fileno(stdin);
        FILE *sd = fopen(dev, "rw");
        if (!sd) {
                printf("Cannot open device!\n");
                exit(1);
        }
        int sdd = fileno(sd);
        if (baud) {
                tcgetattr(sdd, &xyz);
                cfsetispeed(&xyz, baud);
                cfsetospeed(&xyz, baud);
                tcsetattr(sdd, TCSANOW, &xyz);
        }
        while (1) {
                if (ready(stream)) {
                        gets(buf); //<-- Buffer overflow possible here - Oh well :)
                        fprintf(sd, "%s", buf);
                        fflush(sd);
                }
                if (!feof(sd)) {
                        fread(&c, 1, 1, sd);
                        printf("%c", c);
                        fflush(stdout);
                        fflush(sd);
                }
        }
}

Well, thanks in advanced.
I hope someone understands the problem and please excuse the hacky code.

theNbomr 05-11-2011 08:54 AM

Code:

int main(int argc, char **argv)
{
        process_arguments(argc, argv);
        char c;
        char buf[170];
        struct termios xyz;
        int stream = fileno(stdin);
        FILE *sd = fopen(dev, "rw");

What is 'dev'? No declaration or assignment. It is (at least) much more conventional to use simple open()/read()/write()/close() for streams like serial ports.

--- rod.

EDIT: Oops. Missed the call to process_arguments(). Never mind the first comment.

smeezekitty 05-11-2011 06:43 PM

Quote:

Originally Posted by theNbomr (Post 4353266)
Code:

int main(int argc, char **argv)
{
        process_arguments(argc, argv);
        char c;
        char buf[170];
        struct termios xyz;
        int stream = fileno(stdin);
        FILE *sd = fopen(dev, "rw");

What is 'dev'? No declaration or assignment. It is (at least) much more conventional to use simple open()/read()/write()/close() for streams like serial ports.

--- rod.

EDIT: Oops. Missed the call to process_arguments(). Never mind the first comment.

Does open/read/write have an advantage?

smeezekitty 05-11-2011 08:08 PM

It never enters the:
Code:

if (ready(stream)) {

theNbomr 05-12-2011 11:09 AM

Quote:

Originally Posted by smeezekitty (Post 4353773)
Does open/read/write have an advantage?

They don't obfuscate the file descriptor, which is a required data type for the use of such APIs as termios. They don't try to format data, which is usually the requirement for input data on a device (but, since you are using fread(), this doesn't really matter). They don't return EOF on input mismatch, which allows you to more easily identify 'real' EOFs. They return a raw byte count of received data, which is often useful. There may be other reasons; these are the ones that seem important to me.

--- rod.


All times are GMT -5. The time now is 07:49 PM.