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