How To get the "file structure/ fd" in open of character device in Mac driver

With the parameter which I get in ".open/.close" unable to distinguish from which file descriptor the method is being called, can you please let me know the procedure to retrieve the the info so that It can be uniquely identified.


Is there any other alternatives to character device, so that I can establish the connection between user-space and kernel space


typedef int (dev_t, int, int, struct proc *) open_close_fcn_t;

struct cdevsw {

open_close_fcn_t *d_open;

open_close_fcn_t *d_close;

read_write_fcn_t *d_read;

read_write_fcn_t *d_write;

....

}


I have tried to fetch the filedesc structure from "struct proc / proc_self()" so that I can get the info of all open file descriptors corresponding to process

struct filedesc *fdp = p->p_fd;

but able to see "*fpd" as NULL


Thanks

Venkat

Accepted Reply

So can we conclude that, there is no way to distinguish the uniqueness of the file descripter in driver …

Yes. I thought my initial response was pretty clear on that subject:

The file descriptor table is not part of the macOS KPI … so your current approach is definitely a dead end.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Is there any other alternatives to character device, so that I can establish the connection between user-space and kernel space

Can you elaborate more on your high-level goals here? The file descriptor table is not part of the macOS KPI (which is why

p_fd
is
NULL
), so your current approach is definitely a dead end. I may be able to suggest an alternative, but for that I need to know more context.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I'm writing a custom usb/network kernel extention, and in order to have the user level interaction to the kernel space I created a character device


for usb/network kext -> using IOUSBHostInterface, IOEthernetController



Thanks

Venkat

My requirement is simple,

with the above approach I cannot distinguish "fd" context,


I need to handle multiple file handlers at the sametime, so I'm looking for some uniqueness (similar to 'struct file (in linux)'), so that I can differentiate the file handler corresponding to the system call(read/write/ioctl) which has been called

If possible can you share the docs/links regarding usage of character devices and for async support


-venkat

can you please tell me an alternative to character device!!!

I'm writing a custom usb/network kernel extention, and in order to have the user level interaction to the kernel space I created a character device

That’s an odd approach. On macOS the kernel is divided into subsystems (Mach, BSD, I/O Kit) and things go more smoothly if you restrict your KEXT to operating within one of those subsystems (“don’t cross the streams” :-). Given that you’re already working within the I/O Kit subsystem, it makes the most sense to publish user-space functionality via an I/O Kit user client rather than via a BSD construct.

And it’s no coincidence that I/O Kit user clients have specific support for identifying the calling process (via the

owningTask
parameter passed to
newUserClient()
).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks eskimo for the valuable info, I'll try to use "IOUserClient (IOKituser client/ IOKitLib)"


but I need a way to create the character device in BSD,(or any other alternative) using "struct cdevsw { open_close_f " , and when the user perform open/reads/write/ioctl operation, then in the kernal space I need a way to differentiate the fd


ex:

consider there are char devices/ any other devices

/dev/apple0; /dev/apple1


in the userspace when the app invokes the sys call open multiple times


user kernal

fd_3 = open("/dev/apple0") => int kext_open(dev_t dev, int flags, int type, struct proc *p)

fd_4 = open("/dev/apple0") => int kext_open(dev_t dev, int flags, int type, struct proc *p)


write(fd_4, buf, len); => int kext_write(dev_t dev, uio_t uio, int ioflags);

read(fd_3, buf, len); => int kext_read(dev_t dev, uio_t uio, int ioflags);

here cannot distinguish from which file descriptor the syscall(read/write) is being called,

since the major:minor numner is same,(dev_t)

struct proc is also same, as both are in same process [proc_self()]


need a way the differentiate based on file descriptor (fd)


Thanks

Venkat

but I need a way to create the character device in BSD

Why? What client software is going to be opening that character device?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I want to create a custom user application to operate, and perform open/read/write operations


Thanks

venkat

I want to create a custom user application to operate, and perform open/read/write operations

Why not do those operations via the user client? Is your app doing something that specifically requires file descriptors (like putting the descriptor in a

select
set)?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Yes, my app mainly depends on file descriptors,

Is it possible to get file structure(any unique identifier) to distinguish in driver?, if possible please let me know


I want to put the user application as simple as possible without any "new user client", user application is unaware of driver operations so I cannot use "user client [if I don't have any alternative then I can use that]"

currently I'm able to implement select() functionality as well


Thanks

Venkat

Is it possible to get file structure(any unique identifier) to distinguish in driver?

No. To quote my earlier post:

The file descriptor table is not part of the macOS KPI (which is why

p_fd
is
NULL
), so your current approach is definitely a dead end.

You wrote:

I want to put the user application as simple as possible without any "new user client"

Presumably you’re porting this program from some platform that does represent file descriptors within the kernel, in which case you’ve hit a significant architectural difference. I don’t think there’s going to be any way to be 100% compatible with your existing user space code, but that doesn’t mean you need to rewrite it completely. You could continue to use a character device but tweak the user space opening code to allow you to distinguish between file descriptors (for example, by using a different minor device number).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

You wrote:

by using a different minor device number,

I can use the above approach to distinguish the char devices (viz, /dev/apple0, /dev/apple1),

case 1:

but cannot handle the situation if user app opens the device twice ( /dev/apple0) - this is my major concern

case2:

I can distinguish using the proc (pid (or) thread id), if it called from different process/threads


So can we conclude that, there is no way to distinguish the uniqueness of the file descripter in driver [but I think there should be a mapping between file handlers and its context]

or shell I raise a request in https://developer.apple.com/support/technical/


Thanks

Venkat

So can we conclude that, there is no way to distinguish the uniqueness of the file descripter in driver …

Yes. I thought my initial response was pretty clear on that subject:

The file descriptor table is not part of the macOS KPI … so your current approach is definitely a dead end.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Yes your thought initial response was pretty clear on that subject, but was trying a way(other than 'fpd') to map uniqueness to identify 'fd'.

as suggested by you earlier I'm using "IOUserClient", and I don't want to create any mess by merging BSD and IOKit subsystems


Thanks a lot for the info