2012-01-08 10 views
21

जब मैं लिनक्स के तहत एक डेमॉन सी का उपयोग कर लिखने का प्रयास किया, मैं मैं कांटा कोड ब्लॉक के बाद निम्नलिखित कोड जोड़ने चाहिए कहा गया था:लिनक्स डिमन लिखते समय टीटीई से क्यों अलग होना चाहिए?

/* Preparations */ 
... 

/* Fork a new process */ 
pid_t cpid = fork(); 
if (cpid == -1){perror("fork");exit(1);} 
if (cpid > 0){exit(0);} 

/* WHY detach from tty ? */ 
int fd = open("/dev/tty", O_RDWR); 
ioctl(fd, TIOCNOTTY, NULL); 

/* Why set PGID as current PID ? */ 
setpgid(getpid(), 0); 

मेरा प्रश्न है: वहाँ ऊपर संचालन करने के लिए बहुत जरूरी है ?

+0

मुझे लगता है कि कारण का एक हिस्सा यह है कि एक डेमॉन को आउटपुट लिखने या इनपुट पढ़ने की उम्मीद नहीं है। अगर आप शुरू करना चाहते थे, उदा। एक एसएसएच सत्र पर एक HTTP सर्वर, आप बाद में सत्र में यादृच्छिक चेतावनी आउटपुट की उम्मीद नहीं करेंगे। –

+1

@ जॉन चडविक आप जो कह रहे हैं वह वास्तव में उन चीजों में से एक है जो आप डिमन में परिवर्तित करते समय करना चाहते हैं, लेकिन आप इसे स्टडीन, स्टडआउट और स्टडरर बंद करके प्राप्त करते हैं। कुछ सिग्नल से बचने के लिए आप टर्मिनल से अलग हो जाते हैं (नीचे दिए गए उत्तरों देखें)। –

+1

क्या आप मेरे उत्तर को "अस्वीकार" कर सकते हैं और इसके बजाय @ AdamZalcman को स्वीकार कर सकते हैं? वह मुझसे ज्यादा बेहतर काम करता है। और वह setid() के बारे में पूरी तरह से सही है, आपको इसका उपयोग करना चाहिए। – fge

उत्तर

34

टर्मिनल के ऑपरेशन से संबंधित सिग्नल भेजने से बचने के लिए आपको टर्मिनल से अपनी डेमॉन प्रक्रिया को अलग करना होगा (जैसे टर्मिनल सत्र समाप्त होने पर SIGUP और संभावित रूप से सिग्टिन और सिगेटू)।

नोट हालांकि कि TIOCNOTTY ioctl का उपयोग कर टर्मिनल से अलग करने का तरीका काफी हद तक अप्रचलित है। आपको इसके बजाय setsid() का उपयोग करना चाहिए।

अपने मूल प्रक्रिया समूह को छोड़ने के लिए डिमन का कारण उस समूह को भेजे गए सिग्नल प्राप्त नहीं करना है। ध्यान दें कि setsid() आपकी प्रक्रिया को अपने स्वयं के प्रक्रिया समूह में भी रखता है।

+2

+1 'सेटिड() ' – fge

+0

+1 के लिए बहुत अच्छे और पूर्ण उत्तर के लिए +1, विशेष रूप से" हम ऐसा क्यों करते हैं? " अंश। –

+0

+1। चेतावनी: सेटिड के बाद भी (2) यदि कोई सावधान नहीं है (फोर्क() फिर से या O_NOCTTY) तो नियंत्रण टर्मिनल प्राप्त करना संभव हो सकता है। – pilcrow

10

दूसरा उत्तर स्पष्ट और तकनीकी रूप से सही है (और इसलिए मैंने तदनुसार ऊपर उठाया)।

एक और जवाब है: "नहीं, कोड लिखना न करें जो खुद को डिमन करता है।"

बजाय एक प्रक्रिया पर्यवेक्षण फ्रेमवर्क (daemontools या runit या launchd) की तरह है कि आप के लिए यह का ख्याल रखता है का उपयोग करें।

पारंपरिक यूनिक्स सर्वर स्वयं daemonizing है, और कई बातों पर इस तरह के fusses के रूप में: आदि वर्तमान कार्यशील निर्देशिका, प्रक्रिया समूह और सत्र स्वतंत्रता, संकेत मास्क और स्वभाव, फाइल सिस्टम जड़, विशेषाधिकार, umask, खुले फ़ाइल वर्णनकर्ता,

हालांकि, इनमें से अधिकांश या सभी प्रक्रिया विशेषताओं को exec() में विरासत में मिला है, जिसका अर्थ है कि एक सर्वर प्रक्रिया आमतौर पर वांछित प्रक्रिया समूह, कार्यशील निर्देशिका, रूट इत्यादि के साथ "पैदा" हो सकती है। अपने आप को सब कुछ करने की आवश्यकता नहीं है , हालांकि आपको अक्सर विशेषाधिकार प्राप्त संचालन और विशेषाधिकार निरस्त करने का प्रबंधन करना होगा।

(दरअसल, मैं तर्क दूंगा कि आत्म-डिमनीकरण कार्यक्रमों को लिखने में दीर्घकालिक जोखिम है। बॉयलरप्लेट "पृष्ठभूमि" दिनचर्या प्रतिलिपि बनाई जाती है और पेस्ट की जाती है और जल्दी से पोर्ट और विस्तारित होती है, और प्रोग्रामर सहायक कोड पर समय बिताता है कार्यक्रम का मुख्य उद्देश्य।)

+0

महान जवाब!डेमोनाइजिंग कॉलर की पसंद होनी चाहिए, न कि एप्लिकेशन द्वारा मजबूर नहीं। और कॉलर के लिए, बहुत सारे मौजूदा उपकरण हैं, एप्लिकेशन में इसे फिर से आविष्कार करने की आवश्यकता नहीं है। –

संबंधित मुद्दे