Reputation: 285
I am using Ubuntu 9.04 with kernel 2.8.32. I created a simple system call that counts the number of clone and execve calls. When the user/shell calls this system call, I would like it to pass back to the user these two values. As of now I am using:
#include <linux/sched.h>
#include <linux/asmlinkage>
/* These two variables are extern longs which are defined in sched.h and initialized in process_32.c */
total_execve;
total_clones;
long mycall* (int i){
int array[2];
array[0] = total_execve;
array[1] = total_clones;
return array;
}
I am not able to compile this as I get an undefined reference.
Regarding returning the array: Will my new call be able to access the array, won't the array be located in kernel memory?
Upvotes: 4
Views: 1162
Reputation: 131
You cannot return an array in this way. You need to declare static keyword to return a local array function. You could do something like this:
int *mycall (int i) {
static int array[2];
array[0] = total_execve;
array[1] = total_clones;
return array;
}
Upvotes: 0
Reputation: 14177
Answering your last question first: the array is indeed in "kernel" memory, but it's stack allocated which means it wilL "go away" when the mycall() function exits. Your function may appear to work, but may fail in cases where the memory gets re-used quickly.
To return multiple values, the common pattern is for the caller to pass in pointers to user-space memory, and have the kernel routine to fill them in. For example, you could pass in two pointers for your two values, or define a single struct that contains the values you need and gets filled in by the kernel routine.
Upvotes: 4
Reputation: 50941
Don't return pointers into the stack. Have the caller pass pointers into the function. Also, your function declaration syntax is incorrect. Here's what you want to do:
void mycall (int *execve, int *clones)
{
*execve = total_execve;
*clones = total_clones;
}
Upvotes: 5