Fixed pack/unpack routines for WM_DDE_EXECUTE.
[wine] / library / port.c
1 /*
2  * Misc. functions for systems that don't have them
3  *
4  * Copyright 1996 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library 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  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #ifdef __BEOS__
25 #include <be/kernel/fs_info.h>
26 #include <be/kernel/OS.h>
27 #endif
28
29 #include <assert.h>
30 #include <ctype.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <sys/types.h>
36 #ifdef HAVE_SYS_INTTYPES_H
37 # include <sys/inttypes.h>
38 #endif
39 #ifdef HAVE_SYS_TIME_h
40 # include <sys/time.h>
41 #endif
42 #include <sys/stat.h>
43 #include <sys/ioctl.h>
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <termios.h>
47 #ifdef HAVE_SYS_MMAN_H
48 #include <sys/mman.h>
49 #endif
50 #ifdef HAVE_LIBIO_H
51 # include <libio.h>
52 #endif
53 #ifdef HAVE_SYSCALL_H
54 # include <syscall.h>
55 #endif
56 #ifdef HAVE_STDINT_H
57 # include <stdint.h>
58 #endif
59
60 /***********************************************************************
61  *              usleep
62  */
63 #ifndef HAVE_USLEEP
64 unsigned int usleep (unsigned int useconds)
65 {
66 #if defined(__EMX__)
67     DosSleep(useconds);
68     return 0;
69 #elif defined(__BEOS__)
70     return snooze(useconds);
71 #elif defined(HAVE_SELECT)
72     struct timeval delay;
73
74     delay.tv_sec = useconds / 1000000;
75     delay.tv_usec = useconds % 1000000;
76
77     select( 0, 0, 0, 0, &delay );
78     return 0;
79 #else /* defined(__EMX__) || defined(__BEOS__) || defined(HAVE_SELECT) */
80     errno = ENOSYS;
81     return -1;
82 #endif /* defined(__EMX__) || defined(__BEOS__) || defined(HAVE_SELECT) */
83 }
84 #endif /* HAVE_USLEEP */
85
86 /***********************************************************************
87  *              memmove
88  */
89 #ifndef HAVE_MEMMOVE
90 void *memmove( void *dest, const void *src, unsigned int len )
91 {
92     register char *dst = dest;
93
94     /* Use memcpy if not overlapping */
95     if ((dst + len <= (char *)src) || ((char *)src + len <= dst))
96     {
97         memcpy( dst, src, len );
98     }
99     /* Otherwise do it the hard way (FIXME: could do better than this) */
100     else if (dst < src)
101     {
102         while (len--) *dst++ = *((char *)src)++;
103     }
104     else
105     {
106         dst += len - 1;
107         src = (char *)src + len - 1;
108         while (len--) *dst-- = *((char *)src)--;
109     }
110     return dest;
111 }
112 #endif  /* HAVE_MEMMOVE */
113
114 /***********************************************************************
115  *              strerror
116  */
117 #ifndef HAVE_STRERROR
118 const char *strerror( int err )
119 {
120     /* Let's hope we have sys_errlist then */
121     return sys_errlist[err];
122 }
123 #endif  /* HAVE_STRERROR */
124
125
126 /***********************************************************************
127  *              getpagesize
128  */
129 #ifndef HAVE_GETPAGESIZE
130 size_t getpagesize(void)
131 {
132 # ifdef __svr4__
133     return sysconf(_SC_PAGESIZE);
134 # else
135 #  error Cannot get the page size on this platform
136 # endif
137 }
138 #endif  /* HAVE_GETPAGESIZE */
139
140
141 /***********************************************************************
142  *              clone
143  */
144 #if !defined(HAVE_CLONE) && defined(__linux__)
145 int clone( int (*fn)(void *), void *stack, int flags, void *arg )
146 {
147 #ifdef __i386__
148     int ret;
149     void **stack_ptr = (void **)stack;
150     *--stack_ptr = arg;  /* Push argument on stack */
151     *--stack_ptr = fn;   /* Push function pointer (popped into ebx) */
152     __asm__ __volatile__( "pushl %%ebx\n\t"
153                           "movl %2,%%ebx\n\t"
154                           "int $0x80\n\t"
155                           "popl %%ebx\n\t"   /* Contains fn in the child */
156                           "testl %%eax,%%eax\n\t"
157                           "jnz 0f\n\t"
158                           "xorl %ebp,%ebp\n\t"    /* Terminate the stack frames */
159                           "call *%%ebx\n\t"       /* Should never return */
160                           "xorl %%eax,%%eax\n\t"  /* Just in case it does*/
161                           "0:"
162                           : "=a" (ret)
163                           : "0" (SYS_clone), "r" (flags), "c" (stack_ptr) );
164     assert( ret );  /* If ret is 0, we returned from the child function */
165     if (ret > 0) return ret;
166     errno = -ret;
167     return -1;
168 #else
169     errno = EINVAL;
170     return -1;
171 #endif  /* __i386__ */
172 }
173 #endif  /* !HAVE_CLONE && __linux__ */
174
175 /***********************************************************************
176  *              strcasecmp
177  */
178 #ifndef HAVE_STRCASECMP
179 int strcasecmp( const char *str1, const char *str2 )
180 {
181     const unsigned char *ustr1 = (const unsigned char *)str1;
182     const unsigned char *ustr2 = (const unsigned char *)str2;
183
184     while (*ustr1 && toupper(*ustr1) == toupper(*ustr2)) {
185         ustr1++;
186         ustr2++;
187     }
188     return toupper(*ustr1) - toupper(*ustr2);
189 }
190 #endif /* HAVE_STRCASECMP */
191
192 /***********************************************************************
193  *              strncasecmp
194  */
195 #ifndef HAVE_STRNCASECMP
196 int strncasecmp( const char *str1, const char *str2, size_t n )
197 {
198     const unsigned char *ustr1 = (const unsigned char *)str1;
199     const unsigned char *ustr2 = (const unsigned char *)str2;
200     int res;
201
202     if (!n) return 0;
203     while ((--n > 0) && *ustr1) {
204         if ((res = toupper(*ustr1) - toupper(*ustr2))) return res;
205         ustr1++;
206         ustr2++;
207     }
208     return toupper(*ustr1) - toupper(*ustr2);
209 }
210 #endif /* HAVE_STRNCASECMP */
211
212 /***********************************************************************
213  *              openpty
214  * NOTE
215  *   It looks like the openpty that comes with glibc in RedHat 5.0
216  *   is buggy (second call returns what looks like a dup of 0 and 1
217  *   instead of a new pty), this is a generic replacement.
218  *
219  * FIXME
220  *   We should have a autoconf check for this.
221  */
222 #ifndef HAVE_OPENPTY
223 int openpty(int *master, int *slave, char *name, struct termios *term, struct winsize *winsize)
224 {
225     const char *ptr1, *ptr2;
226     char pts_name[512];
227
228     strcpy (pts_name, "/dev/ptyXY");
229
230     for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) {
231         pts_name[8] = *ptr1;
232         for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) {
233             pts_name[9] = *ptr2;
234
235             if ((*master = open(pts_name, O_RDWR)) < 0) {
236                 if (errno == ENOENT)
237                     return -1;
238                 else
239                     continue;
240             }
241             pts_name[5] = 't';
242             if ((*slave = open(pts_name, O_RDWR)) < 0) {
243                 pts_name[5] = 'p';
244                 close (*master);
245                 continue;
246             }
247
248             if (term != NULL)
249                 tcsetattr(*slave, TCSANOW, term);
250             if (winsize != NULL)
251                 ioctl(*slave, TIOCSWINSZ, winsize);
252             if (name != NULL)
253                 strcpy(name, pts_name);
254             return *slave;
255         }
256     }
257     errno = EMFILE;
258     return -1;
259 }
260 #endif  /* HAVE_OPENPTY */
261
262 /***********************************************************************
263  *              getnetbyaddr
264  */
265 #ifndef HAVE_GETNETBYADDR
266 struct netent *getnetbyaddr(unsigned long net, int type)
267 {
268     errno = ENOSYS;
269     return NULL;
270 }
271 #endif /* defined(HAVE_GETNETBYNAME) */
272
273 /***********************************************************************
274  *              getnetbyname
275  */
276 #ifndef HAVE_GETNETBYNAME
277 struct netent *getnetbyname(const char *name)
278 {
279     errno = ENOSYS;
280     return NULL;
281 }
282 #endif /* defined(HAVE_GETNETBYNAME) */
283
284 /***********************************************************************
285  *              getprotobyname
286  */
287 #ifndef HAVE_GETPROTOBYNAME
288 struct protoent *getprotobyname(const char *name)
289 {
290     errno = ENOSYS;
291     return NULL;
292 }
293 #endif /* !defined(HAVE_GETPROTOBYNAME) */
294
295 /***********************************************************************
296  *              getprotobynumber
297  */
298 #ifndef HAVE_GETPROTOBYNUMBER
299 struct protoent *getprotobynumber(int proto)
300 {
301     errno = ENOSYS;
302     return NULL;
303 }
304 #endif /* !defined(HAVE_GETPROTOBYNUMBER) */
305
306 /***********************************************************************
307  *              getservbyport
308  */
309 #ifndef HAVE_GETSERVBYPORT
310 struct servent *getservbyport(int port, const char *proto)
311 {
312     errno = ENOSYS;
313     return NULL;
314 }
315 #endif /* !defined(HAVE_GETSERVBYPORT) */
316
317 /***********************************************************************
318  *              getsockopt
319  */
320 #ifndef HAVE_GETSOCKOPT
321 int getsockopt(int socket, int level, int option_name,
322                void *option_value, size_t *option_len)
323 {
324     errno = ENOSYS;
325     return -1;
326 }
327 #endif /* !defined(HAVE_GETSOCKOPT) */
328
329 /***********************************************************************
330  *              inet_network
331  */
332 #ifndef HAVE_INET_NETWORK
333 unsigned long inet_network(const char *cp)
334 {
335     errno = ENOSYS;
336     return 0;
337 }
338 #endif /* defined(HAVE_INET_NETWORK) */
339
340 /***********************************************************************
341  *              statfs
342  */
343 #ifndef HAVE_STATFS
344 int statfs(const char *name, struct statfs *info)
345 {
346 #ifdef __BEOS__
347     dev_t mydev;
348     fs_info fsinfo;
349
350     if(!info) {
351         errno = ENOSYS;
352         return -1;
353     }
354
355     if ((mydev = dev_for_path(name)) < 0) {
356         errno = ENOSYS;
357         return -1;
358     }
359
360     if (fs_stat_dev(mydev,&fsinfo) < 0) {
361         errno = ENOSYS;
362         return -1;
363     }
364
365     info->f_bsize = fsinfo.block_size;
366     info->f_blocks = fsinfo.total_blocks;
367     info->f_bfree = fsinfo.free_blocks;
368     return 0;
369 #else /* defined(__BEOS__) */
370     errno = ENOSYS;
371     return -1;
372 #endif /* defined(__BEOS__) */
373 }
374 #endif /* !defined(HAVE_STATFS) */
375
376
377 /***********************************************************************
378  *              lstat
379  */
380 #ifndef HAVE_LSTAT
381 int lstat(const char *file_name, struct stat *buf)
382 {
383     return stat( file_name, buf );
384 }
385 #endif /* HAVE_LSTAT */
386
387
388 /***********************************************************************
389  *              pread
390  *
391  * FIXME: this is not thread-safe
392  */
393 #ifndef HAVE_PREAD
394 ssize_t pread( int fd, void *buf, size_t count, off_t offset )
395 {
396     ssize_t ret;
397     off_t old_pos;
398
399     if ((old_pos = lseek( fd, 0, SEEK_CUR )) == -1) return -1;
400     if (lseek( fd, offset, SEEK_SET ) == -1) return -1;
401     if ((ret = read( fd, buf, count )) == -1)
402     {
403         int err = errno;  /* save errno */
404         lseek( fd, old_pos, SEEK_SET );
405         errno = err;
406         return -1;
407     }
408     if (lseek( fd, old_pos, SEEK_SET ) == -1) return -1;
409     return ret;
410 }
411 #endif /* HAVE_PREAD */
412
413
414 /***********************************************************************
415  *              pwrite
416  *
417  * FIXME: this is not thread-safe
418  */
419 #ifndef HAVE_PWRITE
420 ssize_t pwrite( int fd, const void *buf, size_t count, off_t offset )
421 {
422     ssize_t ret;
423     off_t old_pos;
424
425     if ((old_pos = lseek( fd, 0, SEEK_CUR )) == -1) return -1;
426     if (lseek( fd, offset, SEEK_SET ) == -1) return -1;
427     if ((ret = write( fd, buf, count )) == -1)
428     {
429         int err = errno;  /* save errno */
430         lseek( fd, old_pos, SEEK_SET );
431         errno = err;
432         return -1;
433     }
434     if (lseek( fd, old_pos, SEEK_SET ) == -1) return -1;
435     return ret;
436 }
437 #endif /* HAVE_PWRITE */
438
439
440 /***********************************************************************
441  *              getrlimit
442  */
443 #ifndef HAVE_GETRLIMIT
444 int getrlimit (int resource, struct rlimit *rlim)
445 {
446     return -1; /* FAIL */
447 }
448 #endif /* HAVE_GETRLIMIT */
449
450
451 #if defined(__svr4__) || defined(__NetBSD__)
452 /***********************************************************************
453  *             try_mmap_fixed
454  *
455  * The purpose of this routine is to emulate the behaviour of
456  * the Linux mmap() routine if a non-NULL address is passed,
457  * but the MAP_FIXED flag is not set.  Linux in this case tries
458  * to place the mapping at the specified address, *unless* the
459  * range is already in use.  Solaris, however, completely ignores
460  * the address argument in this case.
461  *
462  * As Wine code occasionally relies on the Linux behaviour, e.g. to
463  * be able to map non-relocateable PE executables to their proper
464  * start addresses, or to map the DOS memory to 0, this routine
465  * emulates the Linux behaviour by checking whether the desired
466  * address range is still available, and placing the mapping there
467  * using MAP_FIXED if so.
468  */
469 static int try_mmap_fixed (void *addr, size_t len, int prot, int flags,
470                            int fildes, off_t off)
471 {
472     char * volatile result = NULL;
473     int pagesize = getpagesize();
474     pid_t pid;
475
476     /* We only try to map to a fixed address if
477        addr is non-NULL and properly aligned,
478        and MAP_FIXED isn't already specified. */
479
480     if ( !addr )
481         return 0;
482     if ( (uintptr_t)addr & (pagesize-1) )
483         return 0;
484     if ( flags & MAP_FIXED )
485         return 0;
486
487     /* We use vfork() to freeze all threads of the
488        current process.  This allows us to check without
489        race condition whether the desired memory range is
490        already in use.  Note that because vfork() shares
491        the address spaces between parent and child, we
492        can actually perform the mapping in the child. */
493
494     if ( (pid = vfork()) == -1 )
495     {
496         perror("try_mmap_fixed: vfork");
497         exit(1);
498     }
499     if ( pid == 0 )
500     {
501         int i;
502         char vec;
503
504         /* We call mincore() for every page in the desired range.
505            If any of these calls succeeds, the page is already
506            mapped and we must fail. */
507         for ( i = 0; i < len; i += pagesize )
508             if ( mincore( (caddr_t)addr + i, pagesize, &vec ) != -1 )
509                _exit(1);
510
511         /* Perform the mapping with MAP_FIXED set.  This is safe
512            now, as none of the pages is currently in use. */
513         result = mmap( addr, len, prot, flags | MAP_FIXED, fildes, off );
514         if ( result == addr )
515             _exit(0);
516
517         if ( result != (void *) -1 ) /* This should never happen ... */
518             munmap( result, len );
519
520        _exit(1);
521     }
522
523     /* vfork() lets the parent continue only after the child
524        has exited.  Furthermore, Wine sets SIGCHLD to SIG_IGN,
525        so we don't need to wait for the child. */
526
527     return result == addr;
528 }
529 #endif
530
531 /***********************************************************************
532  *              wine_anon_mmap
533  *
534  * Portable wrapper for anonymous mmaps
535  */
536 void *wine_anon_mmap( void *start, size_t size, int prot, int flags )
537 {
538     static int fdzero = -1;
539
540 #ifdef MAP_ANON
541     flags |= MAP_ANON;
542 #else
543     if (fdzero == -1)
544     {
545         if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1)
546         {
547             perror( "/dev/zero: open" );
548             exit(1);
549         }
550     }
551 #endif  /* MAP_ANON */
552
553 #ifdef MAP_SHARED
554     flags &= ~MAP_SHARED;
555 #endif
556
557     /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */
558 #ifdef MAP_PRIVATE
559     flags |= MAP_PRIVATE;
560 #endif
561
562 #if defined(__svr4__) || defined(__NetBSD__)
563     if ( try_mmap_fixed( start, size, prot, flags, fdzero, 0 ) )
564         return start;
565 #endif
566
567     return mmap( start, size, prot, flags, fdzero, 0 );
568 }
569
570
571 /*
572  * These functions provide wrappers around dlopen() and associated
573  * functions.  They work around a bug in glibc 2.1.x where calling
574  * a dl*() function after a previous dl*() function has failed
575  * without a dlerror() call between the two will cause a crash.
576  * They all take a pointer to a buffer that
577  * will receive the error description (from dlerror()).  This
578  * parameter may be NULL if the error description is not required.
579  */
580
581 /***********************************************************************
582  *              wine_dlopen
583  */
584 void *wine_dlopen( const char *filename, int flag, char *error, int errorsize )
585 {
586 #ifdef HAVE_DLOPEN
587     void *ret;
588     char *s;
589     dlerror(); dlerror();
590     ret = dlopen( filename, flag );
591     s = dlerror();
592     if (error)
593     {
594         strncpy( error, s ? s : "", errorsize );
595         error[errorsize - 1] = '\0';
596     }
597     dlerror();
598     return ret;
599 #else
600     if (error)
601     {
602         strncpy( error, "dlopen interface not detected by configure", errorsize );
603         error[errorsize - 1] = '\0';
604     }
605     return NULL;
606 #endif
607 }
608
609 /***********************************************************************
610  *              wine_dlsym
611  */
612 void *wine_dlsym( void *handle, const char *symbol, char *error, int errorsize )
613 {
614 #ifdef HAVE_DLOPEN
615     void *ret;
616     char *s;
617     dlerror(); dlerror();
618     ret = dlsym( handle, symbol );
619     s = dlerror();
620     if (error)
621     {
622         strncpy( error, s ? s : "", errorsize );
623         error[errorsize - 1] = '\0';
624     }
625     dlerror();
626     return ret;
627 #else
628     if (error)
629     {
630         strncpy( error, "dlopen interface not detected by configure", errorsize );
631         error[errorsize - 1] = '\0';
632     }
633     return NULL;
634 #endif
635 }
636
637 /***********************************************************************
638  *              wine_dlclose
639  */
640 int wine_dlclose( void *handle, char *error, int errorsize )
641 {
642 #ifdef HAVE_DLOPEN
643     int ret;
644     char *s;
645     dlerror(); dlerror();
646     ret = dlclose( handle );
647     s = dlerror();
648     if (error)
649     {
650         strncpy( error, s ? s : "", errorsize );
651         error[errorsize - 1] = '\0';
652     }
653     dlerror();
654     return ret;
655 #else
656     if (error)
657     {
658         strncpy( error, "dlopen interface not detected by configure", errorsize );
659         error[errorsize - 1] = '\0';
660     }
661     return 1;
662 #endif
663 }
664
665 /***********************************************************************
666  *              wine_rewrite_s4tos2
667  *
668  * Convert 4 byte Unicode strings to 2 byte Unicode strings in-place.
669  * This is only practical if literal strings are writable.
670  */
671 unsigned short* wine_rewrite_s4tos2(const wchar_t* str4 )
672 {
673     unsigned short *str2,*s2;
674
675     if (str4==NULL)
676       return NULL;
677
678     if ((*str4 & 0xffff0000) != 0) {
679         /* This string has already been converted. Return it as is */
680         return (unsigned short*)str4;
681     }
682
683     /* Note that we can also end up here if the string has a single 
684      * character. In such a case we will convert the string over and 
685      * over again. But this is harmless.
686      */
687     str2=s2=(unsigned short*)str4;
688     do {
689         *s2=(unsigned short)*str4;
690         s2++;
691     } while (*str4++ != L'\0');
692
693     return str2;
694 }
695
696 #ifndef HAVE_ECVT
697 /*
698  * NetBSD 1.5 doesn't have ecvt, fcvt, gcvt. We just check for ecvt, though.
699  * Fix/verify these implementations !
700  */
701
702 /***********************************************************************
703  *              ecvt
704  */
705 char *ecvt (double number, int  ndigits,  int  *decpt,  int *sign)
706 {
707     static char buf[40]; /* ought to be enough */
708     char *dec;
709     sprintf(buf, "%.*e", ndigits /* FIXME wrong */, number); 
710     *sign = (number < 0);
711     dec = strchr(buf, '.');
712     *decpt = (dec) ? (int)dec - (int)buf : -1;
713     return buf;
714 }
715
716 /***********************************************************************
717  *              fcvt
718  */
719 char *fcvt (double number, int  ndigits,  int  *decpt,  int *sign)
720 {
721     static char buf[40]; /* ought to be enough */
722     char *dec;
723     sprintf(buf, "%.*e", ndigits, number);
724     *sign = (number < 0);
725     dec = strchr(buf, '.');
726     *decpt = (dec) ? (int)dec - (int)buf : -1;
727     return buf;
728 }
729
730 /***********************************************************************
731  *              gcvt
732  *
733  * FIXME: uses both E and F.
734  */
735 char *gcvt (double number, size_t  ndigit,  char *buff)
736 {
737     sprintf(buff, "%.*E", (int)ndigit, number);
738     return buff;
739 }
740 #endif /* HAVE_ECVT */