我正在尝试在redhat 2.4.18上进行新的系统调用,并且我为其中一个系统调用创建了一个包装函数。
我现在将添加系统调用代码和包装代码添加说明如下
系统调用:
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;
}
包装器:
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;
}
所以故事如下:
我为每个进程添加了一个todo赋值列表,这个系统调用应该读取给定的todo赋值的描述。
系统调用可能会返回错误代码。在这种情况下,我被指示将错误代码放在errno中,并使函数返回-1
所以在包装器中我检查了系统调用的结果值是否为负数,如果是,则更新errno并返回-1。
问题是我在打印时注意到,当我尝试将res的值放入errno的值时,errno和res都会被分配奇怪的值。
从运行示例中我得到了这些照片:
read_TODO: res = -3
read_TODO: res = -3
read_TODO: errno = 134513874
read_TODO: res = 134513874
有什么问题?我该如何解决?