]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/utilsexc.mm
Check for buffer being big enough in wxPathOnly().
[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 #if 0
21
22 #ifndef WX_PRECOMP
23 #if wxUSE_STREAMS
24 #include "wx/stream.h"
25 #endif // wxUSE_STREAMS
26 #endif //WX_PRECOMP
27
28 #include "wx/process.h"
29
30 #include "wx/cocoa/string.h"
31
32 #include "wx/cocoa/objc/objc_uniquifying.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 WX_DECLARE_GET_OBJC_CLASS(wxTaskHandler,NSObject)
108
109 @implementation wxTaskHandler : NSObject
110
111 -(id)init:(void*)handle processIdentifier:(long)pid
112 {
113 self = [super init];
114
115 m_handle = handle;
116 m_pid = pid;
117
118 [[NSNotificationCenter defaultCenter] addObserver:self
119 selector:@selector(termHandler:)
120 name:NSTaskDidTerminateNotification
121 object:nil];
122 return self;
123 }
124
125 - (void)termHandler:(NSNotification *)aNotification
126 {
127 NSTask* theTask = [aNotification object];
128
129 if ([theTask processIdentifier] == m_pid)
130 {
131 ((wxProcess*)m_handle)->OnTerminate([theTask processIdentifier],
132 [theTask terminationStatus]);
133
134 [self release];
135 }
136 }
137
138 @end
139 WX_IMPLEMENT_GET_OBJC_CLASS(wxTaskHandler,NSObject)
140
141 long wxExecute(const wxString& command,
142 int sync,
143 wxProcess *handle,
144 const wxExecuteEnv *env)
145 {
146 NSTask* theTask = [[NSTask alloc] init];
147
148 if (handle && handle->IsRedirected())
149 {
150 NSPipe* theStdinPipe = [[NSPipe alloc] init];
151 NSPipe* theStderrPipe = [[NSPipe alloc] init];
152 NSPipe* theStdoutPipe = [[NSPipe alloc] init];
153
154 [theTask setStandardInput:theStdinPipe];
155 [theTask setStandardError:theStderrPipe];
156 [theTask setStandardOutput:theStdoutPipe];
157
158 handle->SetPipeStreams(new wxPipeInputStream(theStdoutPipe),
159 new wxPipeOutputStream(theStdinPipe),
160 new wxPipeInputStream(theStderrPipe) );
161 }
162
163 NSArray* theQuoteArguments =
164 [wxNSStringWithWxString(command) componentsSeparatedByString:@"\""];
165
166 NSMutableArray* theSeparatedArguments =
167 [NSMutableArray arrayWithCapacity:10];
168
169 for (unsigned i = 0; i < [theQuoteArguments count]; ++i)
170 {
171 [theSeparatedArguments addObjectsFromArray:
172 [[theQuoteArguments objectAtIndex:i] componentsSeparatedByString:@" "]
173 ];
174
175 if(++i < [theQuoteArguments count])
176 [theSeparatedArguments addObject:[theQuoteArguments objectAtIndex:i]];
177 }
178
179 [theTask setLaunchPath:[theSeparatedArguments objectAtIndex:0]];
180 [theTask setArguments:theSeparatedArguments];
181 [theTask launch];
182
183 if(sync & wxEXEC_ASYNC)
184 {
185 [[WX_GET_OBJC_CLASS(wxTaskHandler) alloc]init:handle
186 processIdentifier:[theTask processIdentifier]];
187
188 return 0;
189 }
190 else
191 {
192 [theTask waitUntilExit];
193
194 return [theTask terminationStatus];
195 }
196 }
197 #endif //0