]> git.saurik.com Git - wxWidgets.git/blame - src/cocoa/utilsexc.mm
1. Yet another unit test for new stirng stuff
[wxWidgets.git] / src / cocoa / utilsexc.mm
CommitLineData
dcb68102
RN
1/////////////////////////////////////////////////////////////////////////////
2// Name: 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/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation
14#endif
15
16#include "wx/utils.h"
17
18#include "wx/process.h"
19#include "wx/stream.h"
20
21#include "wx/cocoa/string.h"
22
23#import <Foundation/Foundation.h>
24#import <AppKit/NSWorkspace.h>
25
26class wxPipeInputStream : public wxInputStream
27{
28public:
29 wxPipeInputStream(NSPipe* thePipe) :
30 m_thePipe(thePipe),
31 m_theHandle([m_thePipe fileHandleForReading])
32 {
33 }
34
35 ~wxPipeInputStream()
36 {
37 [m_thePipe release];
38 }
39
40protected:
41 virtual size_t OnSysRead(void *buffer, size_t size)
42 {
43 NSData* theData = [m_theHandle readDataOfLength:size];
44 memcpy(buffer, [theData bytes], [theData length]);
45 return [theData length];
46 }
47
48
49 NSPipe* m_thePipe;
50 NSFileHandle* m_theHandle;
51};
52
53class wxPipeOutputStream : public wxOutputStream
54{
55public:
56 wxPipeOutputStream(NSPipe* thePipe) :
57 m_thePipe(thePipe),
58 m_theHandle([m_thePipe fileHandleForWriting])
59 {
60 }
61
62 ~wxPipeOutputStream()
63 {
64 [m_thePipe release];
65 }
66
67protected:
68
69 virtual size_t OnSysWrite(const void *buffer, size_t bufsize)
70 {
71 NSData* theData = [NSData dataWithBytesNoCopy:(void*)buffer
72 length:bufsize];
73 [m_theHandle writeData:theData];
74 return bufsize;
75 }
76
77 NSPipe* m_thePipe;
78 NSFileHandle* m_theHandle;
79};
80
81@interface wxTaskHandler : NSObject
82{
83 long m_pid;
84 void* m_handle;
85}
86-(id)init:(void*)handle processIdentifier:(long)pid;
87- (void)termHandler:(NSNotification *)aNotification;
88@end
89
90@implementation wxTaskHandler : NSObject
91
92-(id)init:(void*)handle processIdentifier:(long)pid
93{
94 self = [super init];
95
96 m_handle = handle;
97 m_pid = pid;
98
99 [[NSNotificationCenter defaultCenter] addObserver:self
100 selector:@selector(termHandler:)
101 name:NSTaskDidTerminateNotification
102 object:nil];
103 return self;
104}
105
106- (void)termHandler:(NSNotification *)aNotification
107{
108 NSTask* theTask = [aNotification object];
109
110 if ([theTask processIdentifier] == m_pid)
111 {
112 ((wxProcess*)m_handle)->OnTerminate([theTask processIdentifier],
113 [theTask terminationStatus]);
114
115 [self release];
116 }
117}
118
119@end
120
121long wxExecute(const wxString& command,
122 int sync = wxEXEC_ASYNC,
123 wxProcess *handle = NULL)
124{
125 NSTask* theTask = [[NSTask alloc] init];
126
127 if (handle && handle->IsRedirected())
128 {
129 NSPipe* theStdinPipe = [[NSPipe alloc] init];
130 NSPipe* theStderrPipe = [[NSPipe alloc] init];
131 NSPipe* theStdoutPipe = [[NSPipe alloc] init];
132
133 [theTask setStandardInput:theStdinPipe];
134 [theTask setStandardError:theStderrPipe];
135 [theTask setStandardOutput:theStdoutPipe];
136
137 handle->SetPipeStreams(new wxPipeInputStream(theStdoutPipe),
138 new wxPipeOutputStream(theStdinPipe),
139 new wxPipeInputStream(theStderrPipe) );
140 }
141
142 NSArray* theQuoteArguments =
143 [wxNSStringWithWxString(command) componentsSeparatedByString:@"\""];
144
145 NSMutableArray* theSeperatedArguments =
146 [NSMutableArray arrayWithCapacity:10];
147
148 for (unsigned i = 0; i < [theQuoteArguments count]; ++i)
149 {
150 [theSeperatedArguments addObjectsFromArray:
151 [[theQuoteArguments objectAtIndex:i] componentsSeparatedByString:@" "]
152 ];
153
154 if(++i < [theQuoteArguments count])
155 [theSeperatedArguments addObject:[theQuoteArguments objectAtIndex:i]];
156 }
157
158 [theTask setLaunchPath:[theSeperatedArguments objectAtIndex:0]];
159 [theTask setArguments:theSeperatedArguments];
160 [theTask launch];
161
162 if(sync & wxEXEC_ASYNC)
163 {
164 [[wxTaskHandler alloc]init:handle
165 processIdentifier:[theTask processIdentifier]];
166
167 return 0;
168 }
169 else
170 {
171 [theTask waitUntilExit];
172
173 return [theTask terminationStatus];
174 }
175}