]> git.saurik.com Git - wxWidgets.git/blame - src/mac/corefoundation/utilsexc_cf.cpp
Now works when derived from wxTextCtrlBase, using wxScrollHelper.
[wxWidgets.git] / src / mac / corefoundation / utilsexc_cf.cpp
CommitLineData
5d553c56
DE
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/mac/corefoundation/utilsexec_cf.cpp
3// Purpose: Execution-related utilities for Darwin
62705a27 4// Author: David Elliott, Ryan Norton (wxMacExecute)
5d553c56
DE
5// Modified by: Stefan Csomor (added necessary wxT for unicode builds)
6// Created: 2004-11-04
7// RCS-ID: $Id$
62705a27 8// Copyright: (c) David Elliott, Ryan Norton
24498521 9// Licence: wxWindows licence
5d553c56
DE
10// Notes: This code comes from src/mac/carbon/utilsexc.cpp,1.11
11/////////////////////////////////////////////////////////////////////////////
12
13#include "wx/wxprec.h"
14#ifndef WX_PRECOMP
15 #include "wx/log.h"
16 #include "wx/utils.h"
17#endif //ndef WX_PRECOMP
18#include "wx/unix/execute.h"
fc480dc1
DE
19#include "wx/stdpaths.h"
20#include "wx/apptrait.h"
5d553c56 21
62705a27
RN
22
23
5d553c56
DE
24#include <CoreFoundation/CFMachPort.h>
25#include <sys/wait.h>
26extern "C" {
27#include <mach/mach.h>
28}
29
30void wxMAC_MachPortEndProcessDetect(CFMachPortRef port, void *data)
31{
24498521 32 wxEndProcessData *proc_data = (wxEndProcessData*)data;
3bdb628b 33 wxLogDebug(wxT("Process ended"));
24498521
DE
34 int status = 0;
35 int rc = waitpid(abs(proc_data->pid), &status, WNOHANG);
36 if(!rc)
37 {
38 wxLogDebug(wxT("Mach port was invalidated, but process hasn't terminated!"));
39 return;
40 }
41 if((rc != -1) && WIFEXITED(status))
42 proc_data->exitcode = WEXITSTATUS(status);
43 else
44 proc_data->exitcode = -1;
45 wxHandleProcessTermination(proc_data);
5d553c56
DE
46}
47
48int wxAddProcessCallbackForPid(wxEndProcessData *proc_data, int pid)
49{
50 if(pid < 1)
51 return -1;
52 kern_return_t kernResult;
53 mach_port_t taskOfOurProcess;
54 mach_port_t machPortForProcess;
55 taskOfOurProcess = mach_task_self();
56 if(taskOfOurProcess == MACH_PORT_NULL)
57 {
58 wxLogDebug(wxT("No mach_task_self()"));
59 return -1;
60 }
61 wxLogDebug(wxT("pid=%d"),pid);
62 kernResult = task_for_pid(taskOfOurProcess,pid, &machPortForProcess);
63 if(kernResult != KERN_SUCCESS)
64 {
65 wxLogDebug(wxT("no task_for_pid()"));
66 // try seeing if it is already dead or something
67 // FIXME: a better method would be to call the callback function
68 // from idle time until the process terminates. Of course, how
69 // likely is it that it will take more than 0.1 seconds for the
70 // mach terminate event to make its way to the BSD subsystem?
71 usleep(100); // sleep for 0.1 seconds
72 wxMAC_MachPortEndProcessDetect(NULL, (void*)proc_data);
73 return -1;
74 }
75 CFMachPortContext termcb_contextinfo;
b409fa19 76 termcb_contextinfo.version = 0;
5d553c56
DE
77 termcb_contextinfo.info = (void*)proc_data;
78 termcb_contextinfo.retain = NULL;
79 termcb_contextinfo.release = NULL;
80 termcb_contextinfo.copyDescription = NULL;
81 CFMachPortRef CFMachPortForProcess;
82 Boolean ShouldFreePort;
83 CFMachPortForProcess = CFMachPortCreateWithPort(NULL, machPortForProcess, NULL, &termcb_contextinfo, &ShouldFreePort);
84 if(!CFMachPortForProcess)
85 {
86 wxLogDebug(wxT("No CFMachPortForProcess"));
87 mach_port_deallocate(taskOfOurProcess, machPortForProcess);
88 return -1;
89 }
90 if(ShouldFreePort)
91 {
92 kernResult = mach_port_deallocate(taskOfOurProcess, machPortForProcess);
93 if(kernResult!=KERN_SUCCESS)
94 {
95 wxLogDebug(wxT("Couldn't deallocate mach port"));
96 return -1;
97 }
98 }
99 CFMachPortSetInvalidationCallBack(CFMachPortForProcess, &wxMAC_MachPortEndProcessDetect);
100 CFRunLoopSourceRef runloopsource;
101 runloopsource = CFMachPortCreateRunLoopSource(NULL,CFMachPortForProcess, (CFIndex)0);
102 if(!runloopsource)
103 {
104 wxLogDebug(wxT("Couldn't create runloopsource"));
105 return -1;
106 }
107
108 CFRelease(CFMachPortForProcess);
109
110 CFRunLoopAddSource(CFRunLoopGetCurrent(),runloopsource,kCFRunLoopDefaultMode);
111 CFRelease(runloopsource);
112 wxLogDebug(wxT("Successfully added notification to the runloop"));
113 return 0;
114}
115
fc480dc1
DE
116// NOTE: This doens't really belong here but this was a handy file to
117// put it in because it's already compiled for wxCocoa and wxMac GUI lib.
118static wxStandardPathsCF gs_stdPaths;
119wxStandardPathsBase& wxGUIAppTraits::GetStandardPaths()
120{
121 return gs_stdPaths;
122}
123