Интерфейс командной строки общается с процессом через общую память - PullRequest
0 голосов
/ 16 июня 2020

Это своего рода развитие моего последнего вопроса, потому что я думаю, что все еще не понимаю его.

Обычно я разрабатываю приложение под Linux в C, которое служит командой line интерфейс, в основном его основная функция - это возможность анализировать команды, которые изменят некоторую конфигурацию в другом процессе. В этом случае мне нужно общаться через общую память, потому что я имею дело с приложением в реальном времени.

Вот мой упрощенный код:

#define LENGTH 2048

enum InterfaceMode
{
   MAIN,
   TALK
}

struct ProgramSHM
{
    int id;
    int attached;
    int flag;
    char value[LENGTH ];
}

struct Program
{
    int id;
    char* name;
    struct ProgramSHM shm;
}

struct Interface
{
    stuct program* programs;
    struct program* current;

    enum InterfaceMode mode;    
}

struct ProgramSHM* InitProgramSHM(int number)
{
    key_t key;
    int shmId;
    struct ProgramSHM* shm;

    if((key = ftok(".", number)) == (key_t)(-1))
    {
        perror("ftok");
        return NULL;
    }

    if(shmId = shmget(key, sizeof(struct ProgramSHM) + sizeof(char) * LENGTH , IPC_CREAT | 0666 ) == -1)
    {
        perror("shmget");
        return NULL;
    }

    if((shm = (struct ProgramSHM*)shmat(shmId, NULL, 0)) == (struct ProgramSHM*)(-1))
    {
        perror("shmget");
        return NULL;
    }

    shm->id = shmid;
    return shm;
}


int Talk(struct Interface* interface, struct Program* program
{
    interface->mode = TALK;
    interface->current = program;
    interface->current->shm = InitProgramSHM(interface->current->id)
    return 0;   
}

int ExitTalk(struct Interface* interface)
{
    interface->mode = MAIN;
    interface->current = NULL;
}

int ChangeValue(struct Interface* interface, char* value)
{
    if(!IsNullStr(value)) // just checking function I will not attach it to simplify example
    {
        if(strlen(value) > LENGTH)
        {   
            printf("Given string is too long.\n");
            return -1;
        }
        strncpy(interface->current->shm->value, value, LENGTH - 1);
        interface->current->shm->flag = 1;
        return 0;
    }
    printf("You need to specify string as an argument to 'changeValue'.\n");
    return -1;
}

В основном я разбираю команды, чтобы go могло выглядеть так:

'talk prog_1' - если существует struct Program prog_1, он вызывает Talk, поэтому я меняю режим на TALK и устанавливаю sh соединение с SHM

'changeValue someString' - вызывает функцию ChangeValue () с интерфейсом и "someString" в качестве значения

'exit' - отсоединение SHM, возврат в режим MAIN

И вот проблема вызов ChangeValue () изменяет все поля в моей структуре, более того. Если я изменю эту функцию, например, только на printf ("ChangeValue \ n") и НИЧЕГО не делаю, проблема все еще возникает! Но если я попытаюсь изменить только свои значения int, все будет нормально. Честно говоря, я понятия не имею, в чем причина проблемы и почему эти ценности зашкаливают. У тебя есть идеи? Если потребуется дополнительная информация, я обновлю свой пост, как только увижу его, потому что я застрял с этим кодом.

...