can't assign correctly into errno

107 views Asked by At

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?

0

There are 0 answers