1 /////////////////////////////////////////////////////////////////////////
2 // $Id: osdep.cc,v 1.18 2008/02/05 22:57:40 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 // Provide definition of library functions that are missing on various
31 // systems. The only reason this is a .cc file rather than a .c file
32 // is so that it can include bochs.h. Bochs.h includes all the required
33 // system headers, with appropriate #ifdefs for different compilers and
39 //////////////////////////////////////////////////////////////////////
40 // Missing library functions. These should work on any platform
42 //////////////////////////////////////////////////////////////////////
45 /* XXX use real snprintf */
46 /* if they don't have snprintf, just use sprintf */
47 int bx_snprintf (char *s
, size_t maxlen
, const char *format
, ...)
52 va_start (arg
, format
);
53 done
= vsprintf (s
, format
, arg
);
59 #endif /* !BX_HAVE_SNPRINTF */
61 #if !BX_HAVE_VSNPRINTF
62 int bx_vsnprintf (char *s
, size_t maxlen
, const char *format
, va_list arg
)
64 return vsprintf (s
, format
, arg
);
66 #endif /* !BX_HAVE_VSNPRINTF*/
68 #if (!BX_HAVE_STRTOULL && !BX_HAVE_STRTOUQ)
69 /* taken from glibc-2.2.2: strtod.c, and stripped down a lot. There are
70 still a few leftover references to decimal points and exponents,
71 but it works for bases 10 and 16 */
73 #define RETURN(val,end) \
74 do { if (endptr != NULL) *endptr = (char *) (end); \
75 return val; } while (0)
78 bx_strtoull (const char *nptr
, char **endptr
, int baseignore
)
80 int negative
; /* The sign of the number. */
81 int exponent
; /* Exponent of the number. */
83 /* Numbers starting `0X' or `0x' have to be processed with base 16. */
86 /* Number of bits currently in result value. */
89 /* Running pointer after the last character processed in the string. */
91 /* Start of significant part of the number. */
92 const char *startp
, *start_of_digits
;
93 /* Total number of digit and number of digits in integer part. */
95 /* Contains the last character read. */
101 /* Prepare number representation. */
106 /* Parse string to get maximal legal prefix. We need the number of
107 characters of the integer part, the fractional part and the exponent. */
109 /* Ignore leading white space. */
114 /* Get sign of the result. */
123 if (c
< '0' || c
> '9')
125 /* It is really a text we do not recognize. */
129 /* First look whether we are faced with a hexadecimal number. */
130 if (c
== '0' && tolower (cp
[1]) == 'x')
132 /* Okay, it is a hexa-decimal number. Remember this and skip
133 the characters. BTW: hexadecimal numbers must not be
140 /* Record the start of the digits, in case we will check their grouping. */
141 start_of_digits
= startp
= cp
;
143 /* Ignore leading zeroes. This helps us to avoid useless computations. */
147 /* If no other digit but a '0' is found the result is 0.0.
148 Return current read pointer. */
149 if ((c
< '0' || c
> '9')
150 && (base
== 16 && (c
< tolower ('a') || c
> tolower ('f')))
151 && (base
== 16 && (cp
== start_of_digits
|| tolower (c
) != 'p'))
152 && (base
!= 16 && tolower (c
) != 'e'))
154 tp
= start_of_digits
;
155 /* If TP is at the start of the digits, there was no correctly
156 grouped prefix of the string; so no number found. */
157 RETURN (0, tp
== start_of_digits
? (base
== 16 ? cp
- 1 : nptr
) : tp
);
160 /* Remember first significant digit and read following characters until the
161 decimal point, exponent character or any non-FP number character. */
166 if ((c
>= '0' && c
<= '9')
167 || (base
== 16 && tolower (c
) >= 'a' && tolower (c
) <= 'f'))
174 /* The whole string is parsed. Store the address of the next character. */
176 *endptr
= (char *) cp
;
181 for (p
=start_of_digits
; p
!=cp
; p
++) {
182 n
= n
* (Bit64s
)base
;
184 c
= (c
>= 'a') ? (10+c
-'a') : c
-'0';
186 //printf ("after shifting in digit %c, n is %lld\n", *p, n);
188 return negative
? -n
: n
;
190 #endif /* !BX_HAVE_STRTOULL */
192 #if BX_TEST_STRTOULL_MAIN
193 /* test driver for strtoull. Do not compile by default. */
194 int main (int argc
, char **argv
)
196 char buf
[256], *endbuf
;
200 printf ("Enter a long int: ");
202 l
= strtoul (buf
, &endbuf
, 10);
203 printf ("As a long, %ld\n", l
);
204 printf ("Endbuf is at buf[%d]\n", endbuf
-buf
);
205 ll
= bx_strtoull (buf
, &endbuf
, 10);
206 printf ("As a long long, %lld\n", ll
);
207 printf ("Endbuf is at buf[%d]\n", endbuf
-buf
);
211 #endif /* BX_TEST_STRTOULL_MAIN */
214 /* XXX use real strdup */
215 char *bx_strdup(const char *str
)
219 temp
= (char*)malloc(strlen(str
)+1);
220 sprintf(temp
, "%s", str
);
223 // Well, I'm sure this isn't how strdup is REALLY implemented,
226 #endif /* !BX_HAVE_STRDUP */
229 char *bx_strrev(char *str
)
236 for (p1
= str
, p2
= str
+ strlen(str
) - 1; p2
> p1
; ++p1
, --p2
) {
243 #endif /* !BX_HAVE_STRREV */
246 namespace std
{extern "C" {char *mktemp(char *tpl
);}}
249 int bx_mkstemp(char *tpl
)
252 return ::open(tpl
, O_RDWR
| O_CREAT
| O_TRUNC
256 , S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IWGRP
);
258 #endif // !BX_HAVE_MKSTEMP
260 //////////////////////////////////////////////////////////////////////
261 // Missing library functions, implemented for MacOS only
262 //////////////////////////////////////////////////////////////////////
265 // these functions are part of MacBochs. They are not intended to be
271 int fd_read(char *buffer
, Bit32u offset
, Bit32u bytes
)
276 param
.ioRefNum
=-5; // Refnum of the floppy disk driver
278 param
.ioPosMode
=fsFromStart
;
279 param
.ioPosOffset
=offset
;
280 param
.ioBuffer
=buffer
;
281 param
.ioReqCount
=bytes
;
282 err
= PBReadSync((union ParamBlockRec
*)(¶m
));
283 return param
.ioActCount
;
286 int fd_write(char *buffer
, Bit32u offset
, Bit32u bytes
)
291 param
.ioRefNum
=-5; // Refnum of the floppy disk driver
293 param
.ioPosMode
=fsFromStart
;
294 param
.ioPosOffset
=offset
;
295 param
.ioBuffer
=buffer
;
296 param
.ioReqCount
=bytes
;
297 err
= PBWriteSync((union ParamBlockRec
*)(¶m
));
298 return param
.ioActCount
;
301 int fd_stat(struct stat
*buf
)
308 err
= DriveStatus(1, &status
);
309 if (status
.diskInPlace
<1 || status
.diskInPlace
> 2)
311 buf
->st_mode
= S_IFCHR
;
314 #endif /* BX_WITH_MACOS */
318 //////////////////////////////////////////////////////////////////////
319 // New functions to replace library functions
320 // with OS-independent versions
321 //////////////////////////////////////////////////////////////////////
323 #if BX_HAVE_REALTIME_USEC
325 static Bit64u last_realtime64_top
= 0;
326 static Bit64u last_realtime64_bottom
= 0;
328 Bit64u
bx_get_realtime64_usec(void)
330 Bit64u new_bottom
= ((Bit64u
) GetTickCount()) & BX_CONST64(0x0FFFFFFFF);
331 if(new_bottom
< last_realtime64_bottom
) {
332 last_realtime64_top
+= BX_CONST64(0x0000000100000000);
334 last_realtime64_bottom
= new_bottom
;
335 Bit64u interim_realtime64
=
336 (last_realtime64_top
& BX_CONST64(0xFFFFFFFF00000000)) |
337 (new_bottom
& BX_CONST64(0x00000000FFFFFFFF));
338 return interim_realtime64
*(BX_CONST64(1000));
340 #elif BX_HAVE_GETTIMEOFDAY
341 Bit64u
bx_get_realtime64_usec(void)
344 gettimeofday(&thetime
,0);
346 mytime
=(Bit64u
)thetime
.tv_sec
*(Bit64u
)1000000+(Bit64u
)thetime
.tv_usec
;