데몬은 RO 모드에서만 파일을 엽니다.

데몬은 RO 모드에서만 파일을 엽니다.

키로거를 직접 작성하려고 합니다. 키로거 개발에 대한 내 논리가 좋은지 모르겠지만 다음과 같은 방식으로 수행하려고 생각했습니다.
키 입력 이벤트를 얻으려면 먼저 데몬 프로세스를 생성하고 /dev/input/by-path/platform-i8042-serio-0-event-kbd에 액세스하여 얻은 데이터를 파일에 씁니다.
코드는 계속 실행되지만 여기서 문제는 쓰려는 파일이 RO 모드에서 열려 있고 데몬이 백그라운드에서 실행 중이지만 쓸 수 없다는 것입니다.

#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>

#define RUNNING_DIR "/tmp"
#define LOCK_FILE "exampled.lock"
#define LOG_FILE "exampled.log"
//#define TEST_FILE "testd.txt"

static const char *const evval[3] = {
    "RELEASED",
    "PRESSED ",
    "REPEATED"
};

void log_message(char* filename, char* message)
{
    FILE *logfile;
    logfile = fopen(filename, "a");
    if(!logfile) return;
    fprintf(logfile, "%s\n", message);
    fclose(logfile);
}


void signal_handler(sig)
int sig;
{
    switch(sig)
    {
        case SIGHUP:// not relevant
            log_message(LOG_FILE, "hangup signal catched");
            break;
        case SIGTERM:// not relevant
            log_message(LOG_FILE, "terminate signal catched");
            exit(0);
            break;
        case SIGTTIN: // not relevant
            log_message(LOG_FILE, "from sigttin");
            break;
        case SIGTTOU:// only this is relevant here
            poll_kbd();
            break;
    }
}

int poll_kbd()
{
    const char *dev = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";

    struct input_event ev;
    int n;
    int fd;
    FILE* f;
    f = fopen(LOG_FILE, "w");
    fd = open(dev, O_RDWR); 
    if (fd == -1) {
        fprintf(stderr, "Cannot open %s: %s.\n", dev, strerror(errno));
        return EXIT_FAILURE;
    }

    while (1) {
        n = read(fd, &ev, sizeof ev);
        if (n == (ssize_t)-1) {
            if (errno == EINTR)
                continue;
            else
                break;
        } else
        if (n != sizeof ev) {
            errno = EIO;
            break;
        }

        if (ev.type == EV_KEY && ev.value >= 0 && ev.value <= 2){
            fprintf(f, "%s 0x%04x (%d)\n", evval[ev.value], (int)ev.code, (int)ev.code);
        }
    }

}

void daemonize()
{
    int i, lfp;
    char str[10];

        if(getppid()==1) return;  // already a daemon, pid1 for init

        i = fork();
        if(i<0) exit(1); // fork error
        if(i>0) exit(0); // parent exits

        // child daemon continues
        setsid(); // obtain a new process group
        for (i=getdtablesize();i>=0;--i) close(i); // close all descriptors

        i =  open("/dev/null", O_RDWR); dup(i); dup(i); // handle standard IO
        umask(027); // set newly created file permissions
        chdir(RUNNING_DIR); // change running dir
        if (lfp<0) exit(1); // cannot open
        if (lockf(lfp, F_TLOCK, 0) < 0) exit(0); // cannot lock

        // first instance continues
        sprintf(str, "%d\n", getpid());
        write(lfp, str, strlen(str)); // record pid to lockfile
        signal(SIGCHLD, SIG_IGN); // ignore child
        signal(SIGTSTP, SIG_IGN); // ignore tty signals

        signal(SIGHUP, signal_handler); // catch hangup signal
        signal(SIGTERM, signal_handler); // catch kill signal
        signal(SIGTTIN, signal_handler);
        signal(SIGTTOU, signal_handler);
}

main()
{
    daemonize();
    while(1)
    {
        //the signal is raised to envoke the keyboard input detection function
        raise(SIGTTOU);
        sleep(1);
    }
}

누구든지 이 문제를 해결하도록 도와줄 수 있습니까? 무엇이 잘못되었는지. 어떤 제안이라도 높이 평가하겠습니다. 감사해요.

답변1

당신은 처음부터 너무 컸어요. 작업이 더 잘 작동하도록 보장하는 작은 코드 조각으로 시작하세요. 왜 데몬에서 즉시 시작되고 왜 이상한 신호로 호출되는지 poll_kbdC 언어에서는 오류 코드도 확인해야 합니다.

포효는 끝났다.

이제 작동하지 않는 이유는 다음과 같습니다. >>f = fopen(LOG_FILE, "w"); 자르기각 통화에 대한 로그 파일입니다 kbd_poll.

이를 로 변경 "a"하고 스크립트를 실행했는지 확인하세요 . 그러면 읽기 액세스 권한이 있습니다. root함수가 로 리디렉션된 "/dev/input/by-path/platform-i8042-serio-0-event-kbd"후에도 오류가 표시되지 않습니다 . 그러면 (나에게는) 효과가 있을 것입니다.deamonize()stderr/dev/null

관련 정보