blob: fb07e0e5ce33fac2deb6be6e6f1080dd9b1a9afe [file] [log] [blame]
Alexandre Julliard18f92e71996-07-17 20:02:21 +00001/*
2 * Misc. functions for systems that don't have them
3 *
4 * Copyright 1996 Alexandre Julliard
5 */
6
7#include "config.h"
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +00008
Alexandre Julliard3b96efc1999-09-04 14:36:02 +00009#include <ctype.h>
Marcus Meissner3b092841999-02-20 16:46:39 +000010#include <stdio.h>
David Luyeree517e81999-02-28 12:27:56 +000011#include <string.h>
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +000012#include <unistd.h>
Alexandre Julliardca22b331996-07-12 19:02:39 +000013#include <sys/types.h>
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000014#include <sys/time.h>
Alexandre Julliard8da12c41999-01-17 16:55:11 +000015#include <sys/stat.h>
16#include <sys/ioctl.h>
17#include <errno.h>
18#include <fcntl.h>
19#include <termios.h>
Marcus Meissner592ba101999-01-20 14:18:55 +000020#ifdef HAVE_LIBIO_H
21# include <libio.h>
22#endif
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000023
24#ifndef HAVE_USLEEP
Alexandre Julliard349a9531997-02-02 19:01:52 +000025#ifdef __EMX__
26unsigned int usleep (unsigned int useconds) { DosSleep(useconds); }
27#else
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000028unsigned int usleep (unsigned int useconds)
29{
30 struct timeval delay;
31
32 delay.tv_sec = 0;
33 delay.tv_usec = useconds;
34
Alexandre Julliardca22b331996-07-12 19:02:39 +000035 select( 0, 0, 0, 0, &delay );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000036 return 0;
37}
Alexandre Julliard349a9531997-02-02 19:01:52 +000038#endif
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000039#endif /* HAVE_USLEEP */
40
Alexandre Julliard18f92e71996-07-17 20:02:21 +000041#ifndef HAVE_MEMMOVE
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000042void *memmove( void *dest, const void *src, unsigned int len )
Alexandre Julliard18f92e71996-07-17 20:02:21 +000043{
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000044 register char *dst = dest;
45
Alexandre Julliard18f92e71996-07-17 20:02:21 +000046 /* Use memcpy if not overlapping */
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000047 if ((dst + len <= (char *)src) || ((char *)src + len <= dst))
Alexandre Julliard18f92e71996-07-17 20:02:21 +000048 {
49 memcpy( dst, src, len );
50 }
51 /* Otherwise do it the hard way (FIXME: could do better than this) */
52 else if (dst < src)
53 {
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000054 while (len--) *dst++ = *((char *)src)++;
Alexandre Julliard18f92e71996-07-17 20:02:21 +000055 }
56 else
57 {
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000058 dst += len - 1;
Alexandre Julliard18f92e71996-07-17 20:02:21 +000059 src = (char *)src + len - 1;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000060 while (len--) *dst-- = *((char *)src)--;
Alexandre Julliard18f92e71996-07-17 20:02:21 +000061 }
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000062 return dest;
Alexandre Julliard18f92e71996-07-17 20:02:21 +000063}
64#endif /* HAVE_MEMMOVE */
Alexandre Julliard44ed71f1997-12-21 19:17:50 +000065
66#ifndef HAVE_STRERROR
67const char *strerror( int err )
68{
69 /* Let's hope we have sys_errlist then */
70 return sys_errlist[err];
71}
72#endif /* HAVE_STRERROR */
Alexandre Julliard0623a6f1998-01-18 18:01:49 +000073
74#if !defined(HAVE_CLONE) && defined(__linux__)
75#include <assert.h>
76#include <errno.h>
77#include <syscall.h>
78int clone( int (*fn)(void *), void *stack, int flags, void *arg )
79{
80#ifdef __i386__
81 int ret;
82 void **stack_ptr = (void **)stack;
83 *--stack_ptr = arg; /* Push argument on stack */
84 *--stack_ptr = fn; /* Push function pointer (popped into ebx) */
85 __asm__ __volatile__( "pushl %%ebx\n\t"
86 "movl %2,%%ebx\n\t"
87 "int $0x80\n\t"
88 "popl %%ebx\n\t" /* Contains fn in the child */
89 "testl %%eax,%%eax\n\t"
90 "jnz 0f\n\t"
91 "call *%%ebx\n\t" /* Should never return */
92 "xorl %%eax,%%eax\n\t" /* Just in case it does*/
93 "0:"
94 : "=a" (ret)
Marcus Meissner4ede2961999-02-21 18:18:42 +000095 : "0" (SYS_clone), "r" (flags), "c" (stack_ptr) );
Alexandre Julliard0623a6f1998-01-18 18:01:49 +000096 assert( ret ); /* If ret is 0, we returned from the child function */
97 if (ret > 0) return ret;
98 errno = -ret;
99 return -1;
100#else
101 errno = EINVAL;
102 return -1;
103#endif /* __i386__ */
104}
105#endif /* !HAVE_CLONE && __linux__ */
Alexandre Julliard8da12c41999-01-17 16:55:11 +0000106
107
Alexandre Julliard3b96efc1999-09-04 14:36:02 +0000108#ifndef HAVE_STRCASECMP
109int strcasecmp( const char *str1, const char *str2 )
110{
111 while (*str1 && toupper(*str1) == toupper(*str2)) { str1++; str2++; }
112 return toupper(*str1) - toupper(*str2);
113}
114#endif /* HAVE_STRCASECMP */
115
116#ifndef HAVE_STRNCASECMP
117int strncasecmp( const char *str1, const char *str2, size_t n )
118{
119 int res;
120 if (!n) return 0;
121 while ((--n > 0) && *str1)
122 if ((res = toupper(*str1++) - toupper(*str2++))) return res;
123 return toupper(*str1) - toupper(*str2);
124}
125#endif /* HAVE_STRNCASECMP */
126
Alexandre Julliard8da12c41999-01-17 16:55:11 +0000127/**
128 * It looks like the openpty that comes with glibc in RedHat 5.0
129 * is buggy (second call returns what looks like a dup of 0 and 1
130 * instead of a new pty), this is a generic replacement.
131 */
132/** We will have an autoconf check for this soon... */
133
134int wine_openpty(int *master, int *slave, char *name,
135 struct termios *term, struct winsize *winsize)
136{
137 char *ptr1, *ptr2;
138 char pts_name[512];
139
140 strcpy (pts_name, "/dev/ptyXY");
141
142 for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) {
143 pts_name[8] = *ptr1;
144 for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) {
145 pts_name[9] = *ptr2;
146
147 if ((*master = open(pts_name, O_RDWR)) < 0) {
148 if (errno == ENOENT)
149 return -1;
150 else
151 continue;
152 }
153 pts_name[5] = 't';
154 if ((*slave = open(pts_name, O_RDWR)) < 0) {
155 pts_name[5] = 'p';
156 continue;
157 }
158
159 if (term != NULL)
160 tcsetattr(*slave, TCSANOW, term);
161 if (winsize != NULL)
162 ioctl(*slave, TIOCSWINSZ, winsize);
163 if (name != NULL)
164 strcpy(name, pts_name);
165 return *slave;
166 }
167 }
168 return -1;
169}
170