aclocal.m4 (libiberty_AC_DECLARE_ERRNO): New macro.
[platform/upstream/gcc.git] / libiberty / pexecute.c
1 /* Utilities to execute a program in a subprocess (possibly linked by pipes
2    with other subprocesses), and wait for it.
3    Copyright (C) 1996-2000 Free Software Foundation, Inc.
4
5 This file is part of the libiberty library.
6 Libiberty is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 Libiberty is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with libiberty; see the file COPYING.LIB.  If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* This file exports two functions: pexecute and pwait.  */
22
23 /* This file lives in at least two places: libiberty and gcc.
24    Don't change one without the other.  */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <stdio.h>
31 #include <errno.h>
32 #ifdef NEED_DECLARATION_ERRNO
33 extern int errno;
34 #endif
35 #ifdef HAVE_STRING_H
36 #include <string.h>
37 #endif
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41 #ifdef HAVE_STDLIB_H
42 #include <stdlib.h>
43 #endif
44 #define ISSPACE (x) isspace(x)
45 #ifdef HAVE_SYS_WAIT_H
46 #include <sys/wait.h>
47 #endif
48
49 #ifdef vfork /* Autoconf may define this to fork for us. */
50 # define VFORK_STRING "fork"
51 #else
52 # define VFORK_STRING "vfork"
53 #endif
54 #ifdef HAVE_VFORK_H
55 #include <vfork.h>
56 #endif
57 #ifdef VMS
58 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
59                lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
60 #endif /* VMS */
61
62 #include "libiberty.h"
63
64 /* stdin file number.  */
65 #define STDIN_FILE_NO 0
66
67 /* stdout file number.  */
68 #define STDOUT_FILE_NO 1
69
70 /* value of `pipe': port index for reading.  */
71 #define READ_PORT 0
72
73 /* value of `pipe': port index for writing.  */
74 #define WRITE_PORT 1
75
76 static char *install_error_msg = "installation problem, cannot exec `%s'";
77
78 /* pexecute: execute a program.
79
80    PROGRAM and ARGV are the arguments to execv/execvp.
81
82    THIS_PNAME is name of the calling program (i.e. argv[0]).
83
84    TEMP_BASE is the path name, sans suffix, of a temporary file to use
85    if needed.  This is currently only needed for MSDOS ports that don't use
86    GO32 (do any still exist?).  Ports that don't need it can pass NULL.
87
88    (FLAGS & PEXECUTE_SEARCH) is non-zero if $PATH should be searched
89    (??? It's not clear that GCC passes this flag correctly).
90    (FLAGS & PEXECUTE_FIRST) is nonzero for the first process in chain.
91    (FLAGS & PEXECUTE_FIRST) is nonzero for the last process in chain.
92    FIRST_LAST could be simplified to only mark the last of a chain of processes
93    but that requires the caller to always mark the last one (and not give up
94    early if some error occurs).  It's more robust to require the caller to
95    mark both ends of the chain.
96
97    The result is the pid on systems like Unix where we fork/exec and on systems
98    like WIN32 and OS2 where we use spawn.  It is up to the caller to wait for
99    the child.
100
101    The result is the WEXITSTATUS on systems like MSDOS where we spawn and wait
102    for the child here.
103
104    Upon failure, ERRMSG_FMT and ERRMSG_ARG are set to the text of the error
105    message with an optional argument (if not needed, ERRMSG_ARG is set to
106    NULL), and -1 is returned.  `errno' is available to the caller to use.
107
108    pwait: cover function for wait.
109
110    PID is the process id of the task to wait for.
111    STATUS is the `status' argument to wait.
112    FLAGS is currently unused (allows future enhancement without breaking
113    upward compatibility).  Pass 0 for now.
114
115    The result is the pid of the child reaped,
116    or -1 for failure (errno says why).
117
118    On systems that don't support waiting for a particular child, PID is
119    ignored.  On systems like MSDOS that don't really multitask pwait
120    is just a mechanism to provide a consistent interface for the caller.
121
122    pfinish: finish generation of script
123
124    pfinish is necessary for systems like MPW where a script is generated that
125    runs the requested programs.
126 */
127
128 #ifdef __MSDOS__
129
130 /* MSDOS doesn't multitask, but for the sake of a consistent interface
131    the code behaves like it does.  pexecute runs the program, tucks the
132    exit code away, and returns a "pid".  pwait must be called to fetch the
133    exit code.  */
134
135 #include <process.h>
136
137 /* For communicating information from pexecute to pwait.  */
138 static int last_pid = 0;
139 static int last_status = 0;
140 static int last_reaped = 0;
141
142 int
143 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
144      const char *program;
145      char * const *argv;
146      const char *this_pname;
147      const char *temp_base;
148      char **errmsg_fmt, **errmsg_arg;
149      int flags;
150 {
151   int rc;
152
153   last_pid++;
154   if (last_pid < 0)
155     last_pid = 1;
156
157   if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
158     abort ();
159
160 #ifdef __GO32__
161   /* ??? What are the possible return values from spawnv?  */
162   rc = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
163 #else
164   char *scmd, *rf;
165   FILE *argfile;
166   int i, el = flags & PEXECUTE_SEARCH ? 4 : 0;
167
168   if (temp_base == 0)
169     temp_base = choose_temp_base ();
170   scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el);
171   rf = scmd + strlen(program) + 2 + el;
172   sprintf (scmd, "%s%s @%s.gp", program,
173            (flags & PEXECUTE_SEARCH ? ".exe" : ""), temp_base);
174   argfile = fopen (rf, "w");
175   if (argfile == 0)
176     {
177       int errno_save = errno;
178       free (scmd);
179       errno = errno_save;
180       *errmsg_fmt = "cannot open `%s.gp'";
181       *errmsg_arg = temp_base;
182       return -1;
183     }
184
185   for (i=1; argv[i]; i++)
186     {
187       char *cp;
188       for (cp = argv[i]; *cp; cp++)
189         {
190           if (*cp == '"' || *cp == '\'' || *cp == '\\' || ISSPACE (*cp))
191             fputc ('\\', argfile);
192           fputc (*cp, argfile);
193         }
194       fputc ('\n', argfile);
195     }
196   fclose (argfile);
197
198   rc = system (scmd);
199
200   {
201     int errno_save = errno;
202     remove (rf);
203     free (scmd);
204     errno = errno_save;
205   }
206 #endif
207
208   if (rc == -1)
209     {
210       *errmsg_fmt = install_error_msg;
211       *errmsg_arg = program;
212       return -1;
213     }
214
215   /* Tuck the status away for pwait, and return a "pid".  */
216   last_status = rc << 8;
217   return last_pid;
218 }
219
220 int
221 pwait (pid, status, flags)
222      int pid;
223      int *status;
224      int flags;
225 {
226   /* On MSDOS each pexecute must be followed by it's associated pwait.  */
227   if (pid != last_pid
228       /* Called twice for the same child?  */
229       || pid == last_reaped)
230     {
231       /* ??? ECHILD would be a better choice.  Can we use it here?  */
232       errno = EINVAL;
233       return -1;
234     }
235   /* ??? Here's an opportunity to canonicalize the values in STATUS.
236      Needed?  */
237   *status = last_status;
238   last_reaped = last_pid;
239   return last_pid;
240 }
241
242 #endif /* MSDOS */
243
244 #if defined (_WIN32) && ! defined (_UWIN)
245
246 #include <process.h>
247
248 #ifdef __CYGWIN__
249
250 #define fix_argv(argvec) (argvec)
251
252 extern int _spawnv ();
253 extern int _spawnvp ();
254
255 #else /* ! __CYGWIN__ */
256
257 /* This is a kludge to get around the Microsoft C spawn functions' propensity
258    to remove the outermost set of double quotes from all arguments.  */
259
260 const char * const *
261 fix_argv (argvec)
262      char **argvec;
263 {
264   int i;
265
266   for (i = 1; argvec[i] != 0; i++)
267     {
268       int len, j;
269       char *temp, *newtemp;
270
271       temp = argvec[i];
272       len = strlen (temp);
273       for (j = 0; j < len; j++)
274         {
275           if (temp[j] == '"')
276             {
277               newtemp = xmalloc (len + 2);
278               strncpy (newtemp, temp, j);
279               newtemp [j] = '\\';
280               strncpy (&newtemp [j+1], &temp [j], len-j);
281               newtemp [len+1] = 0;
282               temp = newtemp;
283               len++;
284               j++;
285             }
286         }
287
288         argvec[i] = temp;
289       }
290
291   for (i = 0; argvec[i] != 0; i++)
292     {
293       if (strpbrk (argvec[i], " \t"))
294         {
295           int len, trailing_backslash;
296           char *temp;
297
298           len = strlen (argvec[i]);
299           trailing_backslash = 0;
300
301           /* There is an added complication when an arg with embedded white
302              space ends in a backslash (such as in the case of -iprefix arg
303              passed to cpp). The resulting quoted strings gets misinterpreted
304              by the command interpreter -- it thinks that the ending quote
305              is escaped by the trailing backslash and things get confused. 
306              We handle this case by escaping the trailing backslash, provided
307              it was not escaped in the first place.  */
308           if (len > 1 
309               && argvec[i][len-1] == '\\' 
310               && argvec[i][len-2] != '\\')
311             {
312               trailing_backslash = 1;
313               ++len;                    /* to escape the final backslash. */
314             }
315
316           len += 2;                     /* and for the enclosing quotes. */
317
318           temp = xmalloc (len + 1);
319           temp[0] = '"';
320           strcpy (temp + 1, argvec[i]);
321           if (trailing_backslash)
322             temp[len-2] = '\\';
323           temp[len-1] = '"';
324           temp[len] = '\0';
325
326           argvec[i] = temp;
327         }
328     }
329
330   return (const char * const *) argvec;
331 }
332 #endif /* __CYGWIN__ */
333
334 #include <io.h>
335 #include <fcntl.h>
336 #include <signal.h>
337
338 /* mingw32 headers may not define the following.  */
339
340 #ifndef _P_WAIT
341 #  define _P_WAIT       0
342 #  define _P_NOWAIT     1
343 #  define _P_OVERLAY    2
344 #  define _P_NOWAITO    3
345 #  define _P_DETACH     4
346
347 #  define WAIT_CHILD    0
348 #  define WAIT_GRANDCHILD       1
349 #endif
350
351 /* Win32 supports pipes */
352 int
353 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
354      const char *program;
355      char * const *argv;
356      const char *this_pname;
357      const char *temp_base;
358      char **errmsg_fmt, **errmsg_arg;
359      int flags;
360 {
361   int pid;
362   int pdes[2], org_stdin, org_stdout;
363   int input_desc, output_desc;
364   int retries, sleep_interval;
365
366   /* Pipe waiting from last process, to be used as input for the next one.
367      Value is STDIN_FILE_NO if no pipe is waiting
368      (i.e. the next command is the first of a group).  */
369   static int last_pipe_input;
370
371   /* If this is the first process, initialize.  */
372   if (flags & PEXECUTE_FIRST)
373     last_pipe_input = STDIN_FILE_NO;
374
375   input_desc = last_pipe_input;
376
377   /* If this isn't the last process, make a pipe for its output,
378      and record it as waiting to be the input to the next process.  */
379   if (! (flags & PEXECUTE_LAST))
380     {
381       if (_pipe (pdes, 256, O_BINARY) < 0)
382         {
383           *errmsg_fmt = "pipe";
384           *errmsg_arg = NULL;
385           return -1;
386         }
387       output_desc = pdes[WRITE_PORT];
388       last_pipe_input = pdes[READ_PORT];
389     }
390   else
391     {
392       /* Last process.  */
393       output_desc = STDOUT_FILE_NO;
394       last_pipe_input = STDIN_FILE_NO;
395     }
396
397   if (input_desc != STDIN_FILE_NO)
398     {
399       org_stdin = dup (STDIN_FILE_NO);
400       dup2 (input_desc, STDIN_FILE_NO);
401       close (input_desc); 
402     }
403
404   if (output_desc != STDOUT_FILE_NO)
405     {
406       org_stdout = dup (STDOUT_FILE_NO);
407       dup2 (output_desc, STDOUT_FILE_NO);
408       close (output_desc);
409     }
410
411   pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
412     (_P_NOWAIT, program, fix_argv(argv));
413
414   if (input_desc != STDIN_FILE_NO)
415     {
416       dup2 (org_stdin, STDIN_FILE_NO);
417       close (org_stdin);
418     }
419
420   if (output_desc != STDOUT_FILE_NO)
421     {
422       dup2 (org_stdout, STDOUT_FILE_NO);
423       close (org_stdout);
424     }
425
426   if (pid == -1)
427     {
428       *errmsg_fmt = install_error_msg;
429       *errmsg_arg = program;
430       return -1;
431     }
432
433   return pid;
434 }
435
436 /* MS CRTDLL doesn't return enough information in status to decide if the
437    child exited due to a signal or not, rather it simply returns an
438    integer with the exit code of the child; eg., if the child exited with 
439    an abort() call and didn't have a handler for SIGABRT, it simply returns
440    with status = 3. We fix the status code to conform to the usual WIF*
441    macros. Note that WIFSIGNALED will never be true under CRTDLL. */
442
443 int
444 pwait (pid, status, flags)
445      int pid;
446      int *status;
447      int flags;
448 {
449 #ifdef __CYGWIN__
450   return wait (status);
451 #else
452   int termstat;
453
454   pid = _cwait (&termstat, pid, WAIT_CHILD);
455
456   /* ??? Here's an opportunity to canonicalize the values in STATUS.
457      Needed?  */
458
459   /* cwait returns the child process exit code in termstat.
460      A value of 3 indicates that the child caught a signal, but not
461      which one.  Since only SIGABRT, SIGFPE and SIGINT do anything, we
462      report SIGABRT.  */
463   if (termstat == 3)
464     *status = SIGABRT;
465   else
466     *status = (((termstat) & 0xff) << 8);
467
468   return pid;
469 #endif /* __CYGWIN__ */
470 }
471
472 #endif /* _WIN32 && ! _UWIN */
473
474 #ifdef OS2
475
476 /* ??? Does OS2 have process.h?  */
477 extern int spawnv ();
478 extern int spawnvp ();
479
480 int
481 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
482      const char *program;
483      char * const *argv;
484      const char *this_pname;
485      const char *temp_base;
486      char **errmsg_fmt, **errmsg_arg;
487      int flags;
488 {
489   int pid;
490
491   if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
492     abort ();
493   /* ??? Presumably 1 == _P_NOWAIT.  */
494   pid = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
495   if (pid == -1)
496     {
497       *errmsg_fmt = install_error_msg;
498       *errmsg_arg = program;
499       return -1;
500     }
501   return pid;
502 }
503
504 int
505 pwait (pid, status, flags)
506      int pid;
507      int *status;
508      int flags;
509 {
510   /* ??? Here's an opportunity to canonicalize the values in STATUS.
511      Needed?  */
512   int pid = wait (status);
513   return pid;
514 }
515
516 #endif /* OS2 */
517
518 #ifdef MPW
519
520 /* MPW pexecute doesn't actually run anything; instead, it writes out
521    script commands that, when run, will do the actual executing.
522
523    For example, in GCC's case, GCC will write out several script commands:
524
525    cpp ...
526    cc1 ...
527    as ...
528    ld ...
529
530    and then exit.  None of the above programs will have run yet.  The task
531    that called GCC will then execute the script and cause cpp,etc. to run.
532    The caller must invoke pfinish before calling exit.  This adds
533    the finishing touches to the generated script.  */
534
535 static int first_time = 1;
536
537 int
538 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
539      const char *program;
540      char * const *argv;
541      const char *this_pname;
542      const char *temp_base;
543      char **errmsg_fmt, **errmsg_arg;
544      int flags;
545 {
546   char tmpprogram[255];
547   char *cp, *tmpname;
548   int i;
549
550   mpwify_filename (program, tmpprogram);
551   if (first_time)
552     {
553       printf ("Set Failed 0\n");
554       first_time = 0;
555     }
556
557   fputs ("If {Failed} == 0\n", stdout);
558   /* If being verbose, output a copy of the command.  It should be
559      accurate enough and escaped enough to be "clickable".  */
560   if (flags & PEXECUTE_VERBOSE)
561     {
562       fputs ("\tEcho ", stdout);
563       fputc ('\'', stdout);
564       fputs (tmpprogram, stdout);
565       fputc ('\'', stdout);
566       fputc (' ', stdout);
567       for (i=1; argv[i]; i++)
568         {
569           fputc ('\'', stdout);
570           /* See if we have an argument that needs fixing.  */
571           if (strchr(argv[i], '/'))
572             {
573               tmpname = (char *) xmalloc (256);
574               mpwify_filename (argv[i], tmpname);
575               argv[i] = tmpname;
576             }
577           for (cp = argv[i]; *cp; cp++)
578             {
579               /* Write an Option-d escape char in front of special chars.  */
580               if (strchr("'+", *cp))
581                 fputc ('\266', stdout);
582               fputc (*cp, stdout);
583             }
584           fputc ('\'', stdout);
585           fputc (' ', stdout);
586         }
587       fputs ("\n", stdout);
588     }
589   fputs ("\t", stdout);
590   fputs (tmpprogram, stdout);
591   fputc (' ', stdout);
592
593   for (i=1; argv[i]; i++)
594     {
595       /* See if we have an argument that needs fixing.  */
596       if (strchr(argv[i], '/'))
597         {
598           tmpname = (char *) xmalloc (256);
599           mpwify_filename (argv[i], tmpname);
600           argv[i] = tmpname;
601         }
602       if (strchr (argv[i], ' '))
603         fputc ('\'', stdout);
604       for (cp = argv[i]; *cp; cp++)
605         {
606           /* Write an Option-d escape char in front of special chars.  */
607           if (strchr("'+", *cp))
608             fputc ('\266', stdout);
609           fputc (*cp, stdout);
610         }
611       if (strchr (argv[i], ' '))
612         fputc ('\'', stdout);
613       fputc (' ', stdout);
614     }
615
616   fputs ("\n", stdout);
617
618   /* Output commands that arrange to clean up and exit if a failure occurs.
619      We have to be careful to collect the status from the program that was
620      run, rather than some other script command.  Also, we don't exit
621      immediately, since necessary cleanups are at the end of the script.  */
622   fputs ("\tSet TmpStatus {Status}\n", stdout);
623   fputs ("\tIf {TmpStatus} != 0\n", stdout);
624   fputs ("\t\tSet Failed {TmpStatus}\n", stdout);
625   fputs ("\tEnd\n", stdout);
626   fputs ("End\n", stdout);
627
628   /* We're just composing a script, can't fail here.  */
629   return 0;
630 }
631
632 int
633 pwait (pid, status, flags)
634      int pid;
635      int *status;
636      int flags;
637 {
638   *status = 0;
639   return 0;
640 }
641
642 /* Write out commands that will exit with the correct error code
643    if something in the script failed.  */
644
645 void
646 pfinish ()
647 {
648   printf ("\tExit \"{Failed}\"\n");
649 }
650
651 #endif /* MPW */
652
653 /* include for Unix-like environments but not for Dos-like environments */
654 #if ! defined (__MSDOS__) && ! defined (OS2) && ! defined (MPW) \
655     && ! (defined (_WIN32) && ! defined (_UWIN))
656
657 extern int execv ();
658 extern int execvp ();
659
660 int
661 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
662      const char *program;
663      char * const *argv;
664      const char *this_pname;
665      const char *temp_base ATTRIBUTE_UNUSED;
666      char **errmsg_fmt, **errmsg_arg;
667      int flags;
668 {
669   int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
670   int pid;
671   int pdes[2];
672   int input_desc, output_desc;
673   int retries, sleep_interval;
674   /* Pipe waiting from last process, to be used as input for the next one.
675      Value is STDIN_FILE_NO if no pipe is waiting
676      (i.e. the next command is the first of a group).  */
677   static int last_pipe_input;
678
679   /* If this is the first process, initialize.  */
680   if (flags & PEXECUTE_FIRST)
681     last_pipe_input = STDIN_FILE_NO;
682
683   input_desc = last_pipe_input;
684
685   /* If this isn't the last process, make a pipe for its output,
686      and record it as waiting to be the input to the next process.  */
687   if (! (flags & PEXECUTE_LAST))
688     {
689       if (pipe (pdes) < 0)
690         {
691           *errmsg_fmt = "pipe";
692           *errmsg_arg = NULL;
693           return -1;
694         }
695       output_desc = pdes[WRITE_PORT];
696       last_pipe_input = pdes[READ_PORT];
697     }
698   else
699     {
700       /* Last process.  */
701       output_desc = STDOUT_FILE_NO;
702       last_pipe_input = STDIN_FILE_NO;
703     }
704
705   /* Fork a subprocess; wait and retry if it fails.  */
706   sleep_interval = 1;
707   for (retries = 0; retries < 4; retries++)
708     {
709       pid = vfork ();
710       if (pid >= 0)
711         break;
712       sleep (sleep_interval);
713       sleep_interval *= 2;
714     }
715
716   switch (pid)
717     {
718     case -1:
719       {
720         *errmsg_fmt = VFORK_STRING;
721         *errmsg_arg = NULL;
722         return -1;
723       }
724
725     case 0: /* child */
726       /* Move the input and output pipes into place, if necessary.  */
727       if (input_desc != STDIN_FILE_NO)
728         {
729           close (STDIN_FILE_NO);
730           dup (input_desc);
731           close (input_desc);
732         }
733       if (output_desc != STDOUT_FILE_NO)
734         {
735           close (STDOUT_FILE_NO);
736           dup (output_desc);
737           close (output_desc);
738         }
739
740       /* Close the parent's descs that aren't wanted here.  */
741       if (last_pipe_input != STDIN_FILE_NO)
742         close (last_pipe_input);
743
744       /* Exec the program.  */
745       (*func) (program, argv);
746
747       /* Note: Calling fprintf and exit here doesn't seem right for vfork.  */
748       fprintf (stderr, "%s: ", this_pname);
749       fprintf (stderr, install_error_msg, program);
750       fprintf (stderr, ": %s\n", xstrerror (errno));
751       exit (-1);
752       /* NOTREACHED */
753       return 0;
754
755     default:
756       /* In the parent, after forking.
757          Close the descriptors that we made for this child.  */
758       if (input_desc != STDIN_FILE_NO)
759         close (input_desc);
760       if (output_desc != STDOUT_FILE_NO)
761         close (output_desc);
762
763       /* Return child's process number.  */
764       return pid;
765     }
766 }
767
768 int
769 pwait (pid, status, flags)
770      int pid;
771      int *status;
772      int flags ATTRIBUTE_UNUSED;
773 {
774   /* ??? Here's an opportunity to canonicalize the values in STATUS.
775      Needed?  */
776 #ifdef VMS
777   pid = waitpid (-1, status, 0);
778 #else
779   pid = wait (status);
780 #endif
781   return pid;
782 }
783
784 #endif /* ! __MSDOS__ && ! OS2 && ! MPW && ! (_WIN32 && ! _UWIN) */