2010-02-03 11 views
10

मेरे पास एक बाल प्रक्रिया है जो छद्म टर्मिनल में चलती है। मूल प्रक्रिया रूट के रूप में नहीं चलती है, लेकिन बच्चे की प्रक्रिया सु या सूडो के माध्यम से होती है। इस वजह से इसे बाहर निकलने के लिए मजबूर करने के लिए बाल प्रक्रिया को संकेत भेजना संभव नहीं है। मैं इसे इन तरीकों में से किसी एक से बाहर निकलने के लिए मजबूर करना चाहता हूं:बाल प्रक्रिया में Ctrl-C नियंत्रण वर्ण या टर्मिनल हैंगअप संदेश कैसे भेजें?

  • एक Ctrl-C अनुकरण करना।
  • एक टर्मिनल हैंगअप अनुकरण।

मैं इनमें से किसी एक को कैसे कर सकता हूं? मैं पहले से ही एक प्राइवेट मास्टर fd है, और मुझे कुछ इस तरह की कोशिश की है:

write(master, &termios.c_cc[VINTR], 1) 

लेकिन यह कुछ भी नहीं है।

+0

मुझे नहीं पता कि यह आपके प्रोग्राम/पीटीआई के साथ काम करेगा, लेकिन मैं बैश चलाने के बाद से क्या करता हूं, और बैश डिफ़ॉल्ट रूप से^सी को सिगिनट के रूप में लेता है [मुझे लगता है?] एक char बनाता है जिसमें एक हेक्स कोड: (0x03^सी के लिए) और फिर इसे मेरे पीटीआई के साथ लिखें: लिखें (m_nMaster, और ctrlC, sizeof (ctrlC)); –

उत्तर

2

मैं अंत में निम्नलिखित समाधान के साथ चला गया। तो प्रक्रिया पदानुक्रम इस तरह दिखता है:

original process   <---- runs as user 
    | 
    +-- helper process  <---- runs as user, session leader, 
     |      has own pty, in pty's foreground process group 
     | 
     +--- sudo  <---- runs as root 

सहायक प्रक्रिया की हत्या करके, Pty अब और एक अग्रभूमि प्रक्रिया नहीं है। यह ओएस को उपयोगकर्ता के बावजूद, पूरे अग्रभूमि प्रक्रिया समूह को SIGHUP भेजने का कारण बनता है, इसलिए सुडो भी SIGHUP'ed है।

0

वहाँ इस लक्ष्य को हासिल करने के दो तरीके है:

  • बच्चे प्रक्रिया से, जाल SIGCHLD संकेत और इसे संभाल, आप _exit सकता है (0) बच्चे प्रक्रिया समाप्त करने के लिए
  • एक कार्यक्रम ptree कहा जाता है । आप इसे इस तरह से कार्य करके यह धोखा हो सकता है ... स्यूडोकोड में:
 
obtain the parent's pid. 
using _popen("ptree %d", parent_pid) 
for each entry of child process 
system ("kill -1 %d", child_process_pid) 

वहाँ दो जो मन में आता ... खेद अगर इसकी नहीं आगे की आप के लिए, मदद

इस आशा मदद करता है, सर्वश्रेष्ठ संबंध, टॉम।

+0

वह सीधे बच्चे को संकेत नहीं दे सकता क्योंकि यह एक अलग प्रभावी यूआईडी के तहत चल रहा है। – caf

+0

@ कैफ: हमम .... क्या आप इसका उत्तर दे सकते हैं? कल्पना करें कि क्या छद्म टर्मिनल पर बाल प्रक्रिया चल रही है, इसे लिनक्स उदाहरण के तहत ले जाएं ... अगर एक बाइनरी फ़ाइल छद्म टर्मिनल को कैट/dev/pty4 पर ले जाती है, जहां बच्चे की प्रक्रिया होती है, तो वह कारण होगा एक टर्मिनल hangup? यानी बिल्ली binary_file>/dev/pty4 – t0mm13b

+0

