I am trying to define a custom system call that traverses all the processes currently running. The function declaration would look something like this: ssize_t traverse_process(struct customStructure *list, size_t length);
I've found out that in order to define a new system call, we use the SYSCALL_DEFINEx macro (in my case 2).
However, I also read that the macro is actually equivalent to asmlinkage long sys_traverse_process(struct customStructure *list, size_t length);
.
However, as you can see, my traverse_process' function declaration returns a ssize_t. Is there any way to define a system call without using the fore-mentioned macro?
Any help would be well appreciated.! Thank you.
Returning long
is the only proper way for a system call in Linux.
There is no way for a system call to return a value, which size differs from the size of long
.
Do you expect ssize_t
to have the same size as long
on all platforms ? If yes (this is a correct expectation), then there is no reason to prefer ssize_t
over long
. If you are not sure that your return type will fit to long
on every platform, then you simply cannot use this return type.
For example, from the C standard you knows, that read function returns ssize_t
. But read
system call has long
as return type (it is defined using DEFINE_SYSCALL
macro):
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
struct fd f = fdget(fd);
ssize_t ret = -EBADF;
if (f.file) {
loff_t pos = file_pos_read(f.file);
ret = vfs_read(f.file, buf, count, &pos);
file_pos_write(f.file, pos);
fdput(f);
}
return ret;
}
Note, that despite on long
being return type of the system call, the above implementation returns a value of type ssize_t
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.