Braedon
Braedon

Reputation: 71

Python's ioctl function returns FileNotFoundError: [Errno 2] No such file or directory while the C function with the same args succeeds

I am creating a driver for an existing python library with a device that communicates via ioctl. The vendor of the device provided some sample C code that I have been using for reference but I am stuck on the most basic client connect call for the device. When I make the ioctl call it returns the error FileNotFoundError: [Errno 2] No such file or directory even though the file does exist and I have permission to access it since I have the permissions in the C code which runs fine.

Changing other parts of the function like setting the file descriptor to a fd that doesn't exist or 1/2 yields other errors so I know its seeing the file descriptor fine just not finding the file. I also tried using os.fdopen to pass fcntl.ioctl a io.File object instead and got the same results.

I took the request int from the C code as well as the sizeof the return struct just by printing them out to the screen so the arguments for the C ioctl call and Python ioctl call should be identical.

//c code
int pse_client_connect(void) {
    int fd, ret;
    struct ishtp_cc_data cc_data;

    // Prep input connection data
    memcpy(&(cc_data.in_client_uuid), &pse_smhi_guid, sizeof(pse_smhi_guid));

    // Open the pse character device for operations
    fd = open(PSE_CHRDEV, O_RDWR);
    printf("File Descriptor: %i\n", fd);
    printf("Size of Struct: %li\n",sizeof(cc_data));
    printf("Request Int: %li\n", IOCTL_ISHTP_CONNECT_CLIENT);
    if (fd <= 0) {
        printf("Failed to open the pse device file\nAre you running as root?\n");
        return fd;
    }

    // Send the connection IOCTL
    ret = ioctl(fd, IOCTL_ISHTP_CONNECT_CLIENT, &cc_data);
    if (ret) {
        printf("Failed to connect to the PSE over ISHTP/HECI\n");
        return ret;
    }

    return fd;
}
//output
File Descriptor: 3
Size of Struct: 16
Request Int: 3222292481
#Python Code
import fcntl, array, os

def pse_client_connect():
    device_file=os.open("/dev/pse", os.O_RDWR)
    print(device_file)
    if (device_file <= 0):
        print("Failed to open the pse device file\nAre you running as root?\n")
    buf = array.array('B', [0]*16)
    ret = fcntl.ioctl(device_file,3222292481,buf,True )
    print(buf)
    os.close(device_file)

if __name__ == "__main__":
    pse_client_connect()
# Output
(base) root@host:/# python main.py
3
Traceback (most recent call last):
  File "/home/tech/Downloads/pse_heci/py_example/main.py", line 14, in <module>
    pse_client_connect()
  File "/home/tech/Downloads/pse_heci/py_example/main.py", line 9, in pse_client_connect
    ret = fcntl.ioctl(device_file,3222292481,buf,True )
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory

I have checked that the file descriptors are actually being opened and are alive.

(base) root@host:/# sudo lsof | grep "/dev/pse"
python    311743                              root    3u      CHR              239,0       0t0        413 /dev/pse
(base) root@host:/# sudo lsof | grep "/dev/pse"
dio       320841                              root    3u      CHR              239,0       0t0        413 /dev/pse

I am expecting that the ioctl would fill my buf object with bytes that I could then unpack into the struct that I'm expecting.

I'm not sure if I'm missing something in the way that pythons ioctl handles file descriptors or maybe launches in a different process? but I'm at an impasse since I can't get my debugger to step into the function.

Upvotes: 0

Views: 77

Answers (0)

Related Questions