Release 980927
[wine] / misc / port.c
1 /*
2  * Misc. functions for systems that don't have them
3  *
4  * Copyright 1996 Alexandre Julliard
5  */
6
7 #include "config.h"
8 #include <sys/types.h>
9 #include <sys/time.h>
10
11 #ifndef HAVE_USLEEP
12 #ifdef __EMX__
13 unsigned int usleep (unsigned int useconds) { DosSleep(useconds); }
14 #else
15 unsigned int usleep (unsigned int useconds)
16 {
17     struct timeval delay;
18
19     delay.tv_sec = 0;
20     delay.tv_usec = useconds;
21
22     select( 0, 0, 0, 0, &delay );
23     return 0;
24 }
25 #endif
26 #endif /* HAVE_USLEEP */
27
28 #ifndef HAVE_MEMMOVE
29 void *memmove( void *dest, const void *src, unsigned int len )
30 {
31     register char *dst = dest;
32
33     /* Use memcpy if not overlapping */
34     if ((dst + len <= (char *)src) || ((char *)src + len <= dst))
35     {
36         memcpy( dst, src, len );
37     }
38     /* Otherwise do it the hard way (FIXME: could do better than this) */
39     else if (dst < src)
40     {
41         while (len--) *dst++ = *((char *)src)++;
42     }
43     else
44     {
45         dst += len - 1;
46         src = (char *)src + len - 1;
47         while (len--) *dst-- = *((char *)src)--;
48     }
49     return dest;
50 }
51 #endif  /* HAVE_MEMMOVE */
52
53 #ifndef HAVE_STRERROR
54 const char *strerror( int err )
55 {
56     /* Let's hope we have sys_errlist then */
57     return sys_errlist[err];
58 }
59 #endif  /* HAVE_STRERROR */
60
61 #if !defined(HAVE_CLONE) && defined(__linux__)
62 #include <assert.h>
63 #include <errno.h>
64 #include <syscall.h>
65 int clone( int (*fn)(void *), void *stack, int flags, void *arg )
66 {
67 #ifdef __i386__
68     int ret;
69     void **stack_ptr = (void **)stack;
70     *--stack_ptr = arg;  /* Push argument on stack */
71     *--stack_ptr = fn;   /* Push function pointer (popped into ebx) */
72     __asm__ __volatile__( "pushl %%ebx\n\t"
73                           "movl %2,%%ebx\n\t"
74                           "int $0x80\n\t"
75                           "popl %%ebx\n\t"   /* Contains fn in the child */
76                           "testl %%eax,%%eax\n\t"
77                           "jnz 0f\n\t"
78                           "call *%%ebx\n\t"       /* Should never return */
79                           "xorl %%eax,%%eax\n\t"  /* Just in case it does*/
80                           "0:"
81                           : "=a" (ret)
82                           : "0" (SYS_clone), "g" (flags), "c" (stack_ptr) );
83     assert( ret );  /* If ret is 0, we returned from the child function */
84     if (ret > 0) return ret;
85     errno = -ret;
86     return -1;
87 #else
88     errno = EINVAL;
89     return -1;
90 #endif  /* __i386__ */
91 }
92 #endif  /* !HAVE_CLONE && __linux__ */