Ammar
Ammar

Reputation: 1233

How to implement a system call that has structure parameter?

I want to implement a system call where I pass in a reference to a structure variable, then I would like display the values in the same file.

For example I have the following structure.

struct procInfo{
int processID[64]; // the PID of each process
};

Let's say the system call I want to implement is int getProcessIds(struct procInfo*) and I call it inside a file called pcid.c.

I want the system call to grab the process ids from the scheduler inside proc.c file so I can print them inside my pcid.c file.

I know how to create regular system calls that don't have input parameters. I also know how to print the process ids using this system call inside proc.c file, however I don't know how to print them inside pcid.c file. I don't understand how the strucutre pointer is returned so I can print it inside the pcid.c.

I followed a similar system call int fstat(int fd, struct stat*) but I don't see how the structure pointer is returned.

I hope my question is clear, I am using XV6 operating system, thanks!

Updated

I was able to get it to work, I didn't need to use malloc to allocate memory. Here is the strange thing though, I added another variable to my structure so here is what it became.

struct procInfo{
int processID[64]; // the PID of each process
char processname[64][16] // the name of each process
};

After the system call inside the proc.c file, here is how I am printing the values.

printf(1,"Name = %s\n" ,procInfo->processname[0]);
printf(1,"PID = %d\n" , procInfo->processID[0] );

But the strange thing is that I get the trap 14 err 4 on cpu 1 eip 0x510 addr 0x7417ba08--kill proc, however I tried printing only one value and it worked.

printf(1,"Name = %s\n" ,procInfo->processname[0]);
//printf(1,"PID = %d\n" , procInfo->processID[0] );

Or

//printf(1,"Name = %s\n" ,procInfo->processname[0]);
printf(1,"PID = %d\n" , procInfo->processID[0] );

Why did it work when I only print one of them ? Am I printing correctly?

Upvotes: 1

Views: 6128

Answers (1)

StenSoft
StenSoft

Reputation: 9609

The pointer is not returned but points to an allocated memory where the syscall will write. The memory needs to be allocated by the caller before the syscall is called.

If there is already such a struct allocated inside proc.c, you should copy it to the provided buffer with memcpy. You should never pass reference to kernel memory to user-space programs, apart from being huge security risk it may also change at any time without the program's knowledge or be in a memory region not accessible by the program.

A typical usage would be this:

A user-space part:

struct procInfo info;
getProcessIds(&info);

A kernel-space part:

int getProcessIds(struct procInfo *info)
{
    struct procInfo *localInfo = getProccessInfoFromScheduler();
    memcpy(info, localInfo, sizeof(struct procInfo));
    return 0;
}

Upvotes: 1

Related Questions