私はlibgpmを使ってコンソールアプリケーションからマウスイベントを読み込みます。シェルから直接実行すると正常に動作します。 mc(Midnight Commander)で実行すると、マウスイベントは受信されません。
問題は、mcが私のプロセスのために生成する疑似端末に関連しています。 gpmにGpm_Open(0 - auto?ではなく)の2番目の引数として渡された指定されたコンソール画面を使用させることで、この問題を部分的に解決できました。
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*/);
// ...
}