Correct behaviour of DEL key back to deleting the current character.
[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  *              getnetbyaddr
214  */
215 #ifndef HAVE_GETNETBYADDR
216 struct netent *getnetbyaddr(unsigned long net, int type)
217 {
218     errno = ENOSYS;
219     return NULL;
220 }
221 #endif /* defined(HAVE_GETNETBYNAME) */
222
223 /***********************************************************************
224  *              getnetbyname
225  */
226 #ifndef HAVE_GETNETBYNAME
227 struct netent *getnetbyname(const char *name)
228 {
229     errno = ENOSYS;
230     return NULL;
231 }
232 #endif /* defined(HAVE_GETNETBYNAME) */
233
234 /***********************************************************************
235  *              getprotobyname
236  */
237 #ifndef HAVE_GETPROTOBYNAME
238 struct protoent *getprotobyname(const char *name)
239 {
240     errno = ENOSYS;
241     return NULL;
242 }
243 #endif /* !defined(HAVE_GETPROTOBYNAME) */
244
245 /***********************************************************************
246  *              getprotobynumber
247  */
248 #ifndef HAVE_GETPROTOBYNUMBER
249 struct protoent *getprotobynumber(int proto)
250 {
251     errno = ENOSYS;
252     return NULL;
253 }
254 #endif /* !defined(HAVE_GETPROTOBYNUMBER) */
255
256 /***********************************************************************
257  *              getservbyport
258  */
259 #ifndef HAVE_GETSERVBYPORT
260 struct servent *getservbyport(int port, const char *proto)
261 {
262     errno = ENOSYS;
263     return NULL;
264 }
265 #endif /* !defined(HAVE_GETSERVBYPORT) */
266
267 /***********************************************************************
268  *              getsockopt
269  */
270 #ifndef HAVE_GETSOCKOPT
271 int getsockopt(int socket, int level, int option_name,
272                void *option_value, size_t *option_len)
273 {
274     errno = ENOSYS;
275     return -1;
276 }
277 #endif /* !defined(HAVE_GETSOCKOPT) */
278
279 /***********************************************************************
280  *              inet_network
281  */
282 #ifndef HAVE_INET_NETWORK
283 unsigned long inet_network(const char *cp)
284 {
285     errno = ENOSYS;
286     return 0;
287 }
288 #endif /* defined(HAVE_INET_NETWORK) */
289
290 /***********************************************************************
291  *              statfs
292  */
293 #ifndef HAVE_STATFS
294 int statfs(const char *name, struct statfs *info)
295 {
296 #ifdef __BEOS__
297     dev_t mydev;
298     fs_info fsinfo;
299
300     if(!info) {
301         errno = ENOSYS;
302         return -1;
303     }
304
305     if ((mydev = dev_for_path(name)) < 0) {
306         errno = ENOSYS;
307         return -1;
308     }
309
310     if (fs_stat_dev(mydev,&fsinfo) < 0) {
311         errno = ENOSYS;
312         return -1;
313     }
314
315     info->f_bsize = fsinfo.block_size;
316     info->f_blocks = fsinfo.total_blocks;
317     info->f_bfree = fsinfo.free_blocks;
318     return 0;
319 #else /* defined(__BEOS__) */
320     errno = ENOSYS;
321     return -1;
322 #endif /* defined(__BEOS__) */
323 }
324 #endif /* !defined(HAVE_STATFS) */
325
326
327 /***********************************************************************
328  *              lstat
329  */
330 #ifndef HAVE_LSTAT
331 int lstat(const char *file_name, struct stat *buf)
332 {
333     return stat( file_name, buf );
334 }
335 #endif /* HAVE_LSTAT */
336
337
338 /***********************************************************************
339  *              pread
340  *
341  * FIXME: this is not thread-safe
342  */
343 #ifndef HAVE_PREAD
344 ssize_t pread( int fd, void *buf, size_t count, off_t offset )
345 {
346     ssize_t ret;
347     off_t old_pos;
348
349     if ((old_pos = lseek( fd, 0, SEEK_CUR )) == -1) return -1;
350     if (lseek( fd, offset, SEEK_SET ) == -1) return -1;
351     if ((ret = read( fd, buf, count )) == -1)
352     {
353         int err = errno;  /* save errno */
354         lseek( fd, old_pos, SEEK_SET );
355         errno = err;
356         return -1;
357     }
358     if (lseek( fd, old_pos, SEEK_SET ) == -1) return -1;
359     return ret;
360 }
361 #endif /* HAVE_PREAD */
362
363
364 /***********************************************************************
365  *              pwrite
366  *
367  * FIXME: this is not thread-safe
368  */
369 #ifndef HAVE_PWRITE
370 ssize_t pwrite( int fd, const void *buf, size_t count, off_t offset )
371 {
372     ssize_t ret;
373     off_t old_pos;
374
375     if ((old_pos = lseek( fd, 0, SEEK_CUR )) == -1) return -1;
376     if (lseek( fd, offset, SEEK_SET ) == -1) return -1;
377     if ((ret = write( fd, buf, count )) == -1)
378     {
379         int err = errno;  /* save errno */
380         lseek( fd, old_pos, SEEK_SET );
381         errno = err;
382         return -1;
383     }
384     if (lseek( fd, old_pos, SEEK_SET ) == -1) return -1;
385     return ret;
386 }
387 #endif /* HAVE_PWRITE */
388
389
390 #if defined(__svr4__) || defined(__NetBSD__)
391 /***********************************************************************
392  *             try_mmap_fixed
393  *
394  * The purpose of this routine is to emulate the behaviour of
395  * the Linux mmap() routine if a non-NULL address is passed,
396  * but the MAP_FIXED flag is not set.  Linux in this case tries
397  * to place the mapping at the specified address, *unless* the
398  * range is already in use.  Solaris, however, completely ignores
399  * the address argument in this case.
400  *
401  * As Wine code occasionally relies on the Linux behaviour, e.g. to
402  * be able to map non-relocateable PE executables to their proper
403  * start addresses, or to map the DOS memory to 0, this routine
404  * emulates the Linux behaviour by checking whether the desired
405  * address range is still available, and placing the mapping there
406  * using MAP_FIXED if so.
407  */
408 static int try_mmap_fixed (void *addr, size_t len, int prot, int flags,
409                            int fildes, off_t off)
410 {
411     char * volatile result = NULL;
412     int pagesize = getpagesize();
413     pid_t pid;
414
415     /* We only try to map to a fixed address if
416        addr is non-NULL and properly aligned,
417        and MAP_FIXED isn't already specified. */
418
419     if ( !addr )
420         return 0;
421     if ( (uintptr_t)addr & (pagesize-1) )
422         return 0;
423     if ( flags & MAP_FIXED )
424         return 0;
425
426     /* We use vfork() to freeze all threads of the
427        current process.  This allows us to check without
428        race condition whether the desired memory range is
429        already in use.  Note that because vfork() shares
430        the address spaces between parent and child, we
431        can actually perform the mapping in the child. */
432
433     if ( (pid = vfork()) == -1 )
434     {
435         perror("try_mmap_fixed: vfork");
436         exit(1);
437     }
438     if ( pid == 0 )
439     {
440         int i;
441         char vec;
442
443         /* We call mincore() for every page in the desired range.
444            If any of these calls succeeds, the page is already
445            mapped and we must fail. */
446         for ( i = 0; i < len; i += pagesize )
447             if ( mincore( (caddr_t)addr + i, pagesize, &vec ) != -1 )
448                _exit(1);
449
450         /* Perform the mapping with MAP_FIXED set.  This is safe
451            now, as none of the pages is currently in use. */
452         result = mmap( addr, len, prot, flags | MAP_FIXED, fildes, off );
453         if ( result == addr )
454             _exit(0);
455
456         if ( result != (void *) -1 ) /* This should never happen ... */
457             munmap( result, len );
458
459        _exit(1);
460     }
461
462     /* vfork() lets the parent continue only after the child
463        has exited.  Furthermore, Wine sets SIGCHLD to SIG_IGN,
464        so we don't need to wait for the child. */
465
466     return result == addr;
467 }
468 #endif
469
470 /***********************************************************************
471  *              wine_anon_mmap
472  *
473  * Portable wrapper for anonymous mmaps
474  */
475 void *wine_anon_mmap( void *start, size_t size, int prot, int flags )
476 {
477     static int fdzero = -1;
478
479 #ifdef MAP_ANON
480     flags |= MAP_ANON;
481 #else
482     if (fdzero == -1)
483     {
484         if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1)
485         {
486             perror( "/dev/zero: open" );
487             exit(1);
488         }
489     }
490 #endif  /* MAP_ANON */
491
492 #ifdef MAP_SHARED
493     flags &= ~MAP_SHARED;
494 #endif
495
496     /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */
497 #ifdef MAP_PRIVATE
498     flags |= MAP_PRIVATE;
499 #endif
500
501 #if defined(__svr4__) || defined(__NetBSD__)
502     if ( try_mmap_fixed( start, size, prot, flags, fdzero, 0 ) )
503         return start;
504 #endif
505
506     return mmap( start, size, prot, flags, fdzero, 0 );
507 }
508
509
510 /*
511  * These functions provide wrappers around dlopen() and associated
512  * functions.  They work around a bug in glibc 2.1.x where calling
513  * a dl*() function after a previous dl*() function has failed
514  * without a dlerror() call between the two will cause a crash.
515  * They all take a pointer to a buffer that
516  * will receive the error description (from dlerror()).  This
517  * parameter may be NULL if the error description is not required.
518  */
519
520 /***********************************************************************
521  *              wine_dlopen
522  */
523 void *wine_dlopen( const char *filename, int flag, char *error, int errorsize )
524 {
525 #ifdef HAVE_DLOPEN
526     void *ret;
527     const char *s;
528     dlerror(); dlerror();
529     ret = dlopen( filename, flag );
530     s = dlerror();
531     if (error)
532     {
533         strncpy( error, s ? s : "", errorsize );
534         error[errorsize - 1] = '\0';
535     }
536     dlerror();
537     return ret;
538 #else
539     if (error)
540     {
541         strncpy( error, "dlopen interface not detected by configure", errorsize );
542         error[errorsize - 1] = '\0';
543     }
544     return NULL;
545 #endif
546 }
547
548 /***********************************************************************
549  *              wine_dlsym
550  */
551 void *wine_dlsym( void *handle, const char *symbol, char *error, int errorsize )
552 {
553 #ifdef HAVE_DLOPEN
554     void *ret;
555     const char *s;
556     dlerror(); dlerror();
557     ret = dlsym( handle, symbol );
558     s = dlerror();
559     if (error)
560     {
561         strncpy( error, s ? s : "", errorsize );
562         error[errorsize - 1] = '\0';
563     }
564     dlerror();
565     return ret;
566 #else
567     if (error)
568     {
569         strncpy( error, "dlopen interface not detected by configure", errorsize );
570         error[errorsize - 1] = '\0';
571     }
572     return NULL;
573 #endif
574 }
575
576 /***********************************************************************
577  *              wine_dlclose
578  */
579 int wine_dlclose( void *handle, char *error, int errorsize )
580 {
581 #ifdef HAVE_DLOPEN
582     int ret;
583     const char *s;
584     dlerror(); dlerror();
585     ret = dlclose( handle );
586     s = dlerror();
587     if (error)
588     {
589         strncpy( error, s ? s : "", errorsize );
590         error[errorsize - 1] = '\0';
591     }
592     dlerror();
593     return ret;
594 #else
595     if (error)
596     {
597         strncpy( error, "dlopen interface not detected by configure", errorsize );
598         error[errorsize - 1] = '\0';
599     }
600     return 1;
601 #endif
602 }
603
604 /***********************************************************************
605  *              wine_rewrite_s4tos2
606  *
607  * Convert 4 byte Unicode strings to 2 byte Unicode strings in-place.
608  * This is only practical if literal strings are writable.
609  */
610 unsigned short* wine_rewrite_s4tos2(const wchar_t* str4 )
611 {
612     unsigned short *str2,*s2;
613
614     if (str4==NULL)
615       return NULL;
616
617     if ((*str4 & 0xffff0000) != 0) {
618         /* This string has already been converted. Return it as is */
619         return (unsigned short*)str4;
620     }
621
622     /* Note that we can also end up here if the string has a single 
623      * character. In such a case we will convert the string over and 
624      * over again. But this is harmless.
625      */
626     str2=s2=(unsigned short*)str4;
627     do {
628         *s2=(unsigned short)*str4;
629         s2++;
630     } while (*str4++ != L'\0');
631
632     return str2;
633 }
634
635 #ifndef HAVE_ECVT
636 /*
637  * NetBSD 1.5 doesn't have ecvt, fcvt, gcvt. We just check for ecvt, though.
638  * Fix/verify these implementations !
639  */
640
641 /***********************************************************************
642  *              ecvt
643  */
644 char *ecvt (double number, int  ndigits,  int  *decpt,  int *sign)
645 {
646     static char buf[40]; /* ought to be enough */
647     char *dec;
648     sprintf(buf, "%.*e", ndigits /* FIXME wrong */, number); 
649     *sign = (number < 0);
650     dec = strchr(buf, '.');
651     *decpt = (dec) ? (int)dec - (int)buf : -1;
652     return buf;
653 }
654
655 /***********************************************************************
656  *              fcvt
657  */
658 char *fcvt (double number, int  ndigits,  int  *decpt,  int *sign)
659 {
660     static char buf[40]; /* ought to be enough */
661     char *dec;
662     sprintf(buf, "%.*e", ndigits, number);
663     *sign = (number < 0);
664     dec = strchr(buf, '.');
665     *decpt = (dec) ? (int)dec - (int)buf : -1;
666     return buf;
667 }
668
669 /***********************************************************************
670  *              gcvt
671  *
672  * FIXME: uses both E and F.
673  */
674 char *gcvt (double number, size_t  ndigit,  char *buff)
675 {
676     sprintf(buff, "%.*E", (int)ndigit, number);
677     return buff;
678 }
679 #endif /* HAVE_ECVT */
680
681
682 /***********************************************************************
683  *              interlocked functions
684  */
685 #ifdef __i386__
686
687 __ASM_GLOBAL_FUNC(interlocked_cmpxchg,
688                   "movl 12(%esp),%eax\n\t"
689                   "movl 8(%esp),%ecx\n\t"
690                   "movl 4(%esp),%edx\n\t"
691                   "lock; cmpxchgl %ecx,(%edx)\n\t"
692                   "ret");
693 __ASM_GLOBAL_FUNC(interlocked_cmpxchg_ptr,
694                   "movl 12(%esp),%eax\n\t"
695                   "movl 8(%esp),%ecx\n\t"
696                   "movl 4(%esp),%edx\n\t"
697                   "lock; cmpxchgl %ecx,(%edx)\n\t"
698                   "ret");
699 __ASM_GLOBAL_FUNC(interlocked_xchg,
700                   "movl 8(%esp),%eax\n\t"
701                   "movl 4(%esp),%edx\n\t"
702                   "lock; xchgl %eax,(%edx)\n\t"
703                   "ret");
704 __ASM_GLOBAL_FUNC(interlocked_xchg_ptr,
705                   "movl 8(%esp),%eax\n\t"
706                   "movl 4(%esp),%edx\n\t"
707                   "lock; xchgl %eax,(%edx)\n\t"
708                   "ret");
709 __ASM_GLOBAL_FUNC(interlocked_xchg_add,
710                   "movl 8(%esp),%eax\n\t"
711                   "movl 4(%esp),%edx\n\t"
712                   "lock; xaddl %eax,(%edx)\n\t"
713                   "ret");
714
715 #elif defined(__sparc__) && defined(__sun__)
716
717 /*
718  * As the earlier Sparc processors lack necessary atomic instructions,
719  * I'm simply falling back to the library-provided _lwp_mutex routines
720  * to ensure mutual exclusion in a way appropriate for the current 
721  * architecture.  
722  *
723  * FIXME:  If we have the compare-and-swap instruction (Sparc v9 and above)
724  *         we could use this to speed up the Interlocked operations ...
725  */
726 #include <synch.h>
727 static lwp_mutex_t interlocked_mutex = DEFAULTMUTEX;
728
729 long interlocked_cmpxchg( long *dest, long xchg, long compare )
730 {
731     _lwp_mutex_lock( &interlocked_mutex );
732     if (*dest == compare) *dest = xchg;
733     else compare = *dest;
734     _lwp_mutex_unlock( &interlocked_mutex );
735     return compare;
736 }
737
738 void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
739 {
740     _lwp_mutex_lock( &interlocked_mutex );
741     if (*dest == compare) *dest = xchg;
742     else compare = *dest;
743     _lwp_mutex_unlock( &interlocked_mutex );
744     return compare;
745 }
746
747 long interlocked_xchg( long *dest, long val )
748 {
749     long retv;
750     _lwp_mutex_lock( &interlocked_mutex );
751     retv = *dest;
752     *dest = val;
753     _lwp_mutex_unlock( &interlocked_mutex );
754     return retv;
755 }
756
757 void *interlocked_xchg_ptr( void **dest, void *val )
758 {
759     long retv;
760     _lwp_mutex_lock( &interlocked_mutex );
761     retv = *dest;
762     *dest = val;
763     _lwp_mutex_unlock( &interlocked_mutex );
764     return retv;
765 }
766
767 long interlocked_xchg_add( long *dest, long incr )
768 {
769     long retv;
770     _lwp_mutex_lock( &interlocked_mutex );
771     retv = *dest;
772     *dest += incr;
773     _lwp_mutex_unlock( &interlocked_mutex );
774     return retv;
775 }
776
777 #else
778 # error You must implement the interlocked* functions for your CPU
779 #endif