用户态内核设备逐行读取程序数据覆盖问题修复及log.txt逐行写入优化咨询
Hey there! Let's break down and fix your two main issues step by step, plus clean up some problematic logic in your code.
First: Fixing the Data Overwrite Problem
Your original code had a few key issues causing data loss/overwrite:
- You opened
log.txtwithw+mode, which clears the entire file every time the program runs—use append mode instead to preserve existing content. - You only wrote the buffer to the file once after filling it, which meant any partial reads or overwritten buffer data got lost.
- The
lseeklogic was backwards and unnecessary, leading to missed writes if the seek operation succeeded.
Second: Implementing Line Breaks Between Log Entries
To get an empty line between each log entry, we need to split the read data into individual lines, then write each line followed by an extra newline character.
Corrected Code
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <fcntl.h> #define BUFFER_LENGTH 256 int main() { int fd; char buffer[BUFFER_LENGTH]; FILE *fPtr; // Open device in read-only mode (no need for RDWR unless the device requires it) if ((fd = open("/dev/show_log_device_dev", O_RDONLY)) == -1) { perror("Failed to open the device file"); return errno; } // Open log file in append mode to preserve existing content fPtr = fopen("log.txt", "a+"); if (!fPtr) { perror("Failed to open log.txt"); close(fd); return errno; } printf("Started reading from /dev/show_log_device_dev...\n"); // Read from device continuously until EOF or error ssize_t bytes_read; while ((bytes_read = read(fd, buffer, BUFFER_LENGTH - 1)) > 0) { // Null-terminate the buffer to safely handle string operations buffer[bytes_read] = '\0'; // Split the read data into individual lines char *line = strtok(buffer, "\n"); while (line != NULL) { // Write line to log with an extra newline for spacing fprintf(fPtr, "%s\n\n", line); // Print to console for visibility printf("Read line: %s\n", line); // Get next line from the buffer line = strtok(NULL, "\n"); } // Flush the file buffer to ensure data writes to disk immediately fflush(fPtr); } if (bytes_read == -1) { perror("Failed to read from device"); } // Clean up resources fclose(fPtr); close(fd); return 0; }
Key Changes Explained
- Append Mode for Log File: Using
a+instead ofw+ensures existing log content isn't erased when the program starts. - Immediate Line Processing: Instead of waiting to fill the buffer, we split each read into lines and write them to the file right away—this prevents buffer overwrites from losing unwritten data.
- Proper String Termination: Adding
buffer[bytes_read] = '\0'ensures we don't hit undefined behavior when using string functions likestrtok. - Line Spacing:
fprintf(fPtr, "%s\n\n", line)adds an extra newline after each log entry, creating the empty line gap you want. - Error Handling: Added checks for
fopenfailure and cleaned up resources properly if errors occur.
Bonus Note
If your kernel device clears its buffer after each read (common for custom log devices), this code ensures you never miss data by writing immediately. If you want to run this as a persistent log monitor, wrap the read loop in an infinite while(1) and add signal handling (e.g., for SIGINT) to exit gracefully.
内容的提问来源于stack exchange,提问作者QueryMan

