c中使用子进程实现logger功能?

问题描述 投票:0回答:1

我在使用以下代码时遇到问题。因此,在 logger.c 文件中,我创建了一个记录器子进程,它将继续循环等待读取。每当跑步时,我什么也得不到,它只是等待。 我真的不明白我做错了什么。 该记录器文件基本上记录sensor_db.c文件的活动,即每当sensor_db打开、写入一个值以及每当它关闭时记录一条消息。

sensor_db.c 文件:

#include <stdio.h>
#include <stdbool.h>
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include "logger.h"
#include <fcntl.h>
#include <sys/wait.h>
// status 1: file opening error
// status 2: fork failure
// status 3: writing to db file failure
// status 4: file failed to close
// status 5: pipe creation failure

/* definition of global vars */


FILE* open_db(char *filename, bool append) {
    FILE *fp;
    if (append == true) {
        fp = fopen(filename, "a");
    } else {
        fp = fopen(filename, "w");
    }
    create_log_process();
    // Error handling for file opening
    if (fp == NULL) {
//        create_log_process();
        write_to_log_process("ERROR: could not open db file.");
        perror("Error occurred during file opening");
        exit(1);
    }

    // Communicate with the log process
//    create_log_process(); // Create the log process once before opening the data file
    write_to_log_process("Data file opened.");
//    end_log_process();
    return fp;
}


int insert_sensor(FILE * f, sensor_id_t id, sensor_value_t value, sensor_ts_t ts) {
    if (fprintf(f, "%d, %lf, %ld \n", id, value, ts) < 0) {
//        create_log_process();
        write_to_log_process("ERROR: could not write to db file.");
//        end_log_process();
        perror("Error writing to file");
        fclose(f);
        exit(3);
    }

    // Communicate with the log process
//    create_log_process();
    write_to_log_process("Data inserted.");
//    end_log_process();
    return 0;
}

int close_db(FILE * f) {
    if ( fclose(f) == EOF) {
//        create_log_process();
        write_to_log_process("ERROR: could not close db file.");
//        end_log_process();
        perror("Error closing file");
        exit(4);
    };
    // Communicate with the log process
//     create_log_process();
    write_to_log_process("Data file closed.");
    end_log_process();

    return 0;
}

logger.c 文件:

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
#define BUFFER_SIZE 1000

// status 1: file opening error
// status 2: fork failure
// status 3: writing to log file failure
// status 4: file failed to close
// status 5: pipe creation failure
// status 6: writing to log file failure

/*global variables (for file opening + pipe)*/
FILE *fp;
int fd[2], pid;
int i = 0;

int create_log_process() {
    // log file opening
    fp = fopen("gateway.log", "a");
    if (fp == NULL) {
        perror("Error occurred during log file opening");
        exit(1);
    }
    // creation of communication and child process
    if (pipe(fd) == -1) {
        perror("Error occurred during pipe creation");
        exit(5);
    };
    pid = fork();
    // error handle
    if (pid == -1) {
        perror("fork failed");
        exit(2);
    } else if (pid == 0) {
        close(fd[1]); // closing write_end.
        char received_message[BUFFER_SIZE];
        ssize_t bytes_read;
        while ((bytes_read = read(fd[0], received_message, BUFFER_SIZE - 1)) > 0) {
//            received_message[bytes_read] = '\0'; // Null-terminate the received data
            printf("test\n");
            printf("child process reads: %s \n", received_message);
            // timestamp creation.
            time_t timer;
            time(&timer);
            struct tm *timestamp_info;
            timestamp_info = localtime(&timer);
            char timestamp[20];
            strftime(timestamp, sizeof(timestamp), "%a %b %d %X %Y", timestamp_info);

            // writing message to log file.
            if (fprintf(fp, "%d - %s - %s\n", i++, timestamp, received_message) < 0) {
                perror("Error occurred during writing to log file");
                fclose(fp);
            };
            printf("test\n");
        }
        close(fd[0]);
        fclose(fp);
        exit(0);
    } else {
//        close(fd[0]);
    }
    return 0;
}

int write_to_log_process(char *msg) {
    if (pid > 0) {
        char message[BUFFER_SIZE];
        strncpy(message, msg, sizeof(message) - 1);
        message[sizeof(message) - 1] = '\0';  // Ensure null-termination
        if (write(fd[1], message, strlen(message) + 1) == -1) {
            perror("Error occurred during writing to pipe");
            exit(3);
        }
            // opmerking!!! sizeof(msg) don't use, = size of the pointer! use buffer_size...
            // with buffer_size you know for sure the nbytes you want to copy at most + is configurable.
    }
    return 0;
}


int end_log_process() {
    close(fd[0]);
    close(fd[1]);
    wait(NULL);
    return 0;
}

我尝试对其进行调试,但每当我到达记录器文件中定义的子进程中的 read() 函数时,调试器就会停止运行。

另外..这是使用的测试代码:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <time.h>

#include <sys/types.h>

#include "sensor_db.h"
#include "logger.h"
#include "config.h"

int main()
{
    FILE *f = open_db("sensor_db.csv", true);

    sleep(1);
    sensor_id_t id = 1;
    sensor_value_t v = 0.001;
    sensor_ts_t ts = time(NULL);
    insert_sensor(f, id, v, ts);

    id = 2;
    v = 0.002;
    ts = time(NULL);
    insert_sensor(f, id, v, ts);
    id = 3;
    v = 0.003;
    ts = time(NULL);
    insert_sensor(f, id, v, ts);
    sleep(5);
    insert_sensor(f, 4, v, ts);
    close_db(f);

    return 0;
}

c logging fork child-process
1个回答
0
投票

问题在于

message
中的
write_to_log_process()
变量。
sizeof(*msg) == sizeof(char) == 1
,所以
message
只有 1 个字节长,不足以容纳
msg
的副本。

应该是

strlen(msg)+1
以使其达到合适的长度。不过一开始就不需要复制消息,直接从
msg
写就可以了。

int write_to_log_process(char *msg) {
    if (write(fd[1], msg, strlen(msg) + 1) == -1) {  // +1 to include the null terminator
        // opmerking!!! sizeof(msg) don't use, = size of the pointer! use buffer_size...
        // with buffer_size you know for sure the nbytes you want to copy at most + is configurable.
        perror("Error occurred during writing to pipe");
        exit(3);
    }
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.