Как реализовать системный вызов с параметром структуры?

Я хочу реализовать системный вызов, в котором я передаю ссылку на структурную переменную, а затем хочу отображать значения в том же файле.

Например, у меня есть следующая структура.

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

Допустим, я хочу реализовать системный вызов int getProcessIds(struct procInfo*), и я вызываю его внутри файла с именем pcid.c.

Я хочу, чтобы системный вызов получал идентификаторы процессов из планировщика внутри файла proc.c, чтобы я мог распечатать их в своем файле pcid.c.

Я знаю, как создавать обычные системные вызовы без входных параметров. Я также знаю, как распечатать идентификаторы процессов с помощью этого системного вызова внутри файла proc.c, однако я не знаю, как распечатать их внутри файла pcid.c. Я не понимаю, как возвращается указатель структуры, поэтому я могу распечатать его внутри файла pcid.c.

Я следовал аналогичному системному вызову int fstat(int fd, struct stat*), но не вижу, как возвращается указатель структуры.

Надеюсь, мой вопрос понятен, я использую операционную систему XV6, спасибо!

Обновлено

Я смог заставить его работать, мне не нужно было использовать malloc для выделения памяти. Вот что странно, я добавил еще одну переменную в свою структуру, и вот что она стала.

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

После системного вызова внутри файла proc.c я печатаю значения следующим образом.

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

Но странно то, что я получаю trap 14 err 4 on cpu 1 eip 0x510 addr 0x7417ba08--kill proc, однако я пытался напечатать только одно значение, и это сработало.

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] );

Почему это сработало, когда я напечатал только один из них? Я правильно печатаю?


person Ammar    schedule 11.02.2015    source источник


Ответы (1)


Указатель не возвращается, а указывает на выделенную память, куда системный вызов будет писать. Память должна быть выделена вызывающей стороной до вызова системного вызова.

Если внутри proc.c уже есть такая структура, вы должны скопировать ее в предоставленный буфер с помощью memcpy. Вы никогда не должны передавать ссылку на память ядра программам пользовательского пространства, помимо того, что это огромный риск для безопасности, она также может измениться в любое время без ведома программы или находиться в области памяти, недоступной для программы.

Типичное использование будет таким:

Часть пользовательского пространства:

struct procInfo info;
getProcessIds(&info);

Часть пространства ядра:

int getProcessIds(struct procInfo *info)
{
    struct procInfo *localInfo = getProccessInfoFromScheduler();
    memcpy(info, localInfo, sizeof(struct procInfo));
    return 0;
}
person StenSoft    schedule 11.02.2015
comment
поэтому, если я объявлю следующее struct procInfo *procInfo;, как мне выделить для него память, прежде чем я сделаю системный вызов? Прямо сейчас я делаю системный вызов, но не выделяю памяти для структуры. - person Ammar; 11.02.2015
comment
malloc(sizeof(struct procInfo)). Или вы можете просто выделить его в стеке (определить его без *), как это обычно используется для fstat. - person StenSoft; 11.02.2015
comment
Вы так говорите? struct procInfo *procInfo= malloc(sizeof(struct procInfo)); Не думаю, что это сработало! - person Ammar; 11.02.2015
comment
Когда я пытаюсь напечатать procInfo->processID[0] после системного вызова в proc.c, я получаю эту ошибку trap 14 err 4 on cpu 1 eip 0x7000631 addr 0x7000631--kill proc - person Ammar; 11.02.2015
comment
Ловушка означает, что ваш указатель инструкций был поврежден, вероятно, из-за переполнения/опустошения буфера. Я предполагаю, что системный вызов никогда не возвращается. - person StenSoft; 11.02.2015
comment
Странно, у меня внутри user.h было int getProcessIds(struct procInfo *);, потом поменял на int getProcessIds(struct procInfo*); потом ошибка исчезла. Ему не нравился пробел перед *. Во всяком случае, сейчас я не возвращаю ожидаемые значения. Я возвращаю некоторый идентификатор процесса, но это неправильно. - person Ammar; 11.02.2015
comment
Вы уверены насчет malloc, потому что сейчас я думаю, что struct procInfo *procInfo; в pcid.c указывает на другое место в памяти, чем struct procInfo *procInfo; в файле proc.c. У меня там реализован системный вызов, поэтому я могу прочитать, что находится в таблице планировщика. - person Ammar; 11.02.2015
comment
не могли бы вы показать мне, как использовать memcpy для такой реализации? - person Ammar; 11.02.2015