3

I've been working for quite while on little project of mine with some XBee's. Until now all the code has been tested and working on a UBUNTU-SERVER 10.04 LTS, making use of the libftdi libraries for serial-usb simulation/conversion.

At the beginning of this week, I've tried to use the exact same code on a laptop with kubuntu 12.04 make using of the same library versions of libftdi.

The thing is that, in my Satellite L755 - 18K laptop, every time I now try to open my XBee device at /dev/ttyUSB0, it gives me "Bad file descriptor". From the log messages from dmesg, the device registers quite normally and can't seem to put my finger one it.

Here it is the part of code used to open the device:

cfmakeraw(&tio);
cfsetospeed(&tio,B9600);            // 9600 baud
cfsetispeed(&tio,B9600);            // 9600 baud
tio.c_cc[VMIN]=0;
tio.c_cc[VTIME]=10;

serial_fd=open("/dev/ttyUSB0", O_RDWR);

tcsetattr(serial_fd,TCSANOW,&tio);


if (serial_fd < 0){

    cout << "Error while opening device... " << "errno = " << errno << endl;

    printf("Something went wrong with open()! %s\n", strerror(errno));
    exit(1);
}

Any thoughts on the subject would be greatly appreciated.

Regards

cvicente
  • 132
  • 3
  • 12
  • Nope! Running it as my normal user. – cvicente Jul 10 '12 at 22:13
  • Well try running it as root since you request RDWR on /dev/* :) I need to run sermon as root on my system when I want to get RDRW access to /dev/ttyUSBx – Jite Jul 10 '12 at 22:15

2 Answers2

5

The problem is that you're calling open() and tcsetattr() in sequence, then only check afterwards for an error condition with the file.

Consider open() fails for some reason. It will return -1 and set errno to that reason. However, the code in your question proceeds into calling tcsetattr() nonetheless, which will fail since serial_fd will be -1 in our case, and will overwrite errno with the reason why (EBADF, -1 is not a valid file descriptor).

You should instead check for an error condition immediately after opening the file:

serial_fd = open("/dev/ttyUSB0", O_RDWR);
if (serial_fd < 0) {
    cout << "Error while opening device... " << "errno = " << errno << endl;
    perror("Something went wrong with open()");
    exit(1);
}

And only then, issue:

tcsetattr(serial_fd, TCSANOW, &tio);
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • That is an issue, but not "the" issue if I understood the author correctly. I understood the question as "why do I get Bad filedescriptor when trying to open /dev/ttyUSB0", or did I misinterpret something? :) – Jite Jul 10 '12 at 22:14
  • @Jite, you understood correctly indeed, and the answer is *questioner is getting `EBADF` because he's calling `tcsetattr()` before checking that `serial_fd` is valid.* Accessing `errno` immediately after the call to `open()` will allow him to see the actual reason why it fails. – Frédéric Hamidi Jul 10 '12 at 22:19
  • You are right of course. (My guess is that it will give something like: Permission denied) – Jite Jul 10 '12 at 22:23
  • @Jite, yup. Or, worse, `No such device`. – Frédéric Hamidi Jul 10 '12 at 22:29
  • @Jite Yes! that's right, in fact I was wondering why the "Bad file descriptor error". Nevertheless, I think Frédéric presented a good point. I've changed the code as suggested, and the errno was actually overwritten. What is actually happening, is that, after all, I don't have permission to open the device! :-\ – cvicente Jul 10 '12 at 22:31
  • @FrédéricHamidi Touché Frédéric! Exactly that!... looking at the device access permissions, it makes perfect sense that I don't have access to it, but on the other hand it worked perfectly well on my ubuntu-server. – cvicente Jul 10 '12 at 22:33
  • I'll add what I've written in comments as an answer so that others might see it more likely if they get the same problem. +1 to Frédéric for noting the common mistake often causing confusion :). – Jite Jul 10 '12 at 22:38
3

Look at Frédéric's answer and then make sure you have permission to open the device. I need to be root to access (perhaps only to get write permission to) /dev/ttyUSB0 on my system. I think it's distro-dependent because on Debian I was able to open it as a regular user but I need to be root on my Arch distro. Might be possible to fix by looking at groups and permissions for /dev/ttyUSBx.

EDIT: Actually I'm able to get a file descriptor with a simple test program, so it might be a sermon-specific problem in my case.

Simple solution might be to run the program as root.

Jite
  • 4,250
  • 1
  • 17
  • 18
  • 1
    Check your hotplug scripts, they will control the access mode (permission, basically) given to the device node. – Ben Voigt Jul 10 '12 at 22:51