I'm trying to make new system calls on a redhat 2.4.18, and iv'e created a wrapper function for one of the system calls.
i will now add the system call code and the wrapper code add explanation below .
the system call:
int sys_read_TODO(pid_t pid, int TODO_index, char *TODO_description, ssize_t description_size, int* status){
struct task_struct *curTask = current;
struct task_struct *requestedTask = find_task_by_pid(pid);
// check if the requested process is valid
// check if he even exsits, and than whether he is this process, or one of his descendants.
if(!isValidProcess(curTask,requestedTask)){
return -ESRCH;
}
// the given process is ourself or one of our decendants.
// now check if the arguments are valid
if(TODO_description == NULL || status == NULL || TODO_index < 1 || TODO_index > requestedTask->todoQueueLength){
return -EINVAL;
}
// search for the requested todo and get his description
struct list_head *pos;
struct todoNode *curNode;
int counter = 0;
char *reqDesc = NULL;
int reqStatus = 0;
int reqDescLen = 0;
list_for_each(pos,&(requestedTask->todoQueue)){
counter +=1;
if(counter == TODO_index){
curNode = (todoNode*)list_entry(pos,todoNode,listNode);
reqDesc = curNode->description;
reqStatus = curNode->status;
reqDescLen = curNode->descLen;
}
}
// we got the description, now lets see if his size is bigger than the size they requested
if(description_size < reqDescLen){
return -EINVAL;
}
// try to update the status
int bytes_left = copy_to_user(status,&(reqStatus),sizeof(int));
// should we update the status using *status = reqStatus ?
if(bytes_left > 0){
return -EFAULT;
}
// now we will try to copy the description to user space
bytes_left = copy_to_user(TODO_description,reqDesc,reqDescLen);
if(bytes_left > 0){
return -EFAULT;
}
// successful. return the number of description bytes copied, which is len.
return reqDescLen;
}
The wrapper:
int read_TODO(pid_t pid, int TODO_index, char *TODO_description, ssize_t description_size, int* status){
int res;
__asm__
(
"pushl %%eax;"
"pushl %%ebx;"
"pushl %%ecx;"
"pushl %%edx;"
"movl $244, %%eax;"
"movl %1, %%ebx;"
"movl %2, %%ecx;"
"movl %3, %%edx;"
"movl %4, %%esi;"
"movl %5, %%edi;"
"int $0x80;"
"movl %%eax,%0;"
"popl %%edi;"
"popl %%esi;"
"popl %%edx;"
"popl %%ecx;"
"popl %%ebx;"
"popl %%eax;"
: "=m" (res)
: "m" (pid) ,"m" (TODO_index) ,"m"(TODO_description) ,"m" (description_size) ,"m"(status)
);
printf("read_TODO: res = %d\n",res);
if (res < 0)
{
printf("read_TODO: res = %d\n",res);
errno = res;
printf("read_TODO: errno = %d\n",errno);
printf("read_TODO: res = %d\n",res);
res = -1;
}
return res;
}
so the story is as follows:
I added each process a list of todo assignments and this system calls is supposed to read a given todo assignment's description.
The system call might return an error code. in this case, i was instructed to put the error code in the errno, and have the function return -1.
so in the wrapper i checked if the result value from the system call was negative, and if it was, i update the errno and return -1.
the problem is that i noticed by the prints that when i try to put the value of res into the value of errno, both errno and res get assigned with strange values.
From a run example i got these prints:
read_TODO: res = -3
read_TODO: res = -3
read_TODO: errno = 134513874
read_TODO: res = 134513874
What is the problem? and how can i fix it?