Moved duplicated wxMac/wxCocoa code into src/mac/corefoundation/utilsexc_cf.cpp
[wxWidgets.git] / src / cocoa / utilsexc.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/cocoa/utilsexec.mm
3 // Purpose:     Execution-related utilities for wxCocoa
4 // Author:      Ryan Norton
5 // Modified by:
6 // Created:     2004-10-05
7 // RCS-ID:      $Id$
8 // Copyright:   (c) Ryan Norton
9 // Licence:     wxWindows licence
10 // Notes:       This code may be useful on platforms other than Darwin.
11 //              On Darwin we share the CoreFoundation code with wxMac.
12 /////////////////////////////////////////////////////////////////////////////
13
14 #include "wx/wxprec.h"
15 #ifndef WX_PRECOMP
16 #endif
17 #include "wx/unix/execute.h"
18
19 #if 0
20
21 #ifdef __GNUG__
22 #pragma implementation
23 #endif
24
25 #include "wx/utils.h"
26
27 #include "wx/process.h"
28 #include "wx/stream.h"
29
30 #include "wx/cocoa/string.h"
31
32 #import <Foundation/Foundation.h>
33 #import <AppKit/NSWorkspace.h>
34
35 //
36 // RN:  This is a prelimenary implementation - simple
37 // launching and process redirection works,
38 // but with the piping tests in the exec sample
39 // SIGPIPE is triggered...
40 //
41
42 class wxPipeInputStream : public wxInputStream
43 {
44 public:
45     wxPipeInputStream(NSPipe* thePipe) : 
46             m_thePipe(thePipe),
47             m_theHandle([m_thePipe fileHandleForReading])
48     {
49     }
50
51     ~wxPipeInputStream()
52     {   
53         [m_thePipe release];
54     }
55
56 protected:
57     virtual size_t OnSysRead(void *buffer, size_t size)
58     {
59         NSData* theData = [m_theHandle readDataOfLength:size];
60         memcpy(buffer, [theData bytes], [theData length]);
61         return [theData length];
62     }
63     
64     
65     NSPipe*             m_thePipe;
66     NSFileHandle*       m_theHandle;
67 };
68
69 class wxPipeOutputStream : public wxOutputStream
70 {
71 public:
72     wxPipeOutputStream(NSPipe* thePipe) : 
73             m_thePipe(thePipe),
74             m_theHandle([m_thePipe fileHandleForWriting])
75     {
76     }
77
78     ~wxPipeOutputStream()
79     {   
80         [m_thePipe release];
81     }
82
83 protected:
84
85     virtual size_t OnSysWrite(const void *buffer, size_t bufsize)
86     {
87         NSData* theData = [NSData dataWithBytesNoCopy:(void*)buffer 
88                                   length:bufsize];
89         [m_theHandle writeData:theData];
90         return bufsize;
91     }
92         
93     NSPipe*             m_thePipe;
94     NSFileHandle*       m_theHandle;
95 };
96
97 @interface wxTaskHandler : NSObject
98 {
99     long m_pid;
100     void* m_handle;
101 }
102 -(id)init:(void*)handle processIdentifier:(long)pid;
103 - (void)termHandler:(NSNotification *)aNotification;
104 @end
105
106 @implementation wxTaskHandler : NSObject
107
108 -(id)init:(void*)handle processIdentifier:(long)pid 
109 {
110     self = [super init];
111     
112     m_handle = handle;
113     m_pid = pid;
114
115     [[NSNotificationCenter defaultCenter] addObserver:self 
116             selector:@selector(termHandler:) 
117             name:NSTaskDidTerminateNotification 
118             object:nil];
119     return self;
120 }
121
122 - (void)termHandler:(NSNotification *)aNotification 
123 {
124     NSTask* theTask = [aNotification object];
125     
126     if ([theTask processIdentifier] == m_pid)
127     {
128         ((wxProcess*)m_handle)->OnTerminate([theTask processIdentifier], 
129                           [theTask terminationStatus]);
130         
131         [self release];
132     }
133 }
134
135 @end
136
137 long wxExecute(const wxString& command, 
138                 int sync, 
139                 wxProcess *handle)
140 {
141     NSTask* theTask = [[NSTask alloc] init];
142     
143     if (handle && handle->IsRedirected())
144     {
145         NSPipe* theStdinPipe = [[NSPipe alloc] init];
146         NSPipe* theStderrPipe = [[NSPipe alloc] init];
147         NSPipe* theStdoutPipe = [[NSPipe alloc] init];
148     
149         [theTask setStandardInput:theStdinPipe];
150         [theTask setStandardError:theStderrPipe];
151         [theTask setStandardOutput:theStdoutPipe];
152         
153         handle->SetPipeStreams(new wxPipeInputStream(theStdoutPipe),
154                                new wxPipeOutputStream(theStdinPipe),
155                                new wxPipeInputStream(theStderrPipe) );
156     }
157     
158     NSArray* theQuoteArguments = 
159         [wxNSStringWithWxString(command) componentsSeparatedByString:@"\""];
160         
161     NSMutableArray* theSeperatedArguments = 
162         [NSMutableArray arrayWithCapacity:10];
163         
164     for (unsigned i = 0; i < [theQuoteArguments count]; ++i)
165     {
166         [theSeperatedArguments addObjectsFromArray:
167             [[theQuoteArguments objectAtIndex:i] componentsSeparatedByString:@" "]
168         ];
169         
170         if(++i < [theQuoteArguments count])
171             [theSeperatedArguments addObject:[theQuoteArguments objectAtIndex:i]];
172     }
173     
174     [theTask setLaunchPath:[theSeperatedArguments objectAtIndex:0]];
175     [theTask setArguments:theSeperatedArguments];
176     [theTask launch];
177     
178     if(sync & wxEXEC_ASYNC)
179     {
180         [[wxTaskHandler alloc]init:handle 
181                               processIdentifier:[theTask processIdentifier]];
182                                 
183         return 0;
184     }
185     else
186     {
187         [theTask waitUntilExit];
188         
189         return [theTask terminationStatus];
190     }                      
191 }
192 #endif //0
193