Tôi đang cố gắng viết chức năng ghi nhật ký C an toàn chỉ và tôi đang gặp một số vấn đề nghiêm trọng với tệp IO. Vì vậy, về cơ bản, tôi bắt đầu với một fopen
gọi thú vị cho phép tôi mở nhật ký trong chế độ cập nhật nhị phân:C: Chủ đề Ghi nhật ký an toàn vào một tệp
FILE *log, *start;
int timeout = 0, error;
//make file (fails if file exists)
log = fopen(LOG_FILE, "wx");
//Close the file if a new one was created
if(log)
fclose(log);
//Open file in update mode (it must exist for this)
log = fopen(LOG_FILE, "rb+");
Tiếp theo, tôi khóa các tập tin, kết hợp với một thời gian chờ nếu một thread khóa nó quá lâu:
//Init other file pointer
start = log;
//Lock file (with timeout)
rewind(start);
error = lockf(fileno(start), F_TLOCK, 0);
while(error == EACCES || error == EAGAIN)
{
//sleep for a bit
usleep(LOCKED_FILE_RETRY_TIME);
//Incremement timeout
timeout += LOCKED_FILE_RETRY_TIME;
//Check for time out
if(timeout > LOCKED_FILE_TIMEOUT)
{
return;
}
//Retry the lock operation
error = lockf(fileno(start), F_TLOCK, 0);
}
và cuối cùng, tôi thêm thông điệp cần thiết để cuối của tập tin, mở khóa và đóng file:
//Print log entry
fseek(log, 0, SEEK_END);
fwrite((const void*) log_msg, 1, strlen(log_msg), log);
//Unlock the block
rewind(start);
lockf(fileno(start), F_ULOCK, 0);
//Close file
fclose(log);
Tuy nhiên, nó có vẻ như phần lớn các mớ hỗn độn độ tuổi được ghi đè trong nhật ký, thay vì được thêm vào, gần như là nếu fopen
lấy một "ảnh chụp nhanh" của tệp, chờ cho nó được mở khóa và ghi vào nơi kết thúc của tệp nếu quá trình khác không thêm cho nó. Có ai có bất kỳ ý tưởng như thế nào tôi có thể đi về sửa chữa vấn đề này? Là một sang một bên, tôi muốn ở chế độ cập nhật nhị phân vì cuối cùng tôi sẽ thêm một số chức năng cắt tỉa để đảm bảo tệp nhật ký không vượt quá kích thước nhất định và điều này dễ dàng hơn cho tôi khi thực hiện các cuộc gọi fseek
R/W chức năng.
Bất kỳ mẹo nào được đánh giá cao. Cảm ơn trước!
Điều gì sẽ xảy ra khi bạn thực hiện với trình gỡ lỗi? – SecurityMatt
Tất cả các thao tác của bạn là 'bắt đầu' trừ' fseek' và 'fwrite'. điều này có được mong đợi không? – Ganesh
@Ganesh, Có, tôi muốn giữ một tệp con trỏ đến đầu tệp và thực hiện tất cả các văn bản của mình với một tệp khác, chỉ trong trường hợp tôi quên thực hiện 'rewind()' trước khi mở khóa hoặc thực hiện một thao tác khác cần con trỏ đến đầu tệp. – SuperTron