Version:
~ [ 10.0 ] ~
** Warning: Cannot open xref database.
1
2 /* $Id: CallMachOFrameWork.c,v 1.7 2005/01/15 16:43:10 andreradke Exp $ */
3
4 /******************************************************************************
5
6 UserLand Frontier(tm) -- High performance Web content management,
7 object database, system-level and Internet scripting environment,
8 including source code editing and debugging.
9
10 Copyright (C) 1992-2004 UserLand Software, Inc.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26 ******************************************************************************/
27
28 #include "frontier.h"
29 #include "standard.h"
30
31 #include "CallMachOFrameWork.h"
32 #include "memory.h"
33
34
35 /*System.framework functions: popen, pclose, and fread.*/
36
37 typedef FILE* (*popenptr) (const char* command, const char *type);
38 typedef int (*pcloseptr) (FILE* f);
39 typedef size_t (*freadptr) (void *ptr, size_t size, size_t nobj, FILE* f);
40
41 static popenptr popenfunc;
42 static pcloseptr pclosefunc;
43 static freadptr freadfunc;
44
45 static boolean unixshellcallinited = false;
46 static CFBundleRef sysBundle = nil;
47
48
49 static boolean unixshellcallinit (void); /* forward declaration */
50
51
52 boolean unixshellcall (Handle hcommand, Handle hreturn) {
53
54 /*
55 7.0b51: Call the UNIX popen command, which evaluates a string as if it were typed
56 on the command line. Verb: sys.unixShellCommand.
57 Code adapted by Timothy Paustian from Apple sample code.
58 This routine by PBS.
59 */
60
61 FILE *f;
62 char buf [256];
63 long ct = 0;
64
65 if (!unixshellcallinit ())
66 return (false);
67
68 if (!enlargehandle (hcommand, 1, "\0"))
69 return (false);
70
71 lockhandle (hcommand);
72
73 f = popenfunc (*hcommand, "r"); /*popen*/
74
75 unlockhandle (hcommand);
76
77 while (true) {
78
79 ct = freadfunc (buf, 1, sizeof buf, f); /*fread*/
80
81 if (ct > 0)
82 if (!insertinhandle (hreturn, gethandlesize (hreturn), buf, ct))
83 break;
84
85 if (ct < sizeof (buf))
86 break;
87 } /*while*/
88
89 pclosefunc (f); /*pclose*/
90
91 return (true);
92 } /*unixshellcall*/
93
94
95 static boolean unixshellcallinit (void) {
96
97 /*
98 7.0b51 PBS: load the bundle and get the function pointers the first time called.
99 */
100
101 if (unixshellcallinited) /*already inited*/
102 return (true);
103
104 if (sysBundle == nil)
105 if (LoadFrameworkBundle (CFSTR ("System.framework"), &sysBundle) != noErr)
106 return (false);
107
108 popenfunc = (popenptr) CFBundleGetFunctionPointerForName (sysBundle, CFSTR ("popen"));
109
110 if (popenfunc == nil)
111 return (false);
112
113 freadfunc = (freadptr) CFBundleGetFunctionPointerForName (sysBundle, CFSTR ("fread"));
114
115 if (freadfunc == nil)
116 return (false);
117
118 pclosefunc = (pcloseptr) CFBundleGetFunctionPointerForName (sysBundle, CFSTR ("pclose"));
119
120 if (pclosefunc == nil)
121 return (false);
122
123 unixshellcallinited = true;
124
125 return (true);
126 } /*unixshellcallinit*/
127
128
129 OSStatus LoadFrameworkBundle(CFStringRef framework, CFBundleRef *bundlePtr) /*Adapted from Apple sample code*/
130 {
131 OSStatus err;
132 FSRef frameworksFolderRef;
133 CFURLRef baseURL;
134 CFURLRef bundleURL;
135
136 assert(bundlePtr != nil);
137
138 *bundlePtr = nil;
139
140 baseURL = nil;
141 bundleURL = nil;
142
143 err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef);
144 if (err == noErr) {
145 baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef);
146 if (baseURL == nil) {
147 err = coreFoundationUnknownErr;
148 }
149 }
150 if (err == noErr) {
151 bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, framework, false);
152 if (bundleURL == nil) {
153 err = coreFoundationUnknownErr;
154 }
155 }
156 if (err == noErr) {
157 *bundlePtr = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL);
158 if (*bundlePtr == nil) {
159 err = coreFoundationUnknownErr;
160 }
161 }
162 if (err == noErr) {
163 if ( ! CFBundleLoadExecutable( *bundlePtr ) ) {
164 err = coreFoundationUnknownErr;
165 }
166 }
167
168 // Clean up.
169
170 if (err != noErr && *bundlePtr != nil) {
171 CFRelease(*bundlePtr);
172 *bundlePtr = nil;
173 }
174 if (bundleURL != nil) {
175 CFRelease(bundleURL);
176 }
177 if (baseURL != nil) {
178 CFRelease(baseURL);
179 }
180
181 return err;
182 } /*LoadFrameworkBundle*/
183
184
185 void *getframeworkfuncptr (CFStringRef framework, CFStringRef functionname) {
186
187 /*
188 2005-01-15 aradke: give us the name of a framework and the name of a function
189 in the framework and we will retrieve a callable pointer to that function.
190 */
191
192 CFBundleRef bundlePtr;
193
194 if (LoadFrameworkBundle (framework, &bundlePtr) != noErr)
195 return (nil);
196
197 return (CFBundleGetFunctionPointerForName (bundlePtr, functionname));
198 } /*getframeworkfuncptr*/
199
200
201 static UInt32 gluetemplate[6] = {0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420};
202
203 void *convertcfmtomachofuncptr (void *cfmfp) {
204
205 /*
206 2004-11-28 aradke: adapted from Apple's CFM_MachO_CFM sample:
207
208 http://developer.apple.com/samplecode/CFM_MachO_CFM/CFM_MachO_CFM.html
209
210 allocate a block of cfm glue code with instructions for calling the CFM function.
211 the caller is responsible for disposal via disposemachofuncptr
212 */
213
214 UInt32 *mfp = (UInt32*) NewPtr (sizeof(gluetemplate));
215
216 mfp[0] = gluetemplate[0] | ((UInt32) cfmfp >> 16);
217 mfp[1] = gluetemplate[1] | ((UInt32) cfmfp & 0xFFFF);
218 mfp[2] = gluetemplate[2];
219 mfp[3] = gluetemplate[3];
220 mfp[4] = gluetemplate[4];
221 mfp[5] = gluetemplate[5];
222
223 MakeDataExecutable (mfp, sizeof(gluetemplate));
224
225 return ((void *) mfp);
226 } /*convertcfmtomachofuncptr*/
227
228
229 void disposemachofuncptr (void *mfp) {
230
231 if (mfp != nil)
232 DisposePtr (mfp);
233 } /*disposemachofuncptr*/
234
235
236 typedef struct tvectorstruct {
237 ProcPtr procaddr;
238 UInt32 toc;
239 } tvectorstruct, *tvectorptr;
240
241
242 void *convertmachotocfmfuncptr (void *mfp) {
243
244 /*
245 2004-11-28 aradke: allocate a fake TVector and set its procptr entry
246 to the mach procptr handed to us by the caller. the toc entry can
247 safely be set to nil since it's ignored in this context.
248 */
249
250 tvectorptr cfmfp = (tvectorptr) NewPtr (sizeof(tvectorstruct));
251
252 if (MemError() == noErr && cfmfp != nil) {
253
254 cfmfp->procaddr = (ProcPtr) mfp;
255 cfmfp->toc = 0; /*ignored*/
256 }
257
258 return ((void *) cfmfp);
259 } /*convertmachotocfmfuncptr*/
260
261
262 void disposecfmfuncptr (void *cfmfp) {
263
264 if (cfmfp != nil)
265 DisposePtr (cfmfp);
266 } /*disposecfmfuncptr*/
267
268
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.