1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Execution-related utilities for wxCocoa
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation
18 #include "wx/process.h"
19 #include "wx/stream.h"
21 #include "wx/cocoa/string.h"
23 #import <Foundation/Foundation.h>
24 #import <AppKit/NSWorkspace.h>
26 class wxPipeInputStream : public wxInputStream
29 wxPipeInputStream(NSPipe* thePipe) :
31 m_theHandle([m_thePipe fileHandleForReading])
41 virtual size_t OnSysRead(void *buffer, size_t size)
43 NSData* theData = [m_theHandle readDataOfLength:size];
44 memcpy(buffer, [theData bytes], [theData length]);
45 return [theData length];
50 NSFileHandle* m_theHandle;
53 class wxPipeOutputStream : public wxOutputStream
56 wxPipeOutputStream(NSPipe* thePipe) :
58 m_theHandle([m_thePipe fileHandleForWriting])
69 virtual size_t OnSysWrite(const void *buffer, size_t bufsize)
71 NSData* theData = [NSData dataWithBytesNoCopy:(void*)buffer
73 [m_theHandle writeData:theData];
78 NSFileHandle* m_theHandle;
81 @interface wxTaskHandler : NSObject
86 -(id)init:(void*)handle processIdentifier:(long)pid;
87 - (void)termHandler:(NSNotification *)aNotification;
90 @implementation wxTaskHandler : NSObject
92 -(id)init:(void*)handle processIdentifier:(long)pid
99 [[NSNotificationCenter defaultCenter] addObserver:self
100 selector:@selector(termHandler:)
101 name:NSTaskDidTerminateNotification
106 - (void)termHandler:(NSNotification *)aNotification
108 NSTask* theTask = [aNotification object];
110 if ([theTask processIdentifier] == m_pid)
112 ((wxProcess*)m_handle)->OnTerminate([theTask processIdentifier],
113 [theTask terminationStatus]);
121 long wxExecute(const wxString& command,
122 int sync = wxEXEC_ASYNC,
123 wxProcess *handle = NULL)
125 NSTask* theTask = [[NSTask alloc] init];
127 if (handle && handle->IsRedirected())
129 NSPipe* theStdinPipe = [[NSPipe alloc] init];
130 NSPipe* theStderrPipe = [[NSPipe alloc] init];
131 NSPipe* theStdoutPipe = [[NSPipe alloc] init];
133 [theTask setStandardInput:theStdinPipe];
134 [theTask setStandardError:theStderrPipe];
135 [theTask setStandardOutput:theStdoutPipe];
137 handle->SetPipeStreams(new wxPipeInputStream(theStdoutPipe),
138 new wxPipeOutputStream(theStdinPipe),
139 new wxPipeInputStream(theStderrPipe) );
142 NSArray* theQuoteArguments =
143 [wxNSStringWithWxString(command) componentsSeparatedByString:@"\""];
145 NSMutableArray* theSeperatedArguments =
146 [NSMutableArray arrayWithCapacity:10];
148 for (unsigned i = 0; i < [theQuoteArguments count]; ++i)
150 [theSeperatedArguments addObjectsFromArray:
151 [[theQuoteArguments objectAtIndex:i] componentsSeparatedByString:@" "]
154 if(++i < [theQuoteArguments count])
155 [theSeperatedArguments addObject:[theQuoteArguments objectAtIndex:i]];
158 [theTask setLaunchPath:[theSeperatedArguments objectAtIndex:0]];
159 [theTask setArguments:theSeperatedArguments];
162 if(sync & wxEXEC_ASYNC)
164 [[wxTaskHandler alloc]init:handle
165 processIdentifier:[theTask processIdentifier]];
171 [theTask waitUntilExit];
173 return [theTask terminationStatus];