mc(Midnight Commander)에서 시작하는 응용 프로그램에서 gpm을 마우스 입력으로 사용

mc(Midnight Commander)에서 시작하는 응용 프로그램에서 gpm을 마우스 입력으로 사용

저는 libgpm을 사용하여 콘솔 애플리케이션에서 마우스 이벤트를 읽습니다. 쉘에서 직접 실행하면 제대로 작동합니다. mc(Midnight Commander)에서 실행하면 마우스 이벤트가 수신되지 않습니다.

문제는 mc가 내 프로세스를 위해 생성하는 의사 터미널과 관련이 있습니다. gpm이 Gpm_Open(0 - auto? 대신)의 두 번째 인수로 전달된 지정된 콘솔 화면을 사용하도록 하여 이 문제를 부분적으로 해결할 수 있었습니다.

int Gpm_Open(Gpm_Connect*,int);

의사 tty(mc에서 생성)에서 실행할 때 어떤 가상 콘솔 화면을 사용해야 하는지 알 수 있는 방법이 있나요? 활성 콘솔 사용을 고려했지만 내 애플리케이션이 실행되는 콘솔이 아닐 수도 있습니다. 아마도 프로세스 트리를 살펴보고 해당 TTY가 실제 콘솔인지 확인하면 작동할 것입니다. 하지만 주어진 PID에 대해 tty(이름)를 얻는 방법을 모르고 높은 권한이 필요할까봐 걱정됩니다.

아니면 더 쉬운 해결책이 있었으면 좋겠나요?

편집: gpm이 특정 vc 화면을 사용하도록 강요하지 않고 mc에서 sudo(명령줄 사용)를 통해 프로세스를 시작한다는 사실을 방금 확인했습니다. 간단하게 작동합니다!

답변1

ps f프로세스 트리를 얻기 위해 실행되는 간단한 시작 스크립트를 만들었습니다 . 그것은 나에게 좋은 결과를 제공하고 나에게 필요한 모든 것을 알려줍니다.

PID TTY      STAT   TIME COMMAND
281 tty1     Ss     0:00 -bash
383 tty1     S+     0:00  \_ mc
385 pts/0    Ss     0:00      \_ bash -rcfile .bashrc
408 pts/0    R+     0:00          \_ ps f

마지막 줄을 구문 분석하면 처리를 위해 실제 TTY=tty1을 사용하게 되었습니다(물론 죄악입니다 mc). 따라서 마침내 구문 분석된 mc의 tty 번호를 매개변수로 사용하여 프로그램을 실행할 수 있습니다.

ps또 다른 옵션은 마치 프로그램에 tty 개발자 ID와 상위 프로세스 ID가 포함되어 있는 것처럼 "/proc/PID/stat" 파일을 구문 분석하여 프로그램 내에서 tty 번호를 검색하는 것입니다 . 그러나 스크립트를 사용하면 OS에 덜 의존적인 느낌이 듭니다. 아래의 예 "/proc/PID/stat":

383 (mc) R 281 383 281 1025 383 ...
            |            |_ TTY:  test major bits for type and minor for id
            |______________ PPID: use to traverse tree 

그래서 마침내 나는 다음과 같은 코드를 생각해 냈습니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gpm.h>

static int find_tty()
{
    char buf[256];
    char* ptr;
    FILE* f;
    int r;
    char stat;
    int ppid,pgrp,sess,tty;

    int pid = getpid();

    while (pid>0)
    {
        sprintf(buf,"/proc/%d/stat",pid);
        f = fopen(buf,"r");
        if (!f)
            return 0;
        r = fread(buf,1,255,f);
        fclose(f);
        if (r<=0)
            return 0;
        buf[r] = 0;
        ptr = strchr(buf,')');
        if (!ptr || !ptr[1])
            return 0;
        r = sscanf(ptr+2,"%c %d %d %d %d", &stat,&ppid,&pgrp,&sess,&tty);
        if (r!=5)
            return 0;
        if ( (tty&~63) == 1024 && (tty&63) )
            return tty&63;
        pid = ppid;
    }
    return 0;
}

int main(int argc, char* argv[])
{
    Gpm_Connect gpm_connect;
    // ...

    int gpm = Gpm_Open(&gpm_connect,find_tty()/*0*/);
    // ...
}

관련 정보