Watt-32 tcp/ip  2.2 dev-rel.10
misc.h
Go to the documentation of this file.
1 
3 #ifndef _w32_MISC_H
4 #define _w32_MISC_H
5 
6 #ifdef __cplusplus
7 extern "C" {
8 #endif
9 
10 #ifndef __SYS_SWAP_BYTES_H
11 #include <sys/swap.h> /* intel() etc. */
12 #endif
13 
14 #ifndef __SYS_WTIME_H
15 #include <sys/wtime.h> /* struct timeval */
16 #endif
17 
18 #ifndef __SYS_CDEFS_H
19 #include <sys/cdefs.h> /* W32_GCC_VERSION */
20 #endif
21 
22 #if defined(__DJGPP__) || defined(__HIGHC__) || defined(__WATCOMC__) || \
23  defined(__CYGWIN__) || defined(__DMC__)
24  #undef _WIN32 /* Needed for __DMC__ */
25  #include <unistd.h>
26 #endif
27 
28 #if defined(__LCC__) && !defined(W32_LCC_INTRINSICS_INCLUDED)
29  #include <intrinsics.h>
30 #elif defined(__POCC__) && 0
31  #include <intrin.h>
32 #endif
33 
34 /*
35  * Because kbhit() will pull in more conio function that we
36  * really need, use the simple kbhit() variant (without ungetch()
37  * option). This also prevents multiple definition trouble when
38  * linking e.g. PD-curses and Watt-32 library.
39  */
40 #if defined(__DJGPP__)
41  #ifdef __dj_include_conio_h_
42  #error "Don't include <conio.h>"
43  #endif
44  #include <pc.h> /* simple kbhit() */
45 
46 #elif defined(_MSC_VER) && defined(__386__)
47  /*
48  * Problems including <conio.h> from Visual C 4.0
49  */
50  extern int __cdecl kbhit (void);
51 
52 #elif defined(__CYGWIN__)
53  /* Use kbhit(), getch() below */
54 
55 #else /* no other option */
56  #include <conio.h>
57 #endif
58 
59 /*
60  * In misc.c
61  *
62  * Protect internal symbols with a namespace
63  */
64 #define Wait W32_NAMESPACE (Wait)
65 #define valid_addr W32_NAMESPACE (valid_addr)
66 #define is_in_stack W32_NAMESPACE (is_in_stack)
67 #define used_stack W32_NAMESPACE (used_stack)
68 #define os_yield W32_NAMESPACE (os_yield)
69 #define hex_chars_lower W32_NAMESPACE (hex_chars_lower)
70 #define hex_chars_upper W32_NAMESPACE (hex_chars_upper)
71 #define win32_dos_box W32_NAMESPACE (win32_dos_box)
72 #define get_day_num W32_NAMESPACE (get_day_num)
73 #define dword_str W32_NAMESPACE (dword_str)
74 #define shell_exec W32_NAMESPACE (shell_exec)
75 #define assert_fail W32_NAMESPACE (assert_fail)
76 #define ctime_r W32_NAMESPACE (ctime_r)
77 #define localtime_r W32_NAMESPACE (localtime_r)
78 #define strtok_r W32_NAMESPACE (strtok_r)
79 
80 #define memdbg_init W32_NAMESPACE (memdbg_init)
81 #define memdbg_post_init W32_NAMESPACE (memdbg_post_init)
82 #define fopen_excl W32_NAMESPACE (fopen_excl)
83 
84 #if !defined(SEARCH_LIST_DEFINED)
85  #define SEARCH_LIST_DEFINED
86  struct search_list {
87  DWORD type;
88  const char *name;
89  };
90 #endif
91 
92 #define DO_FREE(x) do { \
93  if (x) { \
94  free (x); \
95  x = NULL; \
96  } \
97  } while (0)
98 
99 #if defined(WIN32) || defined(WIN64)
100  #define SOCK_ERRNO(err) WSASetLastError (err)
101 #else
102  #define SOCK_ERRNO(err) errno = _w32_errno = err
103 #endif
104 
105 extern const char hex_chars_lower[];
106 extern const char hex_chars_upper[];
107 
108 extern BOOL win32_dos_box;
109 extern BOOL _watt_fatal_error;
110 extern WORD _watt_os_ver;
111 extern char _watt_assert_buf[256];
112 
113 extern void Wait (unsigned msec);
114 extern BOOL is_in_stack (const void *ptr);
115 extern unsigned used_stack (void);
116 extern BOOL valid_addr (const void *addr, unsigned len);
117 
118 extern void os_yield (void);
119 extern void assert_fail (const char *file, unsigned line, const char *what);
120 
121 extern DWORD get_day_num (void);
122 extern void memdbg_init (void);
123 extern void memdbg_post_init (void);
124 extern FILE *fopen_excl (const char *file, const char *mode);
125 
126 extern char *ctime_r (const time_t *t, char *res);
127 extern struct tm *localtime_r (const time_t *t, struct tm *res);
128 extern char *strtok_r (char *ptr, const char *sep, char **end);
129 
130 extern const char *dos_extender_name (void);
131 extern const char *dword_str (DWORD val);
132 
133 /*
134  * A patch from Ozkan Sezer <sezeroz@gmail.com>.
135  * Using 'access()' in djgpp pulls in unnecessary big dependencies, so
136  * '_chmod()' is smaller and cheaper to use. And plenty good enough.
137  */
138 #if defined(__DJGPP__)
139  #define FILE_EXIST(fname) (_chmod(fname, 0) != -1)
140 #else
141  #define FILE_EXIST(fname) (access(fname, 0) == 0)
142 #endif
143 
144 /*
145  * Yielding while waiting on network reduces CPU-loading.
146  */
147 #if (DOSX & (DJGPP|DOS4GW|PHARLAP|X32VM|WINWATT))
148  #define WATT_YIELD() os_yield() /* includes kbhit() for non-djgpp */
149 #else
150  #define WATT_YIELD() watt_kbhit()
151 #endif
152 
153 #if defined(USE_DEBUG)
154  #define list_lookup W32_NAMESPACE (list_lookup)
155  #define list_lookupX W32_NAMESPACE (list_lookupX)
156  #define MAC_address W32_NAMESPACE (MAC_address)
157  #define unfinished W32_NAMESPACE (unfinished)
158  #define unimplemented W32_NAMESPACE (unimplemented)
159 
160  extern const char *list_lookup (DWORD, const struct search_list *, int);
161  extern const char *list_lookupX (DWORD, const struct search_list *, int);
162  extern const char *MAC_address (const void *addr);
163  extern void unfinished (const char *func, const char *file, unsigned line);
164  extern void unimplemented (const char *func, const char *file, unsigned line);
165 
166  #define UNFINISHED() unfinished (__FUNCTION__, __FILE__, __LINE__)
167  #define UNIMPLEMENTED() unimplemented (__FUNCTION__, __FILE__, __LINE__)
168 #else
169  #define UNFINISHED() ((void)0)
170  #define UNIMPLEMENTED() ((void)0)
171 #endif
172 
173 #if defined(__LARGE__)
174  extern void watt_large_check (const void *sock, int size,
175  const char *file, unsigned line);
176  #define WATT_LARGE_CHECK(sock, size) \
177  watt_large_check(sock, size, __FILE__, __LINE__)
178 #else
179  #define WATT_LARGE_CHECK(sock, size) ((void)0)
180 #endif
181 
182 #if defined(USE_DEBUG) && !defined(NDEBUG)
183  #define WATT_ASSERT(x) do { \
184  if (!(x)) \
185  assert_fail (__FILE__, __LINE__, #x); \
186  } while (0)
187 #else
188  #define WATT_ASSERT(x) ((void)0)
189 #endif
190 
191 /*
192  * Compare function used in qsort() + bsearch().
193  * Cast your function with this.
194  */
195 typedef int (MS_CDECL *CmpFunc) (const void *, const void *);
196 
197 
198 #if defined(WIN32) || defined(WIN64)
199  /*
200  * In winmisc.c
201  */
202  #if defined(__CYGWIN__)
203  /* We use these only under CygWin, but compile them for all Win32 DLLs
204  * since we want e.g. a MingW built watt-32.dll to work with CygWin.
205  */
206  #define kbhit W32_NAMESPACE (kbhit)
207  #define getch W32_NAMESPACE (getch)
208  #define itoa W32_NAMESPACE (itoa)
209  extern int kbhit (void);
210  extern int getch (void);
211  extern char *itoa (int val, char *buf, int radix);
212  #endif
213 
214  #define init_win_misc W32_NAMESPACE (init_win_misc)
215  #define print_thread_times W32_NAMESPACE (print_thread_times)
216  #define wstring_utf8 W32_NAMESPACE (wstring_utf8)
217  #define wstring_acp W32_NAMESPACE (wstring_acp)
218 
219  #define WinDnsQueryA4 W32_NAMESPACE (WinDnsQueryA4)
220  #define WinDnsQueryA6 W32_NAMESPACE (WinDnsQueryA6)
221  #define WinDnsQueryPTR4 W32_NAMESPACE (WinDnsQueryPTR4)
222  #define WinDnsQueryPTR6 W32_NAMESPACE (WinDnsQueryPTR6)
223  #define WinDnsCachePut_A4 W32_NAMESPACE (WinDnsCachePut_A4)
224  #define WinDnsCachePut_A6 W32_NAMESPACE (WinDnsCachePut_A6)
225  #define GetFileVersion W32_NAMESPACE (GetFileVersion)
226 
227  extern HANDLE stdin_hnd, stdout_hnd;
228  extern BOOL _watt_is_win9x, _watt_is_wow64;
229  extern BOOL _watt_is_gui_app, _watt_use_bugtrap;
230 
231  extern CONSOLE_SCREEN_BUFFER_INFO console_info;
232 
233  extern BOOL init_win_misc (void);
234 
235  extern BOOL WinDnsQuery_A4 (const char *name, DWORD *ip4);
236  extern BOOL WinDnsQuery_A6 (const char *name, void *ip6);
237  extern BOOL WinDnsQuery_PTR4 (DWORD ip4, TCHAR *name, size_t size);
238  extern BOOL WinDnsQuery_PTR6 (const void *ip6, TCHAR *name, size_t size);
239  extern BOOL WinDnsCachePut_A4 (const char *name, DWORD ip4);
240  extern BOOL WinDnsCachePut_A6 (const char *name, const void *ip6);
241  extern BOOL GetFileVersion (const char *file, char *buf, size_t buf_len);
242  extern void print_thread_times (HANDLE thread);
243 
244  extern const char *wstring_acp (const wchar_t *in_str);
245  extern const char *wstring_utf8 (const wchar_t *in_str);
246  extern const wchar_t *astring_acp (const char *in_str);
247  extern const wchar_t *astring_utf8 (const char *in_str);
248 
249 #endif /* WIN32 || WIN64 */
250 
251 #if defined(HAVE_UINT64)
252  /*
253  * Format for printing 64-bit types. E.g. "%10"S64_FMT.
254  * Watt-32 code should not try to print a 64-bit number unless
255  * 'HAVE_UINT64' is defined.
256  */
257 
258  /* gcc on Win32 and Win64 are 2 different things regarding
259  * printf-parameters and '-Wformat'. gcc erroneously assumes
260  * that only Microsoft's non-standard formatting is valid on
261  * Windows. Both MinGW and MinGW-w64 provides an ISO compatible
262  * alternative printf(). Hence this:
263  */
264 
265  #if defined(__GNUC__)
266  #if defined(__DJGPP__) || defined(__CYGWIN__)
267  #define S64_FMT "lld"
268  #define U64_FMT "llu"
269  #define S64_SUFFIX(x) (x##LL)
270  #define U64_SUFFIX(x) (x##ULL)
271 
272  #elif defined(__MINGW32__) || defined(__MINGW64__)
273  #define S64_FMT "I64d"
274  #define U64_FMT "I64u"
275  #define S64_SUFFIX(x) (x##LL)
276  #define U64_SUFFIX(x) (x##ULL)
277  #endif
278 
279  #elif defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || \
280  defined(__WATCOMC__) || defined(__LCC__) || defined(__BORLANDC__)
281  #define S64_FMT "I64d"
282  #define U64_FMT "I64u"
283  #define S64_SUFFIX(x) (x##i64)
284  #define U64_SUFFIX(x) (x##Ui64)
285 
286  #else
287  #define S64_FMT "Ld"
288  #define U64_FMT "Lu"
289  #define S64_SUFFIX(x) (x##LL)
290  #define U64_SUFFIX(x) (x##ULL)
291  #endif
292 #endif
293 
294 /* Printing a wide string on Windows.
295  * E.g. printf (buf, "%"WIDESTR_FMT, wide_str);
296  *
297  * Note: we don't build with -D_UNICODE. Hence Ascii formats sometimes
298  * need to print wide-chars using this format.
299  */
300 #if defined(__GNUC__)
301  #define WIDESTR_FMT "S"
302 #else
303  #define WIDESTR_FMT "ws"
304 #endif
305 
306 /* Printing an hex linear address.
307  * Printing av decimal value from the address-bus (e.g. a stack-limit)
308  * E.g. printf (buf, "0x%"ADDR_FMT, ADDR_CAST(ptr));
309  */
310 #if defined(WIN64) && defined(_MSC_VER) /* Untested combo */
311  #define ADDR_FMT "016I64X"
312  #define ADDR_CAST(x) ((uint64)(x))
313  #define ABUS_VAL_FMT U64_FMT
314 
315 #elif defined(WIN64) && defined(__GNUC__) /* MinGW64 usually */
316  #define ADDR_FMT "016I64X" /* Or "016llX" ? */
317  #define ADDR_CAST(x) ((uint64)(x))
318  #define ABUS_VAL_FMT U64_FMT
319 
320 #elif (DOSX != 0)
321  #define ADDR_FMT "08lX"
322  #define ADDR_CAST(x) ((DWORD_PTR)(x)) /* "cl -Wp64" warns here. Ignore it. */
323  #define ABUS_VAL_FMT "u" /* should match an UINT_PTR */
324 
325 #else
326  #define ADDR_FMT "04X" /* real-mode segment or offset. */
327  #define ADDR_CAST(x) ((WORD)(x))
328  #define ABUS_VAL_FMT "u"
329 #endif
330 
331 /*
332  * Setting console colours. Windows only.
333  */
334 #if defined(WIN32) || defined(WIN64)
335  #define SET_ATTR(a) SetConsoleTextAttribute (stdout_hnd, (console_info.wAttributes & ~7) | \
336  (FOREGROUND_INTENSITY | (a)))
337  #define NORM_TEXT() SetConsoleTextAttribute (stdout_hnd, console_info.wAttributes & ~FOREGROUND_INTENSITY)
338  #define HIGH_TEXT() SetConsoleTextAttribute (stdout_hnd, console_info.wAttributes | FOREGROUND_INTENSITY)
339  #define YELLOW_TEXT() SET_ATTR (FOREGROUND_GREEN | FOREGROUND_RED)
340  #define RED_TEXT() SET_ATTR (FOREGROUND_RED)
341 #else
342  #define SET_ATTR(a) ((void)0)
343  #define NORM_TEXT() ((void)0)
344  #define HIGH_TEXT() ((void)0)
345  #define YELLOW_TEXT() ((void)0)
346  #define RED_TEXT() ((void)0)
347 #endif
348 
349 /*
350  * In pc_cbrk.c
351  */
352 extern WORD _watt_handle_cbreak;
353 extern volatile int _watt_cbroke;
354 
355 extern BOOL tcp_cbreak_off (void);
356 extern int set_cbreak (int want_brk);
357 extern void MS_CDECL sig_handler_watt (int sig);
358 
359 #define NEW_BREAK_MODE(old_mode,new_mode) \
360  old_mode = _watt_handle_cbreak, \
361  _watt_handle_cbreak = new_mode, /* enable special interrupt mode */ \
362  _watt_cbroke = 0
363 
364 #define OLD_BREAK_MODE(old_mode) \
365  _watt_cbroke = 0, /* always clean up */ \
366  _watt_handle_cbreak = old_mode
367 
368 
369 #if defined(__MSDOS__)
370  /*
371  * In country.c. Used only in IDNA code.
372  */
373  #define GetCountryCode W32_NAMESPACE (GetCountryCode)
374  #define GetCodePage W32_NAMESPACE (GetCodePage)
375 
376  extern int GetCountryCode (void);
377  extern int GetCodePage (void);
378 
379  /*
380  * In crit.c; Sets up a critical error handler.
381  * No longer used.
382  */
383  #define CRIT_VECT 0x24
384  #define int24_init W32_NAMESPACE (int24_init)
385  #define int24_restore W32_NAMESPACE (int24_restore)
386 
387  extern void int24_init (void);
388  extern void int24_restore (void);
389 
390  /*
391  * In qmsg.c
392  */
393  #define dbg_colour W32_NAMESPACE (dbg_colour)
394  #define dbg_scrpos W32_NAMESPACE (dbg_scrpos)
395  #define dbg_scrstart W32_NAMESPACE (dbg_scrstart)
396  #define dputch W32_NAMESPACE (dputch)
397  #define dmsg W32_NAMESPACE (dmsg)
398  #define dhex1int W32_NAMESPACE (dhex1int)
399  #define dhex2int W32_NAMESPACE (dhex2int)
400  #define dhex4int W32_NAMESPACE (dhex4int)
401  #define dhex8int W32_NAMESPACE (dhex8int)
402 
403  extern BYTE dbg_colour;
404  extern WORD dbg_scrpos;
405  extern WORD dbg_scrstart;
406 
407  extern void dputch (char x);
408  extern void dmsg (const char *s);
409  extern void dhex1int (int x);
410  extern void dhex2int (int x);
411  extern void dhex4int (int x);
412  extern void dhex8int (DWORD x);
413 #endif /* __MSDOS__ */
414 
415 /*
416  * In crc.c
417  */
418 #define crc_init W32_NAMESPACE (crc_init)
419 #define crc_bytes W32_NAMESPACE (crc_bytes)
420 #define crc_table W32_NAMESPACE (crc_table)
421 
422 extern DWORD *crc_table;
423 extern BOOL crc_init (void);
424 extern DWORD crc_bytes (const char *buf, size_t len);
425 
426 /*
427  * In neterr.c
428  */
429 #define short_strerror W32_NAMESPACE (short_strerror)
430 #define pull_neterr_module W32_NAMESPACE (pull_neterr_module)
431 
432 extern int pull_neterr_module;
433 extern const char *short_strerror (int errnum);
434 
435 
436 /*
437  * IREGS structures for pkt_api_entry() etc.
438  * Defines to simplify issuing real-mode interrupts
439  */
440 #if (DOSX & PHARLAP)
441  #define IREGS SWI_REGS /* in Pharlap's <pharlap.h> */
442  #define r_flags flags
443  #define r_ax eax
444  #define r_bx ebx
445  #define r_dx edx
446  #define r_cx ecx
447  #define r_si esi
448  #define r_di edi
449  #define r_ds ds
450  #define r_es es
451  #define r_fs fs
452  #define r_gs gs
453 
454 #elif (DOSX & DJGPP)
455  #define IREGS __dpmi_regs /* in <dpmi.h> */
456  #define r_flags x.flags
457  #define r_ax d.eax
458  #define r_bx d.ebx
459  #define r_dx d.edx
460  #define r_cx d.ecx
461  #define r_si d.esi
462  #define r_di d.edi
463  #define r_ip x.ip
464  #define r_cs x.cs
465  #define r_ds x.ds
466  #define r_es x.es
467  #define r_fs x.fs
468  #define r_gs x.gs
469  #define r_ss x.ss
470  #define r_sp x.sp
471 
472 #elif (DOSX & X32VM)
473  #define IREGS SWI_REGS /* in "x32vm.h" */
474 
475 #elif defined(__CCDL__)
476  #define IREGS union _dpmi_regs_ /* in <dpmi.h> */
477  #define r_flags h.flags
478  #define r_ax d.eax
479  #define r_bx d.ebx
480  #define r_dx d.edx
481  #define r_cx d.ecx
482  #define r_si d.esi
483  #define r_di d.edi
484  #define r_ds h.ds
485  #define r_es h.es
486  #define r_fs h.fs
487  #define r_gs h.gs
488 
489 #elif (DOSX & (DOS4GW|POWERPAK))
490  typedef struct DPMI_regs {
491  DWORD r_di;
492  DWORD r_si;
493  DWORD r_bp;
494  DWORD reserved;
495  DWORD r_bx;
496  DWORD r_dx;
497  DWORD r_cx;
498  DWORD r_ax;
499  WORD r_flags;
500  WORD r_es, r_ds, r_fs, r_gs;
501  WORD r_ip, r_cs, r_sp, r_ss;
502  } IREGS;
503 
504 #elif defined(__MSDOS__) /* r-mode targets */
505 
506  /* IREGS must have same layout and size as Borland's 'struct REGPACK'
507  * and Watcom's 'union REGPACK'. This is checked in `check_reg_struct()'.
508  */
509  #include <sys/pack_on.h>
510 
511  typedef struct IREGS {
512  WORD r_ax, r_bx, r_cx, r_dx, r_bp;
513  WORD r_si, r_di, r_ds, r_es, r_flags;
514  } IREGS;
515 
516  #include <sys/pack_off.h>
517 
518  #if (defined(_MSC_VER) || defined(__DMC__)) && (DOSX == 0)
519  #define intr W32_NAMESPACE (intr)
520  extern void intr (int int_no, IREGS *regs);
521  #endif
522 #endif
523 
524 #define CARRY_BIT 1 /* LSB in r_flags */
525 
526 
527 /* Macro to ease generation of real-mode interrupts.
528  * `_r' should be `IREGS'.
529  */
530 #if (DOSX & DJGPP)
531  #define GEN_INTERRUPT(_i,_r) __dpmi_int ((int)(_i), _r)
532 
533 #elif (DOSX & (PHARLAP|X32VM))
534  #define GEN_INTERRUPT(_i,_r) _dx_real_int ((UINT)(_i), _r)
535 
536 #elif defined(__CCDL__)
537  #define GEN_INTERRUPT(_i,_r) dpmi_simulate_real_interrupt (_i, _r)
538 
539 #elif (DOSX & (DOS4GW|POWERPAK))
540  #define GEN_INTERRUPT(_i,_r) dpmi_real_interrupt ((_i), _r)
541 
542 #elif (DOSX == 0)
543  #if defined(_MSC_VER) || defined(__DMC__)
544  #define GEN_INTERRUPT(_i,_r) intr ((int)(_i), _r) /* our own version */
545 
546  #elif defined(__WATCOMC__)
547  #define GEN_INTERRUPT(_i,_r) intr ((int)(_i), (union REGPACK*)(_r))
548 
549  #else
550  #define GEN_INTERRUPT(_i,_r) intr ((int)(_i), (struct REGPACK*)(_r))
551  #endif
552 
553 #elif (DOSX & WINWATT)
554  /* No interrupts on Win32 */
555 
556 #else
557  #error Help, unknown target.
558 #endif
559 
560 
561 /*
562  * Fixes for Quick-C and Digital Mars to allow an address as lvalue
563  * in FP_SEG/OFF macros (only used in wdpmi.c)
564  */
565 #if (!DOSX)
566  #if defined(_MSC_VER)
567  /*#pragma warning (disable:4759) */
568  #undef FP_SEG
569  #undef FP_OFF
570  #define FP_SEG(p) ((unsigned)(_segment)(void _far *)(p))
571  #define FP_OFF(p) ((unsigned)(p))
572 
573  #elif defined(__DMC__)
574  #undef FP_SEG
575  #undef FP_OFF
576  #define FP_SEG(p) ((unsigned)((DWORD)(void _far*)(p) >> 16))
577  #define FP_OFF(p) ((unsigned)(p))
578  #endif
579 
580 #elif defined(BORLAND386)
581  #undef FP_SEG
582  #undef FP_OFF
583  #define FP_SEG(p) _DS /* segment of something is always our DS */
584  #define FP_OFF(p) (DWORD)(p)
585 
586 #elif (defined(DMC386) || defined(MSC386)) && defined(__MSDOS__)
587  #undef FP_SEG
588  #undef FP_OFF
589  #define FP_SEG(p) ((unsigned)((DWORD)(void _far*)(p) >> 16))
590  #define FP_OFF(p) ((unsigned)(p))
591 #endif
592 
593 
594 #if (defined(MSC386) || defined(__HIGHC__)) && defined(__MSDOS__)
595  #include <pldos32.h>
596  #define dosdate_t _dosdate_t
597  #define dostime_t _dostime_t
598 #endif
599 
600 #if defined(__DMC__) && defined(__MSDOS__)
601  #define dosdate_t dos_date_t
602  #define dostime_t dos_time_t
603 #endif
604 
605 
606 /*
607  * The Watcom STACK_SET() function is from Dan Kegel's RARP implementation
608  */
609 #if defined(__WATCOMC__) && !defined(__386__) /* 16-bit Watcom */
610  extern void STACK_SET (void far *stack);
611  #pragma aux STACK_SET = \
612  "mov ax, ss" \
613  "mov bx, sp" \
614  "mov ss, dx" \
615  "mov sp, si" \
616  "push ax" \
617  "push bx" \
618  parm [dx si] \
619  modify [ax bx];
620 
621  extern void STACK_RESTORE (void);
622  #pragma aux STACK_RESTORE = \
623  "pop bx" \
624  "pop ax" \
625  "mov ss, ax" \
626  "mov sp, bx" \
627  modify [ax bx];
628 
629  extern void PUSHF_CLI (void);
630  #pragma aux PUSHF_CLI = \
631  "pushf" \
632  "cli";
633 
634  extern void POPF (void);
635  #pragma aux POPF = \
636  "popf";
637 
638 #elif defined(WATCOM386) /* 32-bit Watcom targets */
639  extern void STACK_SET (void *stack);
640  #pragma aux STACK_SET = \
641  "mov ax, ss" \
642  "mov ebx, esp" \
643  "mov cx, ds" \
644  "mov ss, cx" \
645  "mov esp, esi" \
646  "push eax" \
647  "push ebx" \
648  parm [esi] \
649  modify [eax ebx ecx];
650 
651  extern void STACK_RESTORE (void);
652  #pragma aux STACK_RESTORE = \
653  "lss esp, [esp]";
654 
655  extern void PUSHF_CLI (void);
656  #pragma aux PUSHF_CLI = \
657  "pushfd" \
658  "cli";
659 
660  extern void POPF (void);
661  #pragma aux POPF = \
662  "popfd";
663 
664  extern WORD watcom_MY_CS (void);
665  #pragma aux watcom_MY_CS = \
666  "mov ax, cs" \
667  modify [ax];
668 
669  extern WORD watcom_MY_DS(void);
670  #pragma aux watcom_MY_DS = \
671  "mov ax, ds" \
672  modify [ax];
673 
674  extern DWORD GET_LIMIT (WORD sel);
675  #pragma aux GET_LIMIT = \
676  ".386p" \
677  "lsl eax, eax" \
678  parm [eax];
679 
680  #define get_cs_limit() GET_LIMIT (watcom_MY_CS())
681  #define get_ds_limit() GET_LIMIT (watcom_MY_DS())
682 
683 #elif defined(BORLAND386) || defined(DMC386) || defined(MSC386)
684  #define STACK_SET(stk) __asm { mov ax, ss; \
685  mov ebx, esp; \
686  mov cx, ds; \
687  mov ss, cx; \
688  mov esp, stk; \
689  push eax; \
690  push ebx \
691  }
692 
693  #define STACK_RESTORE() __asm lss esp, [esp]
694  #define PUSHF_CLI() __emit__ (0x9C,0xFA) /* pushfd; cli */
695  #define POPF() __emit__ (0x9D) /* popfd */
696 
697  extern DWORD get_ds_limit (void);
698  extern DWORD get_cs_limit (void);
699  extern DWORD get_ss_limit (void); /* only needed for X32 */
700 
701 #elif defined(__CCDL__)
702  #define STACK_SET(stk) asm { mov ax, ss; \
703  mov ebx, esp; \
704  mov cx, ds; \
705  mov ss, cx; \
706  mov esp, stk; \
707  push eax; \
708  push ebx \
709  }
710 
711  #define STACK_RESTORE() asm lss esp, [esp]
712  #define PUSHF_CLI() asm { pushfd; cli }
713  #define POPF() asm popfd
714 
715  extern DWORD get_ds_limit (void);
716  extern DWORD get_cs_limit (void);
717 
718 #elif defined(__HIGHC__)
719  #define PUSHF_CLI() _inline (0x9C,0xFA) /* pushfd; cli */
720  #define POPF() _inline (0x9D) /* popfd */
721 
722 #elif defined(__GNUC__) && defined(__i386__)
723  #define PUSHF_CLI() __asm__ __volatile__ ("pushfl; cli" ::: "memory")
724  #define POPF() __asm__ __volatile__ ("popfl" ::: "memory")
725 
726 #elif (defined(__SMALL__) || defined(__LARGE__)) && !defined(__SMALL32__)
727  #if defined(__BORLANDC__) /* prevent spawning tasm.exe */
728  #define PUSHF_CLI() __emit__ (0x9C,0xFA)
729  #define POPF() __emit__ (0x9D)
730 
731  #elif defined(__DMC__) || (defined(_MSC_VER) && !defined(NO_INLINE_ASM))
732  #define PUSHF_CLI() __asm pushf; \
733  __asm cli
734  #define POPF() __asm popf
735  #endif
736 #endif
737 
738 #if !defined(__WATCOMC__) /* Because these are pragmas on Watcom */
739  #ifndef PUSHF_CLI
740  #define PUSHF_CLI() ((void)0)
741  #endif
742 
743  #ifndef POPF
744  #define POPF() ((void)0)
745  #endif
746 #endif
747 
748 
749 #define BEEP_FREQ 7000
750 #define BEEP_MSEC 1
751 
752 #if defined(WIN32) || defined(WIN64)
753  #define BEEP() MessageBeep (MB_OK)
754 
755 #elif defined(_MSC_VER)
756  #define BEEP() ((void)0) /* doesn't even have delay() :-< */
757 
758 #elif defined(__DMC__)
759  #define BEEP() sound_note (BEEP_FREQ, BEEP_MSEC)
760 
761 #elif defined(__DJGPP__)
762  #define BEEP() do { \
763  sound (BEEP_FREQ); \
764  /* delay() don't */ usleep (1000*BEEP_MSEC); \
765  /* work under NT */ nosound(); \
766  } while (0)
767 
768 #elif defined(__CCDL__)
769  #define BEEP() do { \
770  _sound (BEEP_FREQ); \
771  _delay (BEEP_MSEC); \
772  _nosound(); \
773  } while (0)
774 
775 #elif defined(__HIGHC__) /* Limited <conio.h> */
776  #define BEEP() putchar (7)
777 
778 #else
779  #define BEEP() do { \
780  sound (BEEP_FREQ); \
781  delay (BEEP_MSEC); \
782  nosound(); \
783  } while (0)
784 #endif
785 
786 /* Macros for sleeping. Reference on djgpp's usleep().
787  */
788 #if defined(WIN32) || defined(WIN64)
789  #ifndef __MINGW32__
790  #define usleep(us) Sleep((us)/1000)
791  #endif
792  #define uclock() clock()
793  #define UCLOCKS_PER_SEC CLOCKS_PER_SEC
794  #define uclock_t clock_t
795 
796 #elif defined(__WATCOMC__) || defined(__HIGHC__)
797  #define usleep(us) delay((us)/1000)
798  #define uclock() clock()
799  #define UCLOCKS_PER_SEC CLOCKS_PER_SEC
800  #define uclock_t clock_t
801 #endif
802 
803 
804 /*
805  * Defines for real/pmode-mode interrupt handlers (crit.c, netback.c and pcintr.c)
806  */
807 #if !defined(INTR_PROTOTYPE)
808  #if (DOSX == 0)
809  #if (__WATCOMC__ >= 1200) /* OpenWatcom 1.0+ */
810  #define INTR_PROTOTYPE void interrupt far
811  typedef INTR_PROTOTYPE (*W32_IntrHandler)();
812 
813  #elif defined(__TURBOC__)
814  #define INTR_PROTOTYPE void cdecl interrupt
815  typedef void interrupt (*W32_IntrHandler)(void);
816 
817  #else
818  #define INTR_PROTOTYPE void cdecl interrupt
819  typedef void (cdecl interrupt *W32_IntrHandler)();
820  #endif
821 
822  #elif defined(WIN32) || defined(WIN64)
823  /* No need for this on Windows */
824 
825  #elif defined(WATCOM386)
826  #define INTR_PROTOTYPE void __interrupt __far
827  typedef INTR_PROTOTYPE (*W32_IntrHandler)();
828 
829  #elif defined(__HIGHC__)
830  #define INTR_PROTOTYPE _Far void _CC (_INTERRUPT|_CALLING_CONVENTION)
831  typedef INTR_PROTOTYPE (*W32_IntrHandler)();
832 
833  #elif defined(__DJGPP__)
834  #define INTR_PROTOTYPE void /* simply a SIGALRM handler */
835  typedef void (*W32_IntrHandler)(int);
836 
837  #else
838  /* Figure out what to do for others .. */
839  #endif
840 #endif
841 
842 
843 #if defined(__GNUC__) && defined(__i386__) /* also for gcc -m486 and better */
844  /*
845  * This is not used yet since the benefits/drawbacks are unknown.
846  * Define 32-bit multiplication asm macros.
847  *
848  * umul_ppmm (high_prod, low_prod, multiplier, multiplicand)
849  * multiplies two unsigned long integers multiplier and multiplicand,
850  * and generates a two unsigned word product in high_prod and
851  * low_prod.
852  */
853  #define umul_ppmm(w1,w0,u,v) \
854  __asm__ __volatile__ ( \
855  "mull %3" \
856  : "=a" ((DWORD)(w0)), "=d" ((DWORD)(w1)) \
857  : "%0" ((DWORD)(u)), "rm" ((DWORD)(v)))
858 
859  #define mul32(u,v) ({ union ulong_long w; \
860  umul_ppmm (w.s.hi, w.s.lo, u, v); \
861  w.ull; })
862  /* Use as:
863  * DWORD x,y;
864  * ..
865  * uint64 z = mul32 (x,y);
866  */
867 
868  /* Borrowed from djgpp's <sys/farptr.h>
869  * Needed in pkt_receiver_pm() because djgpp 2.03 doesn't
870  * save/restore FS/GS registers in the rmode callback stub.
871  * Not needed if 'USE_FAST_PKT' is used.
872  */
873  extern __inline__ WORD get_fs_reg (void)
874  {
875  WORD sel;
876  __asm__ __volatile__ (
877  "movw %%fs, %w0"
878  : "=r" (sel) : );
879  return (sel);
880  }
881  extern __inline__ WORD get_gs_reg (void)
882  {
883  WORD sel;
884  __asm__ __volatile__ (
885  "movw %%gs, %w0"
886  : "=r" (sel) : );
887  return (sel);
888  }
889  extern __inline__ void set_fs_reg (WORD sel)
890  {
891  __asm__ __volatile__ (
892  "movw %w0, %%fs"
893  :: "rm" (sel));
894  }
895  extern __inline__ void set_gs_reg (WORD sel)
896  {
897  __asm__ __volatile__ (
898  "movw %w0, %%gs"
899  :: "rm" (sel));
900  }
901 #else
902  #define get_fs_reg() (1)
903  #define get_gs_reg() (1)
904  #define set_fs_reg(fs) ((void)0)
905  #define set_gs_reg(gs) ((void)0)
906 #endif /* __GNUC__ && __i386__ */
907 
908 
909 /*
910  * Macros for formatted printing.
911  *
912  * Note: Some versions of snprintf() return -1 if they truncate
913  * the output. Others return size of truncated output.
914  */
915 #undef SNPRINTF
916 #undef VSNPRINTF
917 
918 #if defined(__CYGWIN__)
919  #define SNPRINTF snprintf
920  #define VSNPRINTF vsnprintf
921 
922 #elif defined(WIN32)
923  #define SNPRINTF _snprintf
924  #define VSNPRINTF _vsnprintf
925 
926 #elif defined(__HIGHC__) || defined(__WATCOMC__)
927  #define SNPRINTF _bprintf
928  #define VSNPRINTF _vbprintf
929 
930 #elif defined(__DMC__) || (defined(_MSC_VER) && (_MSC_VER >= 700))
931  #define SNPRINTF _snprintf
932  #define VSNPRINTF _vsnprintf
933 
934 #elif defined(__DJGPP__) && (__DJGPP_MINOR__ >= 4)
935  #define SNPRINTF snprintf
936  #define VSNPRINTF vsnprintf
937 #endif
938 
939 #define UNCONST(type, var, val) (*(type *)&(var)) = val
940 
941 /*
942  * Some prototypes not found in SP-lint's libraries
943  */
944 #if defined(lint) || defined(_lint)
945  extern char *strupr (char*);
946  extern char *strlwr (char*);
947  extern char *strdup (const char*);
948  extern int stricmp (const char*, const char*);
949  extern int strnicmp (const char*, const char*, size_t);
950  extern char *itoa (int, char*, int);
951  extern void *alloca (size_t);
952  extern int gettimeofday (struct timeval*, struct timezone*);
953  extern int fileno (FILE*);
954  extern int isascii (int);
955  extern void psignal (int, const char*);
956  extern int vsscanf (const char*, const char*, va_list);
957 
958  /*@constant int SIGALRM; @*/
959  /*@constant int SIGTRAP; @*/
960  /*@constant int EINVAL; @*/
961  /*@constant int EFAULT; @*/
962 #endif
963 
964 #ifdef __cplusplus
965 };
966 #endif
967 
968 #endif /* _w32_MISC_H */
969 
void assert_fail(const char *file, unsigned line, const char *what)
Store the "assert fail" text for later before printing it.
Definition: misc.c:652
struct tm * localtime_r(const time_t *t, struct tm *res)
A reentrant localtime().
Definition: misc.c:886
char _watt_assert_buf[256]
Definition: misc.c:62
WORD _watt_os_ver
Definition: misc.c:61
char * ctime_r(const time_t *t, char *res)
A reentrant ctime().
Definition: misc.c:878
DWORD get_day_num(void)
Simplified method of getting days since 1970-01-01.
Definition: misc.c:200
volatile int _watt_cbroke
Definition: pc_cbrk.c:47
const char * dword_str(DWORD val)
Return nicely formatted string "xx,xxx,xxx" with thousand separators (left adjusted).
Definition: misc.c:1002
const char * MAC_address(const void *addr)
Return hexa-decimal string for an 6/7 byte MAC-address.
Definition: misc.c:963
const char * list_lookup(DWORD, const struct search_list *, int)
Search 'list' for 'type' and return it's name.
Definition: misc.c:929
WORD _watt_handle_cbreak
Turn off stack-checking here because stack may be out of bounds.
Definition: pc_cbrk.c:46
void Wait(unsigned msec)
Not all vendors have delay().
Definition: misc.c:776
Definition: wtime.h:38
BOOL _watt_fatal_error
Definition: misc.c:60
FILE * fopen_excl(const char *file, const char *mode)
WIN32: Open an existing file (or create) in share-mode but deny other processes to write to the file...
Definition: misc.c:439
int set_cbreak(int want_brk)
Sets normal and extended BREAK mode.
Definition: pc_cbrk.c:129
Definition: misc.h:511
BOOL win32_dos_box
Definition: misc.c:59
Definition: wtime.h:47
BOOL GetFileVersion(const char *file, char *buf, size_t buf_len)
Returns the version of a PE image (.sys, .dll or .exe).
Definition: winmisc.c:219
void MS_CDECL sig_handler_watt(int sig)
SIGINT/SIGBREAK handler function.
Definition: pc_cbrk.c:73