]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/utilsexc.mm
Verified and applied [ 1042133 ] GTK2.0: DrawRotatedText dumb implementation
[wxWidgets.git] / src / cocoa / utilsexc.mm
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
26 class wxPipeInputStream : public wxInputStream
27 {
28 public:
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
40 protected:
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
53 class wxPipeOutputStream : public wxOutputStream
54 {
55 public:
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
67 protected:
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
121 long 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 }