为什么我的fifo读取中间带有奇怪字符的返回字符串?

时间:2018-11-30 10:40:19

标签: c linux

我正在尝试通过命名管道将日志记录语句传递给守护进程。语句包含时间戳,发件人和消息。消息是按照预期的方式创建的,但是当我从管道的另一端读取消息时,它们有时在字符串中间带有奇怪的字符,例如Úèþ。我尝试将'\0'附加到每个日志记录语句的末尾,但没有任何效果。下面是我的管道创建和阅读部分的代码:

char * fdfifo = "./fifo/myfifo";
    mkfifo(fdfifo, 0666);
    int fd = open(fdfifo,O_RDONLY);
    struct timeval timeout;
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    logger(getpid(), pthread_self(), "logger started");
    while(1 && keepRunning){
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(fd, &fds);
        if(select(fd + 1, &fds, NULL, NULL, &timeout)<=0){
            logger(getpid(), pthread_self(), "stopping logger");
            close(fd);
            exit(EXIT_SUCCESS);
            break;
        }
        else{
            pthread_mutex_lock(&lock2);
            FILE *f = fopen("./log/log.log", "a");
            char concat_str[200];
            read(fd, concat_str, 200);
            fprintf(f, "%s\n", concat_str);
            fclose(f);
            pthread_mutex_unlock(&lock2);
        }
    }

这是我正在写管道的部分:

int startLoggerEnd(){
    readfifo = "./fifo/myfifo";
    mkfifo(readfifo, 0666);
    writedesc = open(readfifo,O_WRONLY);
    sleep(2);
    return 0;
}

int logger(pid_t pid, pthread_t tid, char *message){
    char tmp[100];
    char buff[20];
    char msg[200];
    struct tm *sTm;
    time_t now = time (0);
    sTm = gmtime (&now);
    strftime (buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", sTm);
    sprintf(msg,"%s %s %d %s %d %s %s\n", get_timestamp(tmp), "process:", pid,
            "thread:",(unsigned) tid, "||", message);
    write(writedesc, msg, strlen(msg));
    return 0;
}

以及日志文件末尾的几行:

13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
 process: 14736 thread: 127881216 || moi
13:29:41:729 process: 14736 thread: 127881216 || moi
13:29:

1 个答案:

答案 0 :(得分:2)

您当前正在显示分配的内存片(str2)。

但是,您不能确保所请求的内存部分为空。

它可能包含先前操作的字节,导致显示不正确。

确保不显示先前字节的正确方法是在打印之前清理内存。

char *str2 = calloc(strlen(msg) + 1, sizeof(char));
strcpy(str2, msg);
str2[strlen(msg)] = '\0'; // index start at 0, strlen start at 1
write(fd, str2, strlen(str2));
close(fd);

calloc将清除分配的内存,然后将其返回给您。

此外,请注意,此代码会遭受大量内存泄漏,甚至没有释放已分配的str2。