저는 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*/);
// ...
}