Возможна передача структуры через системный вызов.
Хотя невозможно передать саму структуру в качестве параметра системного вызова, передача указателя на него возможна и позволит использовать ее как входной или выходной параметр.
Разрешение использовать в качестве аргумента сами данные, а не указатель на них, повредит требованию механизма системных вызовов, поскольку передача данных должна быть реализована универсальным способом, позволяющим всем типам данных (а также будущим структурам) использоваться.
Давайте посмотрим на существующую реализацию системного вызова fstat.
int fstat(int fd, struct stat *st);
fstat требует номер дескриптора файла в качестве ввода и выводит соответствующую статистическую информацию, используя struct stat.
struct stat {
short type; // Type of file
int dev; // File system's disk device
uint ino; // Inode number
short nlink; // Number of links to file
uint size; // Size of file in bytes
};
Хотя fstat использует указатель структуры в качестве выходного параметра, его использование в качестве входных данных будет аналогичным.
Функция sys_fstat в коде ядра запускает реализацию системного вызова fstat (соглашение XV6 заключается в обработке выборки параметров из пространства пользователя с помощью функций sys_ *).
int sys_fstat(void)
{
struct file *f;
struct stat *st;
if(argfd(0, 0, &f) < 0 || argptr(1, (void*)&st, sizeof(*st)) < 0)
return -1;
return filestat(f, st);
}
Эта функция сначала получает соответствующий структурный файл с номером дескриптора файла, полученным первым аргументом функции fstat (используя argfd). Затем извлекает указатель struct stat, полученный вторым аргументом функции fstat, используя argptr, и сохраняет указанный указатель в локальной переменной указателя (область действия функции).
В этот момент все аргументы были получены и могут использоваться реализацией ядра.
Примечание: Хотя указатель struct stat является указателем пользовательского пространства (расположен в нижней половине виртуального пространства), ядро может использовать его здесь, потому что когда ядро обслуживает системный вызов процесса, он использует собственную таблицу подкачки процесса.