2 * Misc. functions for systems that don't have them
4 * Copyright 1996 Alexandre Julliard
11 #include <be/kernel/fs_info.h>
12 #include <be/kernel/OS.h>
21 #include <sys/types.h>
24 #include <sys/ioctl.h>
28 #ifdef HAVE_SYS_MMAN_H
45 /***********************************************************************
49 unsigned int usleep (unsigned int useconds)
54 #elif defined(__BEOS__)
55 return snooze(useconds);
56 #elif defined(HAVE_SELECT)
59 delay.tv_sec = useconds / 1000000;
60 delay.tv_usec = useconds % 1000000;
62 select( 0, 0, 0, 0, &delay );
64 #else /* defined(__EMX__) || defined(__BEOS__) || defined(HAVE_SELECT) */
67 #endif /* defined(__EMX__) || defined(__BEOS__) || defined(HAVE_SELECT) */
69 #endif /* HAVE_USLEEP */
71 /***********************************************************************
75 void *memmove( void *dest, const void *src, unsigned int len )
77 register char *dst = dest;
79 /* Use memcpy if not overlapping */
80 if ((dst + len <= (char *)src) || ((char *)src + len <= dst))
82 memcpy( dst, src, len );
84 /* Otherwise do it the hard way (FIXME: could do better than this) */
87 while (len--) *dst++ = *((char *)src)++;
92 src = (char *)src + len - 1;
93 while (len--) *dst-- = *((char *)src)--;
97 #endif /* HAVE_MEMMOVE */
99 /***********************************************************************
102 #ifndef HAVE_STRERROR
103 const char *strerror( int err )
105 /* Let's hope we have sys_errlist then */
106 return sys_errlist[err];
108 #endif /* HAVE_STRERROR */
111 /***********************************************************************
114 #ifndef HAVE_GETPAGESIZE
115 size_t getpagesize(void)
118 return sysconf(_SC_PAGESIZE);
120 # error Cannot get the page size on this platform
123 #endif /* HAVE_GETPAGESIZE */
126 /***********************************************************************
129 #if !defined(HAVE_CLONE) && defined(__linux__)
130 int clone( int (*fn)(void *), void *stack, int flags, void *arg )
134 void **stack_ptr = (void **)stack;
135 *--stack_ptr = arg; /* Push argument on stack */
136 *--stack_ptr = fn; /* Push function pointer (popped into ebx) */
137 __asm__ __volatile__( "pushl %%ebx\n\t"
140 "popl %%ebx\n\t" /* Contains fn in the child */
141 "testl %%eax,%%eax\n\t"
143 "xorl %ebp,%ebp\n\t" /* Terminate the stack frames */
144 "call *%%ebx\n\t" /* Should never return */
145 "xorl %%eax,%%eax\n\t" /* Just in case it does*/
148 : "0" (SYS_clone), "r" (flags), "c" (stack_ptr) );
149 assert( ret ); /* If ret is 0, we returned from the child function */
150 if (ret > 0) return ret;
156 #endif /* __i386__ */
158 #endif /* !HAVE_CLONE && __linux__ */
160 /***********************************************************************
163 #ifndef HAVE_STRCASECMP
164 int strcasecmp( const char *str1, const char *str2 )
166 const unsigned char *ustr1 = (const unsigned char *)str1;
167 const unsigned char *ustr2 = (const unsigned char *)str2;
169 while (*ustr1 && toupper(*ustr1) == toupper(*ustr2)) {
173 return toupper(*ustr1) - toupper(*ustr2);
175 #endif /* HAVE_STRCASECMP */
177 /***********************************************************************
180 #ifndef HAVE_STRNCASECMP
181 int strncasecmp( const char *str1, const char *str2, size_t n )
183 const unsigned char *ustr1 = (const unsigned char *)str1;
184 const unsigned char *ustr2 = (const unsigned char *)str2;
188 while ((--n > 0) && *ustr1) {
189 if ((res = toupper(*ustr1) - toupper(*ustr2))) return res;
193 return toupper(*ustr1) - toupper(*ustr2);
195 #endif /* HAVE_STRNCASECMP */
197 /***********************************************************************
200 * It looks like the openpty that comes with glibc in RedHat 5.0
201 * is buggy (second call returns what looks like a dup of 0 and 1
202 * instead of a new pty), this is a generic replacement.
205 * We should have a autoconf check for this.
207 int wine_openpty(int *master, int *slave, char *name,
208 struct termios *term, struct winsize *winsize)
211 return openpty(master, slave, name, term, winsize);
213 const char *ptr1, *ptr2;
216 strcpy (pts_name, "/dev/ptyXY");
218 for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) {
220 for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) {
223 if ((*master = open(pts_name, O_RDWR)) < 0) {
230 if ((*slave = open(pts_name, O_RDWR)) < 0) {
237 tcsetattr(*slave, TCSANOW, term);
239 ioctl(*slave, TIOCSWINSZ, winsize);
241 strcpy(name, pts_name);
250 /***********************************************************************
253 #ifndef HAVE_GETNETBYADDR
254 struct netent *getnetbyaddr(unsigned long net, int type)
259 #endif /* defined(HAVE_GETNETBYNAME) */
261 /***********************************************************************
264 #ifndef HAVE_GETNETBYNAME
265 struct netent *getnetbyname(const char *name)
270 #endif /* defined(HAVE_GETNETBYNAME) */
272 /***********************************************************************
275 #ifndef HAVE_GETPROTOBYNAME
276 struct protoent *getprotobyname(const char *name)
281 #endif /* !defined(HAVE_GETPROTOBYNAME) */
283 /***********************************************************************
286 #ifndef HAVE_GETPROTOBYNUMBER
287 struct protoent *getprotobynumber(int proto)
292 #endif /* !defined(HAVE_GETPROTOBYNUMBER) */
294 /***********************************************************************
297 #ifndef HAVE_GETSERVBYPORT
298 struct servent *getservbyport(int port, const char *proto)
303 #endif /* !defined(HAVE_GETSERVBYPORT) */
305 /***********************************************************************
308 #ifndef HAVE_GETSOCKOPT
309 int getsockopt(int socket, int level, int option_name,
310 void *option_value, size_t *option_len)
315 #endif /* !defined(HAVE_GETSOCKOPT) */
317 /***********************************************************************
320 #ifndef HAVE_INET_NETWORK
321 unsigned long inet_network(const char *cp)
326 #endif /* defined(HAVE_INET_NETWORK) */
328 /***********************************************************************
331 #ifndef HAVE_SETTIMEOFDAY
332 int settimeofday(struct timeval *tp, void *reserved)
340 #endif /* HAVE_SETTIMEOFDAY */
342 /***********************************************************************
346 int statfs(const char *name, struct statfs *info)
357 if ((mydev = dev_for_path(name)) < 0) {
362 if (fs_stat_dev(mydev,&fsinfo) < 0) {
367 info->f_bsize = fsinfo.block_size;
368 info->f_blocks = fsinfo.total_blocks;
369 info->f_bfree = fsinfo.free_blocks;
371 #else /* defined(__BEOS__) */
374 #endif /* defined(__BEOS__) */
376 #endif /* !defined(HAVE_STATFS) */
379 /***********************************************************************
383 int lstat(const char *file_name, struct stat *buf)
385 return stat( file_name, buf );
387 #endif /* HAVE_LSTAT */
389 /***********************************************************************
392 #ifndef HAVE_GETRLIMIT
393 int getrlimit (int resource, struct rlimit *rlim)
395 return -1; /* FAIL */
397 #endif /* HAVE_GETRLIMIT */
399 /***********************************************************************
402 * Portable wrapper for anonymous mmaps
404 void *wine_anon_mmap( void *start, size_t size, int prot, int flags )
406 static int fdzero = -1;
413 if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1)
415 perror( "/dev/zero: open" );
419 #endif /* MAP_ANON */
422 flags &= ~MAP_SHARED;
425 /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */
427 flags |= MAP_PRIVATE;
430 return mmap( start, size, prot, flags, fdzero, 0 );
435 * These functions provide wrappers around dlopen() and associated
436 * functions. They work around a bug in glibc 2.1.x where calling
437 * a dl*() function after a previous dl*() function has failed
438 * without a dlerror() call between the two will cause a crash.
439 * They all take a pointer to a buffer that
440 * will receive the error description (from dlerror()). This
441 * parameter may be NULL if the error description is not required.
444 /***********************************************************************
447 void *wine_dlopen( const char *filename, int flag, char *error, int errorsize )
452 dlerror(); dlerror();
453 ret = dlopen( filename, flag );
457 strncpy( error, s ? s : "", errorsize );
458 error[errorsize - 1] = '\0';
465 strncpy( error, "dlopen interface not detected by configure", errorsize );
466 error[errorsize - 1] = '\0';
472 /***********************************************************************
475 void *wine_dlsym( void *handle, const char *symbol, char *error, int errorsize )
480 dlerror(); dlerror();
481 ret = dlsym( handle, symbol );
485 strncpy( error, s ? s : "", errorsize );
486 error[errorsize - 1] = '\0';
493 strncpy( error, "dlopen interface not detected by configure", errorsize );
494 error[errorsize - 1] = '\0';
500 /***********************************************************************
503 int wine_dlclose( void *handle, char *error, int errorsize )
508 dlerror(); dlerror();
509 ret = dlclose( handle );
513 strncpy( error, s ? s : "", errorsize );
514 error[errorsize - 1] = '\0';
521 strncpy( error, "dlopen interface not detected by configure", errorsize );
522 error[errorsize - 1] = '\0';
528 /***********************************************************************
529 * wine_rewrite_s4tos2
531 * Convert 4 byte Unicode strings to 2 byte Unicode strings in-place.
532 * This is only practical if literal strings are writable.
534 unsigned short* wine_rewrite_s4tos2(const wchar_t* str4 )
536 unsigned short *str2,*s2;
541 if ((*str4 & 0xffff0000) != 0) {
542 /* This string has already been converted. Return it as is */
543 return (unsigned short*)str4;
546 /* Note that we can also end up here if the string has a single
547 * character. In such a case we will convert the string over and
548 * over again. But this is harmless.
550 str2=s2=(unsigned short*)str4;
552 *s2=(unsigned short)*str4;
554 } while (*str4++ != L'\0');
561 * NetBSD 1.5 doesn't have ecvt, fcvt, gcvt. We just check for ecvt, though.
562 * Fix/verify these implementations !
565 /***********************************************************************
568 char *ecvt (double number, int ndigits, int *decpt, int *sign)
570 static buf[40]; /* ought to be enough */
572 sprintf(buf, "%.*e", ndigits /* FIXME wrong */, number);
573 *sign = (number < 0);
574 dec = strchr(buf, '.');
575 *decpt = (dec) ? (int)dec - (int)buf : -1;
579 /***********************************************************************
582 char *fcvt (double number, int ndigits, int *decpt, int *sign)
584 static buf[40]; /* ought to be enough */
586 sprintf(buf, "%.*e", ndigits, number);
587 *sign = (number < 0);
588 dec = strchr(buf, '.');
589 *decpt = (dec) ? (int)dec - (int)buf : -1;
593 /***********************************************************************
596 * FIXME: uses both E and F.
598 char *gcvt (double number, size_t ndigit, char *buff)
600 sprintf(buff, "%.*E", ndigit, number);
603 #endif /* HAVE_ECVT */