كيفية الخروج من عملية الطفل وإرجاع وضعها من ExecVP ()؟
سؤال
في قذيفة مخصصة بسيطة، أقرأ الأوامر من الإدخال القياسي وتنفيذها مع ExecVP (). قبل ذلك، أقوم بإنشاء شوكة من العملية الحالية وأدعو EXECVP () في عملية الطفل هذه، بعد ذلك، قمت بإجراء مخرج (0).
شيء من هذا القبيل:
pid = fork();
if(pid == -1) {
perror("fork");
exit(1);
}
if(pid == 0) {
// CHILD PROCESS CODE GOES HERE...
execvp(pArgs[0], pArgs);
exit(0);
} else {
// PARENT PROCESS CODE GOES HERE...
}
الآن، يمكن تشغيل الأوامر التي تعمل مع execvp () الأخطاء الصحيحة؟ أريد أن أتعامل مع ذلك بشكل صحيح واليمين، وأنا دائما أتصل بالخروج (0)، مما يعني أن عملية الطفل ستتم دائما حالة "موافق".
كيف يمكنني إرجاع الحالة المناسبة من استدعاء execvp () ووضعها في مكالمة الخروج ()؟ يجب أن أحصل فقط على القيمة الدولية التي تعود execvp () وتمريرها كوسيطة خروج () بدلا من 0. هل هذا يكفي وصحيح؟
المحلول
تحتاج إلى استخدام waitpid(3)
أو wait(1)
في القانون الوالد لانتظار الطفل للخروج والحصول على رسالة الخطأ.
بناء الجملة هو:
pid_t waitpid(pid_t pid, int *status, int options);
أو
pid_t wait(int *status);
status
يحتوي على حالة الخروج. انظر الى صفحات الرجل لرؤيتك كيفية تحليلها.
لاحظ أنه لا يمكنك القيام بذلك من عملية الطفل. بمجرد الاتصال execvp
عملية الطفل يموت (لجميع الأغراض العملية) وهو استبدالها بواسطة exec
عملية د. الطريقة الوحيدة التي يمكنك الوصول إليها exit(0)
هناك إذا execvp
نفسه فشل، ولكن بعد ذلك الفشل ليس لأن البرنامج الجديد انتهى. لأنه لم يدرك أبدا لتبدأ.
يحرر: عملية الطفل لا حقا موت. تبقى PID والبيئة دون تغيير، ولكن يتم استبدال الكود الكامل والبيانات ب exec
عملية د. يمكنك الاعتماد على ليس العودة إلى عملية الطفل الأصلية، ما لم exec
فشل.
نصائح أخرى
من سؤالك، من الصعب للغاية معرفة ما تسأل. لذلك سأحاول تغطية زوجين من القضايا ذات الصلة:
execvp()
إما لا يعود (في النجاح)، أو إرجاع خطأ. بمعنى رمز طفلك تحتاج فقط إلى شروط الخطأ التعامل معه. يجب أن تلتقط رمز الطفل نتيجةexecvp()
واستخدام هذه القيمة فيexit()
كما اقترحت. يجب ألا يعود رمز طفلك أبدا 0، لأن النجاح الوحيد يعني أنexecvp
عملت و الذي - التي ستعود العمليات 0 (أو لا).- يمكن للوالد الحصول على معلومات الطفل من
waitpid()
حول هذا هو وضع الخروج. هناك العديد من وحدات الماكرو المحددة لسحب المعلومات من عادstatus
معامل. ملحوظ لغرضكWIFEXITED
لأخبرك إذا خرج الطفل "عادة"، وWEXITSTATUS
للحصول على حالة الطفل كما تم تمريرها إلىexit()
. وبعد انظرwaitpid
صفحة الرجل لحدات الماكرو الأخرى.
يستخدم wait()
أو waitpid()
في العملية الأصل. مثال هنا: إرجاع الرمز عند قيام نظام التشغيل بقتل عمليةك.
أيضا، عندما يموت الطفل SIGCHLD
يتم إرسال إشارة إلى العملية الأصلية.