Added IRIX compile fixes
[wxWidgets.git] / src / gtk1 / utilsgtk.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: utils.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Created: 01/02/97
6 // Id:
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11
12 //#ifdef __GNUG__
13 //#pragma implementation "utils.h"
14 //#endif
15
16 #include "wx/utils.h"
17 #include "wx/string.h"
18
19 #include <stdarg.h>
20 #include <dirent.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <sys/wait.h>
26 #include <pwd.h>
27 #include <errno.h>
28 #include <netdb.h>
29 #include <signal.h>
30
31 #ifdef __SVR4__
32 #include <sys/systeminfo.h>
33 #endif
34
35 //------------------------------------------------------------------------
36 // misc.
37 //------------------------------------------------------------------------
38
39 void wxBell(void)
40 {
41 gdk_beep();
42 };
43
44 void wxSleep(int nSecs)
45 {
46 sleep(nSecs);
47 };
48
49 int wxKill(long pid, int sig)
50 {
51 return kill(pid, sig);
52 };
53
54 void wxDisplaySize( int *width, int *height )
55 {
56 if (width) *width = gdk_screen_width();
57 if (height) *height = gdk_screen_height();
58 }
59
60 void wxGetMousePosition( int* x, int* y )
61 {
62 wxFAIL_MSG( "GetMousePosition not yet implemented" );
63 if (x) *x = 0;
64 if (y) *y = 0;
65 };
66
67 bool wxColourDisplay(void)
68 {
69 wxFAIL_MSG( "wxColourDisplay always returns TRUE" );
70 return TRUE;
71 }
72
73 int wxDisplayDepth(void)
74 {
75 wxFAIL_MSG( "wxDisplayDepth always returns 8" );
76 return 8;
77 }
78
79 //------------------------------------------------------------------------
80 // user and home routines
81 //------------------------------------------------------------------------
82
83 char* wxGetHomeDir( char *dest )
84 {
85 wxString tmp = wxGetUserHome( wxString() );
86 if (tmp.IsNull())
87 strcpy( wxBuffer, "/" );
88 else
89 strcpy( wxBuffer, tmp );
90 if (dest) strcpy( dest, WXSTRINGCAST tmp );
91 return wxBuffer;
92 };
93
94 char *wxGetUserHome( const wxString &user )
95 {
96 struct passwd *who = NULL;
97
98 if (user.IsNull() || (user== ""))
99 {
100 register char *ptr;
101
102 if ((ptr = getenv("HOME")) != NULL)
103 return ptr;
104 if ((ptr = getenv("USER")) != NULL
105 || (ptr = getenv("LOGNAME")) != NULL) {
106 who = getpwnam(ptr);
107 }
108 // We now make sure the the user exists!
109 if (who == NULL)
110 who = getpwuid(getuid());
111 }
112 else
113 who = getpwnam (user);
114
115 return who ? who->pw_dir : (char*)NULL;
116 };
117
118 //------------------------------------------------------------------------
119 // id routines
120 //------------------------------------------------------------------------
121
122 bool wxGetHostName(char *buf, int sz)
123 {
124 *buf = '\0';
125 #if defined(__SVR4__) && !defined(__sgi)
126 return (sysinfo(SI_HOSTNAME, buf, sz) != -1);
127 #else /* BSD Sockets */
128 char name[255];
129 struct hostent *h;
130 // Get hostname
131 if (gethostname(name, sizeof(name)/sizeof(char)-1) == -1)
132 return FALSE;
133 // Get official full name of host
134 strncpy(buf, (h=gethostbyname(name))!=NULL ? h->h_name : name, sz-1);
135 return TRUE;
136 #endif
137 }
138
139 bool wxGetUserId(char *buf, int sz)
140 {
141 struct passwd *who;
142
143 *buf = '\0';
144 if ((who = getpwuid(getuid ())) != NULL) {
145 strncpy (buf, who->pw_name, sz-1);
146 return TRUE;
147 }
148 return FALSE;
149 }
150
151 bool wxGetUserName(char *buf, int sz)
152 {
153 struct passwd *who;
154
155 *buf = '\0';
156 if ((who = getpwuid (getuid ())) != NULL) {
157 strncpy (buf, who->pw_gecos, sz - 1);
158 return TRUE;
159 }
160 return FALSE;
161 }
162
163 //------------------------------------------------------------------------
164 // error and debug output routines
165 //------------------------------------------------------------------------
166
167 void wxDebugMsg( const char *format, ... )
168 {
169 va_list ap;
170 va_start( ap, format );
171 vfprintf( stderr, format, ap );
172 fflush( stderr );
173 va_end(ap);
174 };
175
176 void wxError( const wxString &msg, const wxString &title )
177 {
178 fprintf( stderr, "Error " );
179 if (!title.IsNull()) fprintf( stderr, "%s ", WXSTRINGCAST(title) );
180 if (!msg.IsNull()) fprintf( stderr, ": %s", WXSTRINGCAST(msg) );
181 fprintf( stderr, ".\n" );
182 };
183
184 void wxFatalError( const wxString &msg, const wxString &title )
185 {
186 fprintf( stderr, "Error " );
187 if (!title.IsNull()) fprintf( stderr, "%s ", WXSTRINGCAST(title) );
188 if (!msg.IsNull()) fprintf( stderr, ": %s", WXSTRINGCAST(msg) );
189 fprintf( stderr, ".\n" );
190 exit(1);
191 };
192
193 //------------------------------------------------------------------------
194 // directory routines
195 //------------------------------------------------------------------------
196
197 bool wxDirExists( const wxString& dir )
198 {
199 char buf[500];
200 strcpy( buf, WXSTRINGCAST(dir) );
201 struct stat sbuf;
202 return ((stat(buf, &sbuf) != -1) && S_ISDIR(sbuf.st_mode) ? TRUE : FALSE);
203 };
204
205 //------------------------------------------------------------------------
206 // wild character routines
207 //------------------------------------------------------------------------
208
209 bool wxIsWild( const wxString& pattern )
210 {
211 wxString tmp = pattern;
212 char *pat = WXSTRINGCAST(tmp);
213 while (*pat) {
214 switch (*pat++) {
215 case '?': case '*': case '[': case '{':
216 return TRUE;
217 case '\\':
218 if (!*pat++)
219 return FALSE;
220 }
221 }
222 return FALSE;
223 };
224
225
226 bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
227 {
228 wxString tmp1 = pat;
229 char *pattern = WXSTRINGCAST(tmp1);
230 wxString tmp2 = text;
231 char *str = WXSTRINGCAST(tmp2);
232 char c;
233 char *cp;
234 bool done = FALSE, ret_code, ok;
235 // Below is for vi fans
236 const char OB = '{', CB = '}';
237
238 // dot_special means '.' only matches '.'
239 if (dot_special && *str == '.' && *pattern != *str)
240 return FALSE;
241
242 while ((*pattern != '\0') && (!done)
243 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
244 switch (*pattern) {
245 case '\\':
246 pattern++;
247 if (*pattern != '\0')
248 pattern++;
249 break;
250 case '*':
251 pattern++;
252 ret_code = FALSE;
253 while ((*str!='\0')
254 && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
255 /*loop*/;
256 if (ret_code) {
257 while (*str != '\0')
258 str++;
259 while (*pattern != '\0')
260 pattern++;
261 }
262 break;
263 case '[':
264 pattern++;
265 repeat:
266 if ((*pattern == '\0') || (*pattern == ']')) {
267 done = TRUE;
268 break;
269 }
270 if (*pattern == '\\') {
271 pattern++;
272 if (*pattern == '\0') {
273 done = TRUE;
274 break;
275 }
276 }
277 if (*(pattern + 1) == '-') {
278 c = *pattern;
279 pattern += 2;
280 if (*pattern == ']') {
281 done = TRUE;
282 break;
283 }
284 if (*pattern == '\\') {
285 pattern++;
286 if (*pattern == '\0') {
287 done = TRUE;
288 break;
289 }
290 }
291 if ((*str < c) || (*str > *pattern)) {
292 pattern++;
293 goto repeat;
294 }
295 } else if (*pattern != *str) {
296 pattern++;
297 goto repeat;
298 }
299 pattern++;
300 while ((*pattern != ']') && (*pattern != '\0')) {
301 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
302 pattern++;
303 pattern++;
304 }
305 if (*pattern != '\0') {
306 pattern++, str++;
307 }
308 break;
309 case '?':
310 pattern++;
311 str++;
312 break;
313 case OB:
314 pattern++;
315 while ((*pattern != CB) && (*pattern != '\0')) {
316 cp = str;
317 ok = TRUE;
318 while (ok && (*cp != '\0') && (*pattern != '\0')
319 && (*pattern != ',') && (*pattern != CB)) {
320 if (*pattern == '\\')
321 pattern++;
322 ok = (*pattern++ == *cp++);
323 }
324 if (*pattern == '\0') {
325 ok = FALSE;
326 done = TRUE;
327 break;
328 } else if (ok) {
329 str = cp;
330 while ((*pattern != CB) && (*pattern != '\0')) {
331 if (*++pattern == '\\') {
332 if (*++pattern == CB)
333 pattern++;
334 }
335 }
336 } else {
337 while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
338 if (*++pattern == '\\') {
339 if (*++pattern == CB || *pattern == ',')
340 pattern++;
341 }
342 }
343 }
344 if (*pattern != '\0')
345 pattern++;
346 }
347 break;
348 default:
349 if (*str == *pattern) {
350 str++, pattern++;
351 } else {
352 done = TRUE;
353 }
354 }
355 }
356 while (*pattern == '*')
357 pattern++;
358 return ((*str == '\0') && (*pattern == '\0'));
359 };
360
361 //------------------------------------------------------------------------
362 // subprocess routines
363 //------------------------------------------------------------------------
364
365 typedef struct {
366 gint pid, tag;
367 wxProcess *process;
368 } wxEndProcessData;
369
370 static void GTK_EndProcessDetector(gpointer data, gint source,
371 GdkInputCondition WXUNUSED(condition) )
372 {
373 wxEndProcessData *proc_data = (wxEndProcessData *)data;
374 int pid;
375
376 pid = (proc_data->pid > 0) ? proc_data->pid : -(proc_data->pid);
377
378 /* wait4 is not standard, use at own risk */
379 #if !defined(__sgi)
380 wait4(proc_data->pid, NULL, 0, NULL);
381 #else
382 wait3(NULL, 0, NULL);
383 #endif
384
385 close(source);
386 gdk_input_remove(proc_data->tag);
387
388 if (proc_data->process)
389 proc_data->process->OnTerminate(proc_data->pid);
390
391 if (proc_data->pid > 0)
392 delete proc_data;
393 else
394 proc_data->pid = 0;
395 };
396
397 long wxExecute( char **argv, bool sync, wxProcess *process )
398 {
399 wxEndProcessData *data = new wxEndProcessData;
400 int end_proc_detect[2];
401
402 if (*argv == NULL)
403 return 0;
404
405 /* Create pipes */
406 if (pipe(end_proc_detect) == -1) {
407 perror("pipe failed");
408 return 0;
409 }
410
411 /* fork the process */
412 #if defined(sun) || defined(__ultrix) || defined(__bsdi__)
413 pid_t pid = vfork();
414 #else
415 pid_t pid = fork();
416 #endif
417 if (pid == -1) {
418 perror ("fork failed");
419 return 0;
420 } else if (pid == 0) {
421 /* Close fd not useful */
422 close(end_proc_detect[0]); // close reading side
423
424 /* child */
425 #ifdef _AIX
426 execvp ((const char *)*argv, (const char **)argv);
427 #else
428 execvp (*argv, argv);
429 #endif
430 if (errno == ENOENT)
431 wxError("command not found", *argv);
432 else
433 perror (*argv);
434 wxError("could not execute", *argv);
435 _exit (-1);
436 }
437
438 close(end_proc_detect[1]); // close writing side
439 data->tag = gdk_input_add(end_proc_detect[0], GDK_INPUT_READ,
440 GTK_EndProcessDetector, (gpointer)data);
441 data->pid = pid;
442 if (!sync) {
443 data->process = process;
444 } else {
445 data->process = NULL;
446 data->pid = -(data->pid);
447
448 while (data->pid != 0)
449 wxYield();
450
451 delete data;
452 }
453
454 return pid;
455 };
456
457 long wxExecute( const wxString& command, bool sync, wxProcess *process )
458 {
459 if (command.IsNull() || command == "") return FALSE;
460
461 int argc = 0;
462 char *argv[127];
463 char tmp[1024];
464 const char *IFS = " \t\n";
465
466 strncpy (tmp, command, sizeof(tmp) / sizeof(char) - 1);
467 tmp[sizeof (tmp) / sizeof (char) - 1] = '\0';
468 argv[argc++] = strtok (tmp, IFS);
469 while ((argv[argc++] = strtok(NULL, IFS)) != NULL)
470 /* loop */ ;
471 return wxExecute(argv, sync, process);
472 };
473
474