मैं थ्रेड-सुरक्षित सी लॉगिंग फ़ंक्शन लिखने की कोशिश कर रहा हूं, और मुझे फ़ाइल IO के साथ कुछ गंभीर समस्याएं आ रही हैं। तो, मूल रूप से, मैं एक दिलचस्प fopen
कॉल मुझे द्विआधारी अद्यतन मोड में लॉग खोलने देता है के साथ शुरू:सी: एक फ़ाइल में थ्रेड सुरक्षित लॉगिंग
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+");
इसके बाद, मैं फ़ाइल ताला, एक टाइमआउट को शामिल करता है, तो लंबे समय के लिए एक और धागा ताले यह:
//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);
}
और अंत में, मैं फ़ाइल के अंत करने के लिए आवश्यक संदेश जोड़ने के लिए, इसे अनलॉक और फ़ाइल को बंद करें:
//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);
हालांकि, यह गंदगी के बहुमत की तरह लगता है उम्र में उम्र को अधिलेखित करने के बजाए लॉग में ओवरराइट किया गया है, लगभग fopen
ने फ़ाइल का "स्नैपशॉट" लिया, इसे अनलॉक करने के लिए इंतजार किया, और लिखा कि फाइल का अंत क्या होगा यदि कोई अन्य प्रक्रिया नहीं जुड़ी इसके लिए क्या किसी को इस बारे में कोई विचार है कि मैं इस समस्या को ठीक करने के बारे में कैसे जा सकता हूं?
एक तरफ, मैं बाइनरी अपडेट मोड में होना चाहता हूं क्योंकि मैं अंततः कुछ ट्रिमिंग कार्यक्षमता जोड़ूंगा जो सुनिश्चित करेगा कि लॉग फ़ाइल एक निश्चित आकार से अधिक न हो, और मेरे लिए यह काम करना आसान है fseek
कॉल और आर/डब्ल्यू कार्यक्षमता।
किसी भी सुझाव की सराहना की जाती है। धन्यवाद पहले से ही!
जब आप डीबगर के साथ कदम उठाते हैं तो क्या होता है? – SecurityMatt
आपके सभी ऑपरेशन 'fseek' और' fwrite' को छोड़कर 'स्टार्ट' के साथ हैं। क्या यह उम्मीद है? – Ganesh
@ गणेश, हां, मैं फ़ाइल की शुरुआत में एक फ़ाइल पॉइंटर रखना चाहता था और मेरे सभी लेखन को एक और के साथ करना चाहता था, बस अगर मैं अनलॉक करने या किसी अन्य ऑपरेशन करने से पहले 'रिवाइंड()' करना भूल गया था फ़ाइल की शुरुआत के लिए सूचक। – SuperTron