C write() doesn't send data until close(fd) is called

Kristina picture Kristina · Jul 12, 2010 · Viewed 14.8k times · Source

So I have this test code to send "HELLO" over a USB serial port:

int fd;
struct termios tty;

if((fd = open("/dev/ttyUSB0", O_WRONLY|O_NONBLOCK|O_NOCTTY)) == -1){
err(1, "Cannot open write on /dev/ttyUSB0");
}

tcgetattr(fd, &tty);
tty.c_iflag = 0;
tty.c_oflag = 0;
tty.c_lflag = 0;
tty.c_cflag = 0;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 0;
cfsetospeed(&tty, B19200);
cfsetispeed(&tty, B19200);
tty.c_cflag |= CREAD|CRTSCTS|HUPCL|CS8;
tcsetattr(fd, TCSANOW, &tty);

printf("Write: %i\n", write(fd, "HELLO", 5));

sleep(5);

if(close(fd) != 0){
warn("Could not close write fd");
}

The program executes fine and "HELLO" is sent but there is one problem. "HELLO" doesn't seem to be sent when the write() function is called, but rather when the file descriptor is closed. I added the sleep(5) line above to test out this theory and sure enough, "HELLO" is sent ~5 seconds after the program is executed. How can I get "HELLO" to be sent immediately after the write() command instead of on close()?

Answer

JeremyP picture JeremyP · Jul 12, 2010

The device is a tty device, so fsync isn't going to help, maybe not fflush either.

By default the device is working in canonical mode which means that data is packaged up into units of lines. You'll probably find that adding a cr/lf pair to your data will cause it to be sent.

You need to make sure canonical mode is off. Also, R's answer will be of use.

http://en.wikibooks.org/wiki/Serial_Programming/termios