नहीं, यह क्यों होगा? यह सिर्फ उन बाइट्स को छद्म टर्मिनल जोड़ी के मास्टर पक्ष में पहुंचाएगा। – caf

0

मास्टर को बंद करना दास के नियंत्रण प्रक्रिया समूह में एक हैंगअप को संकेत देना चाहिए।

0

मैं तुम्हें ioctl उपयोग करने के लिए write के बजाय बाधा चरित्र डालने की आवश्यकता है। दुर्भाग्य से इसके लिए तंत्र पोर्टेबल प्रतीत नहीं होता है। लिनक्स के लिए यह इस काम हो सकता है दिखता है:

ioctl(master, TIOCSTI, &termios.c_cc[VINTR]); 
+0

मुझे "अनुमति अस्वीकार"/"ऑपरेशन की अनुमति नहीं है" त्रुटि मिलती है। यदि मैं प्रक्रिया को जड़ के रूप में चलाता हूं तो मुझे "ऑपरेशन का समय समाप्त हो जाता है"। – Hongli

0

पहली बात मैं जाँच चाहते हैं, तो आप इसे गुलाम तरफ नियंत्रित टर्मिनल बनाने की जरूरत है। यह पता चला है कि यह more complex है, मुझे याद है, ptys संभवतः डिफ़ॉल्ट रूप से नियंत्रित नहीं हो रहा है। यह लिंक लिनक्स के लिए है, अन्य सिस्टमों को अपने एसआईएसवी बनाम बीएसडी-नेस के आधार पर एक या दूसरे को करना चाहिए, लेकिन ऐसा लगता है कि टियोकैक्टी कोशिश करने के लिए एक अच्छी शर्त है।

दूसरे

, मैं अगर आप अपने termios में ISIG स्थापित कर रहे हैं की जाँच चाहते हैं; यदि नहीं, तो वीआईएनटीआर और वीक्विट काम नहीं करेगा।

बेशक

, अगर दूसरे छोर SIGINT और SIGQUIT बढ़ रहा है, तो आप अन्य मुद्दों होगा।

4

मुझे ऐसा लगता है यदि आप वास्तव में एक प्राइवेट है (जब तक आप छद्म टर्मिनल से कुछ और ही मतलब), तुम सब करने की ज़रूरत है कि एफडी करने के लिए एक नियंत्रण सी भेज है कि कि। एक प्राइवेट, जो अनंत लूप मुद्रण तारीख चलाता है के तहत

import pty, os, sys, time 

pid, fd = pty.fork() 
if pid == 0: 
    os.execv('/bin/sh', ['/bin/sh', '-c', 
     'while true; do date; sleep 1; done']) 
    sys.exit(0) 
time.sleep(3) 
os.write(fd, '^C') 
print 'results:', os.read(fd, 1024) 

यह कांटे एक प्रक्रिया: इस बात का सबूत के रूप में, मैं अजगर में निम्नलिखित कोड प्रस्तुत (लेकिन काफी सी के पास यह करने के लिए आवश्यक)। तब माता-पिता 3 सेकंड इंतजार कर रहा है और एक नियंत्रण सी भेजता है।

यह निम्न उत्पादन में परिणाम है:

guin:/tmp$ time python /tmp/foo 
results: Fri Feb 5 08:28:09 MST 2010 
Fri Feb 5 08:28:10 MST 2010 
Fri Feb 5 08:28:11 MST 2010 

python /tmp/foo 0.02s user 0.01s system 1% cpu 3.042 total 
guin:/tmp$ 

यह भाग गया सिर्फ 3 सेकंड से अधिक, 3 बार बाहर मुद्रित तिथि, और बाहर निकल गया। , Forking के बाद

बजाय sudo तुरंत exec'ing की, मैं exec() एक सहायक बच्चे प्रक्रिया के बजाय, जो बारी कांटे और अधिकारियों sudo और कॉल में इस पर waitpid:

+0

उपयोगी उदाहरण, धन्यवाद! –

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