]> git.saurik.com Git - wxWidgets.git/blob - src/motif/utilsexc.cpp
compilation 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 #include "wx/process.h"
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24
25 #ifdef VMS
26 /*steve*/
27 #ifdef __HIDE_FORBIDDEN_NAMES
28 #undefine __HIDE_FORBIDDEN_NAMES
29 #endif
30 #include <socket.h>
31 #ifdef VAX
32 /*because 'noshare' is not valid in vax C++*/
33 #define CC$VAXCSHR 1
34 #endif
35 #include <unixlib.h>
36 #define unlink DELETE
37
38 #else
39
40 #if defined(__AIX__) || defined(__xlC__)
41 #include <sys/socket.h>
42 #include <sys/select.h>
43 #else
44 #ifndef __DATA_GENERAL__
45 #include <sys/syscall.h>
46 #endif
47 #endif
48
49 #include <sys/wait.h>
50 #include <unistd.h>
51 #include <dirent.h>
52 #include <pwd.h>
53
54 #endif
55
56 #ifdef __SVR4__
57 #include <sys/systeminfo.h>
58 #endif
59
60 #ifdef __SOLARIS__
61 // somehow missing from sys/wait.h but in the system's docs
62 extern "C"
63 {
64 pid_t wait4(pid_t pid, int *statusp, int options, struct rusage
65 *rusage);
66 }
67 #endif
68
69 #include <sys/time.h>
70 #include <errno.h>
71
72 #include <Xm/Xm.h>
73
74 struct wxLocalProcessData
75 {
76 int pid, end_process;
77 wxProcess *process;
78 };
79
80 #ifdef __SOLARIS__
81 // somehow missing from sys/wait.h but in the system's docs
82 extern "C"
83 {
84 pid_t wait4(pid_t pid, int *statusp, int options, struct rusage
85 *rusage);
86 }
87 #endif
88
89 void wxUsleep(unsigned long milliseconds)
90 {
91 #if defined(HAVE_NANOSLEEP)
92 timespec tmReq;
93 tmReq.tv_sec = milliseconds / 1000;
94 tmReq.tv_nsec = (milliseconds % 1000) * 1000 * 1000;
95
96 // we're not interested in remaining time nor in return value
97 (void)nanosleep(&tmReq, (timespec *)NULL);
98 #elif defined(HAVE_USLEEP)
99 // uncomment this if you feel brave or if you are sure that your version
100 // of Solaris has a safe usleep() function but please notice that usleep()
101 // is known to lead to crashes in MT programs in Solaris 2.[67] and is not
102 // documented as MT-Safe
103 #if defined(__SUN__) && defined(wxUSE_THREADS)
104 #error "usleep() cannot be used in MT programs under Solaris."
105 #endif // Sun
106
107 usleep(milliseconds * 1000); // usleep(3) wants microseconds
108 #else // !sleep function
109 #error "usleep() or nanosleep() function required for wxUsleep"
110 #endif // sleep function
111 }
112
113 void xt_notify_end_process(XtPointer client, int *fid,
114 XtInputId *id)
115 {
116 wxLocalProcessData *process_data = (wxLocalProcessData *)client;
117
118 int pid;
119
120 pid = (process_data->pid > 0) ? process_data->pid : -(process_data->pid);
121
122 /* wait4 is not part of any standard, use at own risk
123 * not sure what wait4 does, but wait3 seems to be closest, whats a digit ;-)
124 * --- offer@sgi.com */
125 #if !defined(__HPUX__) && !defined(__sgi) && !defined(__SGI__) && !defined(__ALPHA__) && !defined(__SUNCC__)
126 wait4(process_data->pid, NULL, 0, NULL);
127 #else
128 wait3((int *) NULL, 0, (rusage *) NULL);
129 #endif
130
131 XtRemoveInput(*id);
132 if (process_data->process)
133 process_data->process->OnTerminate(process_data->pid, 0); // What should 'status' be?
134
135 process_data->end_process = TRUE;
136 /*
137 if (process_data->pid > 0) // synchronous
138 delete process_data;
139 else
140 process_data->pid = 0;
141 */
142 delete process_data;
143 }
144
145 long wxExecute(char **argv, bool sync, wxProcess *handler)
146 {
147 #ifdef VMS
148 return(0);
149 #else
150 if (*argv == NULL)
151 return 0; // Nothing???
152
153 int proc_link[2];
154 if (pipe(proc_link))
155 return 0;
156
157 /* fork the process */
158 #if defined(sun) || defined(__ultrix) || defined(__bsdi__)
159 pid_t pid = vfork ();
160 #else
161 pid_t pid = fork ();
162 #endif
163
164 if (pid == -1)
165 {
166 return 0;
167 }
168 else if (pid == 0)
169 {
170 /* GUILHEM: Close all fds when sync == 0 */
171 if (sync == 0)
172 for (int fd=0;fd<FD_SETSIZE;fd++) {
173 if (proc_link[1] != fd)
174 close(fd);
175 }
176 /* child */
177 #ifdef _AIX
178 execvp ((const char *)*argv, (const char **)argv);
179 #else
180 execvp (*argv, argv);
181 #endif
182 /* GUILHEM: Reopen output stream */
183 // open("/dev/console", O_WRONLY);
184 /* GUILHEM: End */
185 if (errno == ENOENT)
186 printf ("%s: command not found\n", *argv);
187 else
188 perror (*argv);
189 printf ("wxWindows: could not execute '%s'\n", *argv);
190 _exit (-1);
191 }
192
193 wxLocalProcessData *process_data = new wxLocalProcessData;
194
195 process_data->end_process = 0;
196 process_data->process = handler;
197 process_data->pid = (sync) ? pid : -pid;
198
199 close(proc_link[1]);
200 XtAppAddInput((XtAppContext) wxTheApp->GetAppContext(), proc_link[0],
201 (XtPointer *) XtInputReadMask,
202 (XtInputCallbackProc) xt_notify_end_process,
203 (XtPointer) process_data);
204
205 if (sync)
206 {
207 while (!process_data->end_process)
208 XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
209
210 if (WIFEXITED(process_data->end_process) != 0)
211 {
212 return WEXITSTATUS(process_data->end_process);
213 }
214 }
215
216 return pid;
217 #endif
218 // end VMS
219 }
220
221 long wxExecute (const wxString& command, bool sync, wxProcess* handler)
222 {
223 #ifdef VMS
224 return(0);
225 #else
226 if (command.IsNull() || command == "")
227 return 0; // Nothing to do
228
229 // Run a program the recomended way under X (XView)
230 int argc = 0;
231 char *argv[127];
232 char tmp[1024];
233 const char *IFS = " \t\n";
234
235 // Build argument vector
236 strncpy (tmp, (const char*) command, sizeof (tmp) / sizeof (char) - 1);
237 tmp[sizeof (tmp) / sizeof (char) - 1] = '\0';
238 argv[argc++] = strtok (tmp, IFS);
239 while ((argv[argc++] = strtok (NULL, IFS)) != NULL)
240 /* loop */ ;
241
242 return wxExecute(argv, sync, handler);
243 #endif
244 // VMS
245 }