Make Home, End and Enter on the keypad work in the debugger.
[wine.git] / library / port.c
blob7763081fddd07b3359932cd1eb2dc173716d11fa
1 /*
2 * Misc. functions for systems that don't have them
4 * Copyright 1996 Alexandre Julliard
5 */
7 #include "config.h"
8 #include "wine/port.h"
10 #ifdef __BEOS__
11 #include <be/kernel/fs_info.h>
12 #include <be/kernel/OS.h>
13 #endif
15 #include <assert.h>
16 #include <ctype.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/time.h>
23 #include <sys/stat.h>
24 #include <sys/ioctl.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <termios.h>
28 #ifdef HAVE_SYS_MMAN_H
29 #include <sys/mman.h>
30 #endif
31 #ifdef HAVE_LIBIO_H
32 # include <libio.h>
33 #endif
34 #ifdef HAVE_SYSCALL_H
35 # include <syscall.h>
36 #endif
37 #ifdef HAVE_STDINT_H
38 # include <stdint.h>
39 #endif
41 /***********************************************************************
42 * usleep
44 #ifndef HAVE_USLEEP
45 unsigned int usleep (unsigned int useconds)
47 #if defined(__EMX__)
48 DosSleep(useconds);
49 return 0;
50 #elif defined(__BEOS__)
51 return snooze(useconds);
52 #elif defined(HAVE_SELECT)
53 struct timeval delay;
55 delay.tv_sec = useconds / 1000000;
56 delay.tv_usec = useconds % 1000000;
58 select( 0, 0, 0, 0, &delay );
59 return 0;
60 #else /* defined(__EMX__) || defined(__BEOS__) || defined(HAVE_SELECT) */
61 errno = ENOSYS;
62 return -1;
63 #endif /* defined(__EMX__) || defined(__BEOS__) || defined(HAVE_SELECT) */
65 #endif /* HAVE_USLEEP */
67 /***********************************************************************
68 * memmove
70 #ifndef HAVE_MEMMOVE
71 void *memmove( void *dest, const void *src, unsigned int len )
73 register char *dst = dest;
75 /* Use memcpy if not overlapping */
76 if ((dst + len <= (char *)src) || ((char *)src + len <= dst))
78 memcpy( dst, src, len );
80 /* Otherwise do it the hard way (FIXME: could do better than this) */
81 else if (dst < src)
83 while (len--) *dst++ = *((char *)src)++;
85 else
87 dst += len - 1;
88 src = (char *)src + len - 1;
89 while (len--) *dst-- = *((char *)src)--;
91 return dest;
93 #endif /* HAVE_MEMMOVE */
95 /***********************************************************************
96 * strerror
98 #ifndef HAVE_STRERROR
99 const char *strerror( int err )
101 /* Let's hope we have sys_errlist then */
102 return sys_errlist[err];
104 #endif /* HAVE_STRERROR */
107 /***********************************************************************
108 * getpagesize
110 #ifndef HAVE_GETPAGESIZE
111 size_t getpagesize(void)
113 # ifdef __svr4__
114 return sysconf(_SC_PAGESIZE);
115 # else
116 # error Cannot get the page size on this platform
117 # endif
119 #endif /* HAVE_GETPAGESIZE */
122 /***********************************************************************
123 * clone
125 #if !defined(HAVE_CLONE) && defined(__linux__)
126 int clone( int (*fn)(void *), void *stack, int flags, void *arg )
128 #ifdef __i386__
129 int ret;
130 void **stack_ptr = (void **)stack;
131 *--stack_ptr = arg; /* Push argument on stack */
132 *--stack_ptr = fn; /* Push function pointer (popped into ebx) */
133 __asm__ __volatile__( "pushl %%ebx\n\t"
134 "movl %2,%%ebx\n\t"
135 "int $0x80\n\t"
136 "popl %%ebx\n\t" /* Contains fn in the child */
137 "testl %%eax,%%eax\n\t"
138 "jnz 0f\n\t"
139 "xorl %ebp,%ebp\n\t" /* Terminate the stack frames */
140 "call *%%ebx\n\t" /* Should never return */
141 "xorl %%eax,%%eax\n\t" /* Just in case it does*/
142 "0:"
143 : "=a" (ret)
144 : "0" (SYS_clone), "r" (flags), "c" (stack_ptr) );
145 assert( ret ); /* If ret is 0, we returned from the child function */
146 if (ret > 0) return ret;
147 errno = -ret;
148 return -1;
149 #else
150 errno = EINVAL;
151 return -1;
152 #endif /* __i386__ */
154 #endif /* !HAVE_CLONE && __linux__ */
156 /***********************************************************************
157 * strcasecmp
159 #ifndef HAVE_STRCASECMP
160 int strcasecmp( const char *str1, const char *str2 )
162 const unsigned char *ustr1 = (const unsigned char *)str1;
163 const unsigned char *ustr2 = (const unsigned char *)str2;
165 while (*ustr1 && toupper(*ustr1) == toupper(*ustr2)) {
166 ustr1++;
167 ustr2++;
169 return toupper(*ustr1) - toupper(*ustr2);
171 #endif /* HAVE_STRCASECMP */
173 /***********************************************************************
174 * strncasecmp
176 #ifndef HAVE_STRNCASECMP
177 int strncasecmp( const char *str1, const char *str2, size_t n )
179 const unsigned char *ustr1 = (const unsigned char *)str1;
180 const unsigned char *ustr2 = (const unsigned char *)str2;
181 int res;
183 if (!n) return 0;
184 while ((--n > 0) && *ustr1) {
185 if ((res = toupper(*ustr1) - toupper(*ustr2))) return res;
186 ustr1++;
187 ustr2++;
189 return toupper(*ustr1) - toupper(*ustr2);
191 #endif /* HAVE_STRNCASECMP */
193 /***********************************************************************
194 * openpty
195 * NOTE
196 * It looks like the openpty that comes with glibc in RedHat 5.0
197 * is buggy (second call returns what looks like a dup of 0 and 1
198 * instead of a new pty), this is a generic replacement.
200 * FIXME
201 * We should have a autoconf check for this.
203 #ifndef HAVE_OPENPTY
204 int openpty(int *master, int *slave, char *name, struct termios *term, struct winsize *winsize)
206 const char *ptr1, *ptr2;
207 char pts_name[512];
209 strcpy (pts_name, "/dev/ptyXY");
211 for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) {
212 pts_name[8] = *ptr1;
213 for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) {
214 pts_name[9] = *ptr2;
216 if ((*master = open(pts_name, O_RDWR)) < 0) {
217 if (errno == ENOENT)
218 return -1;
219 else
220 continue;
222 pts_name[5] = 't';
223 if ((*slave = open(pts_name, O_RDWR)) < 0) {
224 pts_name[5] = 'p';
225 close (*master);
226 continue;
229 if (term != NULL)
230 tcsetattr(*slave, TCSANOW, term);
231 if (winsize != NULL)
232 ioctl(*slave, TIOCSWINSZ, winsize);
233 if (name != NULL)
234 strcpy(name, pts_name);
235 return *slave;
238 errno = EMFILE;
239 return -1;
241 #endif /* HAVE_OPENPTY */
243 /***********************************************************************
244 * getnetbyaddr
246 #ifndef HAVE_GETNETBYADDR
247 struct netent *getnetbyaddr(unsigned long net, int type)
249 errno = ENOSYS;
250 return NULL;
252 #endif /* defined(HAVE_GETNETBYNAME) */
254 /***********************************************************************
255 * getnetbyname
257 #ifndef HAVE_GETNETBYNAME
258 struct netent *getnetbyname(const char *name)
260 errno = ENOSYS;
261 return NULL;
263 #endif /* defined(HAVE_GETNETBYNAME) */
265 /***********************************************************************
266 * getprotobyname
268 #ifndef HAVE_GETPROTOBYNAME
269 struct protoent *getprotobyname(const char *name)
271 errno = ENOSYS;
272 return NULL;
274 #endif /* !defined(HAVE_GETPROTOBYNAME) */
276 /***********************************************************************
277 * getprotobynumber
279 #ifndef HAVE_GETPROTOBYNUMBER
280 struct protoent *getprotobynumber(int proto)
282 errno = ENOSYS;
283 return NULL;
285 #endif /* !defined(HAVE_GETPROTOBYNUMBER) */
287 /***********************************************************************
288 * getservbyport
290 #ifndef HAVE_GETSERVBYPORT
291 struct servent *getservbyport(int port, const char *proto)
293 errno = ENOSYS;
294 return NULL;
296 #endif /* !defined(HAVE_GETSERVBYPORT) */
298 /***********************************************************************
299 * getsockopt
301 #ifndef HAVE_GETSOCKOPT
302 int getsockopt(int socket, int level, int option_name,
303 void *option_value, size_t *option_len)
305 errno = ENOSYS;
306 return -1;
308 #endif /* !defined(HAVE_GETSOCKOPT) */
310 /***********************************************************************
311 * inet_network
313 #ifndef HAVE_INET_NETWORK
314 unsigned long inet_network(const char *cp)
316 errno = ENOSYS;
317 return 0;
319 #endif /* defined(HAVE_INET_NETWORK) */
321 /***********************************************************************
322 * settimeofday
324 #ifndef HAVE_SETTIMEOFDAY
325 int settimeofday(struct timeval *tp, void *reserved)
327 tp->tv_sec = 0;
328 tp->tv_usec = 0;
330 errno = ENOSYS;
331 return -1;
333 #endif /* HAVE_SETTIMEOFDAY */
335 /***********************************************************************
336 * statfs
338 #ifndef HAVE_STATFS
339 int statfs(const char *name, struct statfs *info)
341 #ifdef __BEOS__
342 dev_t mydev;
343 fs_info fsinfo;
345 if(!info) {
346 errno = ENOSYS;
347 return -1;
350 if ((mydev = dev_for_path(name)) < 0) {
351 errno = ENOSYS;
352 return -1;
355 if (fs_stat_dev(mydev,&fsinfo) < 0) {
356 errno = ENOSYS;
357 return -1;
360 info->f_bsize = fsinfo.block_size;
361 info->f_blocks = fsinfo.total_blocks;
362 info->f_bfree = fsinfo.free_blocks;
363 return 0;
364 #else /* defined(__BEOS__) */
365 errno = ENOSYS;
366 return -1;
367 #endif /* defined(__BEOS__) */
369 #endif /* !defined(HAVE_STATFS) */
372 /***********************************************************************
373 * lstat
375 #ifndef HAVE_LSTAT
376 int lstat(const char *file_name, struct stat *buf)
378 return stat( file_name, buf );
380 #endif /* HAVE_LSTAT */
383 /***********************************************************************
384 * pread
386 * FIXME: this is not thread-safe
388 #ifndef HAVE_PREAD
389 ssize_t pread( int fd, void *buf, size_t count, off_t offset )
391 ssize_t ret;
392 off_t old_pos;
394 if ((old_pos = lseek( fd, 0, SEEK_CUR )) == -1) return -1;
395 if (lseek( fd, offset, SEEK_SET ) == -1) return -1;
396 if ((ret = read( fd, buf, count )) == -1)
398 int err = errno; /* save errno */
399 lseek( fd, old_pos, SEEK_SET );
400 errno = err;
401 return -1;
403 if (lseek( fd, old_pos, SEEK_SET ) == -1) return -1;
404 return ret;
406 #endif /* HAVE_PREAD */
409 /***********************************************************************
410 * pwrite
412 * FIXME: this is not thread-safe
414 #ifndef HAVE_PWRITE
415 ssize_t pwrite( int fd, const void *buf, size_t count, off_t offset )
417 ssize_t ret;
418 off_t old_pos;
420 if ((old_pos = lseek( fd, 0, SEEK_CUR )) == -1) return -1;
421 if (lseek( fd, offset, SEEK_SET ) == -1) return -1;
422 if ((ret = write( fd, buf, count )) == -1)
424 int err = errno; /* save errno */
425 lseek( fd, old_pos, SEEK_SET );
426 errno = err;
427 return -1;
429 if (lseek( fd, old_pos, SEEK_SET ) == -1) return -1;
430 return ret;
432 #endif /* HAVE_PWRITE */
435 /***********************************************************************
436 * getrlimit
438 #ifndef HAVE_GETRLIMIT
439 int getrlimit (int resource, struct rlimit *rlim)
441 return -1; /* FAIL */
443 #endif /* HAVE_GETRLIMIT */
446 #if defined(__svr4__) || defined(__NetBSD__)
447 /***********************************************************************
448 * try_mmap_fixed
450 * The purpose of this routine is to emulate the behaviour of
451 * the Linux mmap() routine if a non-NULL address is passed,
452 * but the MAP_FIXED flag is not set. Linux in this case tries
453 * to place the mapping at the specified address, *unless* the
454 * range is already in use. Solaris, however, completely ignores
455 * the address argument in this case.
457 * As Wine code occasionally relies on the Linux behaviour, e.g. to
458 * be able to map non-relocateable PE executables to their proper
459 * start addresses, or to map the DOS memory to 0, this routine
460 * emulates the Linux behaviour by checking whether the desired
461 * address range is still available, and placing the mapping there
462 * using MAP_FIXED if so.
464 static int try_mmap_fixed (void *addr, size_t len, int prot, int flags,
465 int fildes, off_t off)
467 char * volatile result = NULL;
468 int pagesize = getpagesize();
469 pid_t pid;
471 /* We only try to map to a fixed address if
472 addr is non-NULL and properly aligned,
473 and MAP_FIXED isn't already specified. */
475 if ( !addr )
476 return 0;
477 if ( (uintptr_t)addr & (pagesize-1) )
478 return 0;
479 if ( flags & MAP_FIXED )
480 return 0;
482 /* We use vfork() to freeze all threads of the
483 current process. This allows us to check without
484 race condition whether the desired memory range is
485 already in use. Note that because vfork() shares
486 the address spaces between parent and child, we
487 can actually perform the mapping in the child. */
489 if ( (pid = vfork()) == -1 )
491 perror("try_mmap_fixed: vfork");
492 exit(1);
494 if ( pid == 0 )
496 int i;
497 char vec;
499 /* We call mincore() for every page in the desired range.
500 If any of these calls succeeds, the page is already
501 mapped and we must fail. */
502 for ( i = 0; i < len; i += pagesize )
503 if ( mincore( (caddr_t)addr + i, pagesize, &vec ) != -1 )
504 _exit(1);
506 /* Perform the mapping with MAP_FIXED set. This is safe
507 now, as none of the pages is currently in use. */
508 result = mmap( addr, len, prot, flags | MAP_FIXED, fildes, off );
509 if ( result == addr )
510 _exit(0);
512 if ( result != (void *) -1 ) /* This should never happen ... */
513 munmap( result, len );
515 _exit(1);
518 /* vfork() lets the parent continue only after the child
519 has exited. Furthermore, Wine sets SIGCHLD to SIG_IGN,
520 so we don't need to wait for the child. */
522 return result == addr;
524 #endif
526 /***********************************************************************
527 * wine_anon_mmap
529 * Portable wrapper for anonymous mmaps
531 void *wine_anon_mmap( void *start, size_t size, int prot, int flags )
533 static int fdzero = -1;
535 #ifdef MAP_ANON
536 flags |= MAP_ANON;
537 #else
538 if (fdzero == -1)
540 if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1)
542 perror( "/dev/zero: open" );
543 exit(1);
546 #endif /* MAP_ANON */
548 #ifdef MAP_SHARED
549 flags &= ~MAP_SHARED;
550 #endif
552 /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */
553 #ifdef MAP_PRIVATE
554 flags |= MAP_PRIVATE;
555 #endif
557 #if defined(__svr4__) || defined(__NetBSD__)
558 if ( try_mmap_fixed( start, size, prot, flags, fdzero, 0 ) )
559 return start;
560 #endif
562 return mmap( start, size, prot, flags, fdzero, 0 );
567 * These functions provide wrappers around dlopen() and associated
568 * functions. They work around a bug in glibc 2.1.x where calling
569 * a dl*() function after a previous dl*() function has failed
570 * without a dlerror() call between the two will cause a crash.
571 * They all take a pointer to a buffer that
572 * will receive the error description (from dlerror()). This
573 * parameter may be NULL if the error description is not required.
576 /***********************************************************************
577 * wine_dlopen
579 void *wine_dlopen( const char *filename, int flag, char *error, int errorsize )
581 #ifdef HAVE_DLOPEN
582 void *ret;
583 char *s;
584 dlerror(); dlerror();
585 ret = dlopen( filename, flag );
586 s = dlerror();
587 if (error)
589 strncpy( error, s ? s : "", errorsize );
590 error[errorsize - 1] = '\0';
592 dlerror();
593 return ret;
594 #else
595 if (error)
597 strncpy( error, "dlopen interface not detected by configure", errorsize );
598 error[errorsize - 1] = '\0';
600 return NULL;
601 #endif
604 /***********************************************************************
605 * wine_dlsym
607 void *wine_dlsym( void *handle, const char *symbol, char *error, int errorsize )
609 #ifdef HAVE_DLOPEN
610 void *ret;
611 char *s;
612 dlerror(); dlerror();
613 ret = dlsym( handle, symbol );
614 s = dlerror();
615 if (error)
617 strncpy( error, s ? s : "", errorsize );
618 error[errorsize - 1] = '\0';
620 dlerror();
621 return ret;
622 #else
623 if (error)
625 strncpy( error, "dlopen interface not detected by configure", errorsize );
626 error[errorsize - 1] = '\0';
628 return NULL;
629 #endif
632 /***********************************************************************
633 * wine_dlclose
635 int wine_dlclose( void *handle, char *error, int errorsize )
637 #ifdef HAVE_DLOPEN
638 int ret;
639 char *s;
640 dlerror(); dlerror();
641 ret = dlclose( handle );
642 s = dlerror();
643 if (error)
645 strncpy( error, s ? s : "", errorsize );
646 error[errorsize - 1] = '\0';
648 dlerror();
649 return ret;
650 #else
651 if (error)
653 strncpy( error, "dlopen interface not detected by configure", errorsize );
654 error[errorsize - 1] = '\0';
656 return 1;
657 #endif
660 /***********************************************************************
661 * wine_rewrite_s4tos2
663 * Convert 4 byte Unicode strings to 2 byte Unicode strings in-place.
664 * This is only practical if literal strings are writable.
666 unsigned short* wine_rewrite_s4tos2(const wchar_t* str4 )
668 unsigned short *str2,*s2;
670 if (str4==NULL)
671 return NULL;
673 if ((*str4 & 0xffff0000) != 0) {
674 /* This string has already been converted. Return it as is */
675 return (unsigned short*)str4;
678 /* Note that we can also end up here if the string has a single
679 * character. In such a case we will convert the string over and
680 * over again. But this is harmless.
682 str2=s2=(unsigned short*)str4;
683 do {
684 *s2=(unsigned short)*str4;
685 s2++;
686 } while (*str4++ != L'\0');
688 return str2;
691 #ifndef HAVE_ECVT
693 * NetBSD 1.5 doesn't have ecvt, fcvt, gcvt. We just check for ecvt, though.
694 * Fix/verify these implementations !
697 /***********************************************************************
698 * ecvt
700 char *ecvt (double number, int ndigits, int *decpt, int *sign)
702 static char buf[40]; /* ought to be enough */
703 char *dec;
704 sprintf(buf, "%.*e", ndigits /* FIXME wrong */, number);
705 *sign = (number < 0);
706 dec = strchr(buf, '.');
707 *decpt = (dec) ? (int)dec - (int)buf : -1;
708 return buf;
711 /***********************************************************************
712 * fcvt
714 char *fcvt (double number, int ndigits, int *decpt, int *sign)
716 static char buf[40]; /* ought to be enough */
717 char *dec;
718 sprintf(buf, "%.*e", ndigits, number);
719 *sign = (number < 0);
720 dec = strchr(buf, '.');
721 *decpt = (dec) ? (int)dec - (int)buf : -1;
722 return buf;
725 /***********************************************************************
726 * gcvt
728 * FIXME: uses both E and F.
730 char *gcvt (double number, size_t ndigit, char *buff)
732 sprintf(buff, "%.*E", (int)ndigit, number);
733 return buff;
735 #endif /* HAVE_ECVT */