2012-04-26 11 views
6

क्या सिस्टम पर कुछ ऐसा है। विंडोज़ पर पॉसिक्स?हैकेल के साथ विंडोज़ पर सिग्नल कैसे संभालें?

मैं नीचे दिए गए कोड को विंडोज़ पर चलाने के लिए चाहता हूं, क्या मुझे इसे बदलना चाहिए?

import IO 
import Control.Exception hiding (catch) 
import Control.Concurrent 
import Network 
import System.Posix ---cannot be run on windows. 

main = withSocketsDo (installHandler sigPIPE Ignore Nothing >> main') 
    --so the signal handler cannot be used 

main' = listenOn (PortNumber 9900) >>= acceptConnections 

acceptConnections sock = do 
     putStrLn "trying to accept" -- debug msg 
     [email protected](h,host,port) <- accept sock 
     print conn -- debug msg 
     forkIO $ catch (talk conn `finally` hClose h) (\e -> print e) 
     acceptConnections sock 

talk [email protected](h,_,_) = hGetLine h >>= hPutStrLn h >> hFlush h >> talk conn 
उदाहरण के लिए

, अगर मैं कार्यक्रम चाहते हैं जब CTRL + C, मैं SIGINT के लिए कोई हैंडलर जोड़ना होगा C++ हां, तो बाहर निकलने के लिए, इस तरह की कुछ कोड लिखें:

void callback(int sig) 
{ 
    // printf("catch\n"); 
} 
... 
signal(SIGINT,callback); 

लेकिन मैं डॉन हैकेल में ऐसा करने के बारे में नहीं पता, एफएफआई का उपयोग करें?

उत्तर

4
import Foreign 
import Foreign.C.Types 

type Handler = CInt->IO() 
foreign import ccall "wrapper" 
    genHandler:: (Handler) -> IO (FunPtr Handler) 

foreign import ccall safe "signal.h signal" 
     install:: CInt->FunPtr Handler->IO CInt 
main=do 
     s<-genHandler (\x->putStrLn $ "catch "++(show x)) 
     res<- install 2 s 
     putStrLn $ show res 
     s<-getLine 

ऊपर कोड मुझे क्या करना चाहते हैं, बस signal समारोह आयात करते हैं, एक haskell कॉलबैक के साथ है।

3

मैं विंडोज विशेषज्ञ नहीं हूं, इसलिए मुझे नहीं पता कि आपको जो भी घटना अनदेखा कर रही है उसे अनदेखा करने के लिए आपको क्या करना होगा। आप जो भी संस्करण स्थापित कर चुके हैं, उसके लिए आप Win32 दस्तावेज़ में लगभग पोक करना चाहते हैं। हालांकि, मैं बिल्ड सिस्टम के बारे में कुछ जानता हूं और फ़ंक्शन के दो संस्करणों में से एक को कैसे प्राप्त करना है। तो रणनीति इस तरह दिखेगी:

  1. दो निर्देशिकाएं, unix-src और Win32-src (या कुछ समान नाम) बनाएं। अपने project.cabal फ़ाइल में

    -- unix-src/OSCompat.hs 
    module OSCompat where 
    import System.Posix 
    ignorePipe = installHandler sigPIPE Ignore Nothing 
    
    -- Win32-src/OSCompat.hs 
    module OSCompat where 
    import System.Win32 
    ignorePipe = -- ??? 
    
  2. , अपने executable ब्लॉक में निम्नलिखित की तरह कुछ डाल:

  3. प्रत्येक निर्देशिका में, एक मॉड्यूल OSCompat (या कुछ इसी तरह के नाम) कुछ इस तरह से युक्त कर दिया

    if os(windows) 
        build-depends: Win32 
        hs-source-dirs: Win32-src 
    else 
        build-depends: unix 
        hs-source-dirs: unix-src 
    
  4. इस तरह देखने के लिए अपने शीर्ष स्तर के मॉड्यूल बदलें:

    import OSCompat 
    main = withSocketsDo (ignorePipe >> main') 
    
1

मुझे नहीं लगता कि आप विंडोज पर ऐसा कुछ कर सकते हैं। विंडोज पॉज़िक्स-संगत नहीं है, इसलिए यह पूर्ण सीमा में सिग्नल का समर्थन नहीं करता है, उदा। यह does not support अन्य प्रक्रियाओं के लिए सिग्नल भेज रहा है। is pretty limited उपलब्ध सिग्नल की संख्या भी उपलब्ध है।

यदि मैं सही ढंग से समझ गया तो आप अपने प्रोग्राम को बाहर निकलने से बचाने के लिए सिगिपिप को अनदेखा कर रहे हैं यदि उसका आउटपुट किसी अन्य प्रक्रिया में पाइप किया गया था और फिर यह प्रक्रिया समाप्त हो गई है, है ना? क्षमा करें, मुझे नहीं पता कि विंडोज़ में ऐसा कैसे करें (और वास्तव में आप अक्सर विंडोज़ पर सरल पाइप के माध्यम से संचारित प्रोग्राम नहीं देखते हैं)। यदि आपका सिग्नल हैंडलिंग सॉकेट से जुड़ा हुआ है, तो this मदद कर सकता है।

4

पार्टी के लिए देर हो गई, लेकिन मैंने एक पुस्तकालय लिखा जो मदद कर सकता है। यह विंडोज और लिनक्स दोनों पर सिग्नल हैंडलिंग की अनुमति देता है। यह हैकेज पर उपलब्ध है: https://hackage.haskell.org/package/signal

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