2

I use libgpm in order to read mouse events in my console application. It works fine if started right from the shell. It doesn't receive any mouse events if started from mc (midnight commander).

Problem is related to pseudo terminal mc creates for my process. I can semi-solve this problem by forcing gpm to use specified console screen passed as second argument to Gpm_Open (instead of 0 - auto?).

int Gpm_Open(Gpm_Connect*,int);

Is there any way to know which virtual console screen should I use when running on pseudo tty (created by mc)? I've considered using active console but it may not be the one my application is running on. Probably traversing process tree and checking if its TTY is a real console would work but I don't know how to get tty(name) for given pid and I'm afraid I'd need elevated privileges for that.

Or hopefully is there any simpler workaround?

Edit: I've just noticed that starting my process from mc but via sudo (using command line) without forcing gpm to use patricular vc screen - simply works!

1 Answer 1

0

I managed to create a simple startup script which executes ps f in order to get process tree. It gives me nice output telling me everything I need:

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

Parsing it out from last line up leads me to process with a real TTY=tty1 (of course it is guilty mc). So finally I can execute my program with parsed mc's tty number as an argument.

Another option would be to retrieve tty number inside my program by parsing '/proc/PID/stat' files like ps program does which contain both tty dev id and parent process id. But using script makes me feel it is less OS dependent. Sample '/proc/PID/stat' below:

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

So at the end I've come up with this code:

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .