]> git.saurik.com Git - wxWidgets.git/blob - src/motif/utilsexc.cpp
* Fixes.
[wxWidgets.git] / src / motif / utilsexc.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: utilsexec.cpp
3 // Purpose: Execution-related utilities
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 // #pragma implementation
14 #endif
15
16 #include "wx/utils.h"
17 #include "wx/app.h"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #ifdef VMS
24 /*steve*/
25 #ifdef __HIDE_FORBIDDEN_NAMES
26 #undefine __HIDE_FORBIDDEN_NAMES
27 #endif
28 #include <socket.h>
29 #ifdef VAX
30 /*because 'noshare' is not valid in vax C++*/
31 #define CC$VAXCSHR 1
32 #endif
33 #include <unixlib.h>
34 #define unlink DELETE
35
36 #else
37
38 #if defined(_AIX) || defined(__xlC__)
39 #include <sys/socket.h>
40 #include <sys/select.h>
41 #else
42 #ifndef DG
43 #include <sys/syscall.h>
44 #endif
45 #endif
46
47 #include <sys/wait.h>
48 #include <unistd.h>
49 #include <dirent.h>
50 #include <pwd.h>
51
52 #endif
53
54 #include <sys/time.h>
55
56 #include <Xm/Xm.h>
57
58 struct wxLocalProcessData
59 {
60 int pid, end_process;
61 wxProcess *process;
62 };
63
64 #ifdef __SOLARIS__
65 // somehow missing from sys/wait.h but in the system's docs
66 extern "C"
67 {
68 pid_t wait4(pid_t pid, int *statusp, int options, struct rusage
69 *rusage);
70 }
71 #endif
72
73 void xt_notify_end_process(XtPointer client, int *fid,
74 XtInputId *id)
75 {
76 wxLocalProcessData *process_data = (wxLocalProcessData *)client;
77
78 int pid;
79
80 pid = (process_data->pid > 0) ? process_data->pid : -(process_data->pid);
81
82 /* wait4 is not part of any standard, use at own risk
83 * not sure what wait4 does, but wait3 seems to be closest, whats a digit ;-)
84 * --- offer@sgi.com */
85 #if !defined(__sgi)
86 wait4(process_data->pid, NULL, 0, NULL);
87 #else
88 wait3((int *) NULL, 0, (rusage *) NULL);
89 #endif
90
91 XtRemoveInput(*id);
92 if (process_data->process)
93 process_data->process->OnTerminate(process_data->pid);
94
95 process_data->end_process = TRUE;
96
97 if (process_data->pid > 0)
98 delete process_data;
99 else
100 process_data->pid = 0;
101 }
102
103 long wxExecute(char **argv, bool sync, wxProcess *handler)
104 {
105 #ifdef VMS
106 return(0);
107 #else
108 if (*argv == NULL)
109 return 0; // Nothing???
110
111 int proc_link[2];
112 if (pipe(proc_link))
113 return 0;
114
115 /* fork the process */
116 #if defined(sun) || defined(__ultrix) || defined(__bsdi__)
117 pid_t pid = vfork ();
118 #else
119 pid_t pid = fork ();
120 #endif
121
122 if (pid == -1)
123 {
124 return 0;
125 }
126 else if (pid == 0)
127 {
128 /* GUILHEM: Close all fds when sync == 0 */
129 if (sync == 0)
130 for (int fd=0;fd<FD_SETSIZE;fd++) {
131 if (proc_link[1] != fd)
132 close(fd);
133 }
134 /* child */
135 #ifdef _AIX
136 execvp ((const char *)*argv, (const char **)argv);
137 #else
138 execvp (*argv, argv);
139 #endif
140 /* GUILHEM: Reopen output stream */
141 // open("/dev/console", O_WRONLY);
142 /* GUILHEM: End */
143 if (errno == ENOENT)
144 printf ("%s: command not found\n", *argv);
145 else
146 perror (*argv);
147 printf ("wxWindows: could not execute '%s'\n", *argv);
148 _exit (-1);
149 }
150
151 wxLocalProcessData *process_data = new wxLocalProcessData;
152
153 process_data->end_process = 0;
154 process_data->process = handler;
155 process_data->pid = (sync) ? pid : -pid;
156
157 close(proc_link[1]);
158 XtAppAddInput((XtAppContext) wxTheApp->GetAppContext(), proc_link[0],
159 (XtPointer *) XtInputReadMask,
160 (XtInputCallbackProc) xt_notify_end_process,
161 (XtPointer) process_data);
162
163 if (sync) {
164 while (!process_data->end_process)
165 XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
166
167 if (WIFEXITED(process_data->end_process) != 0)
168 return WEXITSTATUS(process_data->end_process);
169 }
170
171 delete process_data;
172
173 return pid;
174 #endif
175 // end VMS
176 }
177
178 long wxExecute (const wxString& command, bool sync, wxProcess* handler)
179 {
180 #ifdef VMS
181 return(0);
182 #else
183 if (command.IsNull() || command == "")
184 return 0; // Nothing to do
185
186 // Run a program the recomended way under X (XView)
187 int argc = 0;
188 char *argv[127];
189 char tmp[1024];
190 const char *IFS = " \t\n";
191
192 // Build argument vector
193 strncpy (tmp, (const char*) command, sizeof (tmp) / sizeof (char) - 1);
194 tmp[sizeof (tmp) / sizeof (char) - 1] = '\0';
195 argv[argc++] = strtok (tmp, IFS);
196 while ((argv[argc++] = strtok (NULL, IFS)) != NULL)
197 /* loop */ ;
198
199 return wxExecute(argv, sync, handler);
200 #endif
201 // VMS
202 }