Как отправлять сообщения в личку на сервер Minix - PullRequest
2 голосов
/ 19 апреля 2019

Итак, я пытаюсь создать новый системный вызов на сервере PM.У меня вопрос, как я могу отправить какое-то сообщение для функции.

на сервере IPC все, что мне нужно было сделать, это добавить мой системный вызов в список, потому что все функции были определены как (* func) (сообщение *)

(...)/servers/ipc/main.c
static struct {
    int type;
    int (*func)(message *);
    int reply;  /* whether the reply action is passed through */
} ipc_calls[] = {
    (...)
    { IPC_MYNEWSIGNAL,  do_something,   1 },
};

но в PM в table.c функции определены как

(...)/servers/pm/table.c
int (* const call_vec[NR_PM_CALLS])(void) = {
(...)
CALL(PM_GETSYSINFO) = do_getsysinfo
}

и если я пытаюсь передать функцию с подписью

int do_something(message *m)

Я получу ошибку:

Incompatible pointer types: initializing int (*const)(void) with int (message *)

Как правильно создать сигнал на сервере PM, если мне нужно получить какую-то информацию?

1 Ответ

1 голос
/ 20 апреля 2019

Насколько я понял из вопроса, вы хотите получать аргументы внутри обработчика syscall.Давайте возьмем в качестве примера библиотечную функцию clock_settime из libc.

int clock_settime(clockid_t clock_id, const struct timespec *ts)
{
  message m;

  memset(&m, 0, sizeof(m));
  m.m_lc_pm_time.clk_id = clock_id;
  m.m_lc_pm_time.now = 1; /* set time immediately. don't use adjtime() method. */
  m.m_lc_pm_time.sec = ts->tv_sec;
  m.m_lc_pm_time.nsec = ts->tv_nsec;

  if (_syscall(PM_PROC_NR, PM_CLOCK_SETTIME, &m) < 0)
    return -1;

  return 0;
}

Как вы можете видеть, она записывает аргументы внутри структуры сообщения и передает ее _syscall.Хорошо, теперь посмотрим на обработчик системного вызова для PM_CLOCK_SETTIME, который смонтирован в table.c.

int do_gettime()
{
  clock_t ticks, realtime, clock;
  time_t boottime;
  int s;

  if ( (s=getuptime(&ticks, &realtime, &boottime)) != OK)
    panic("do_time couldn't get uptime: %d", s);

  switch (m_in.m_lc_pm_time.clk_id) {
    case CLOCK_REALTIME:
        clock = realtime;
        break;
    case CLOCK_MONOTONIC:
        clock = ticks;
        break;
    default:
        return EINVAL; /* invalid/unsupported clock_id */
  }

  mp->mp_reply.m_pm_lc_time.sec = boottime + (clock / system_hz);
  mp->mp_reply.m_pm_lc_time.nsec =
    (uint32_t) ((clock % system_hz) * 1000000000ULL / system_hz);

  return(OK);
}

Становится ясно, что аргумент является глобальной переменной с именем m_in.Немного больше поиска показывает, что это происходит из glo.h

/* The parameters of the call are kept here. */
EXTERN message m_in;        /* the incoming message itself is kept here. */

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

Взгляните на точку 7 Передача параметра системному вызову здесь .Чтобы понять, как правильно скомпилировать ядро, обратитесь к этому посту.

...