Per your comment, these char *
values point to nul-terminated strings.
Now, you can't just go copying that whole fileDataMap
memory block to userspace - that'll just give userspace a bunch of char *
values that point into kernel space, so it won't actually be able to use them. You need to copy the strings themselves to userspace, not just the pointers (this is a "deep copy").
Now, there's a few ways you can go about this. The easiest it to simply pack all the strings, one after another, into a big char
array in userspace. It's then up to userspace to scan through the block, reconstructing the pointers:
asmlinkage int sys_get_my_data(char __user *data, size_t bufferSize)
{
size_t i;
for (i = 0; i < MAX_BUF_SIZE; i++) {
size_t s0_len = strlen(fileDataMap[i][0]) + 1;
size_t s1_len = strlen(fileDataMap[i][1]) + 1;
if (s0_len + s1_len > bufferSize) {
return -ENOSPC;
}
if (copy_to_user(data, fileDataMap[i][0], s0_len)) {
return -EINVAL;
}
data += s0_len;
bufferSize -= s0_len;
if (copy_to_user(data, fileDataMap[i][1], s1_len)) {
return -EINVAL;
}
data += s1_len;
bufferSize -= s1_len;
}
return 0;
}
This will only work if there are always MAX_BUF_SIZE
string-pairs, because userspace will need to know how many strings it is expecting to recieve in order to be able to safely scan through them. If that's not the case, you'll have to return that information somehow - perhaps the return value of the syscall could be the number of string-pairs?
If you want the kernel to reconstruct the pointer table in userspace, you'll have to copy the strings as above, and then fill out the pointer table - userspace will have to pass two buffers, one for the strings themselves and one for the pointers.