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