ReactOS  0.4.12-dev-916-gffc4e30
misc.c
Go to the documentation of this file.
1 /*
2  * Unit tests for miscellaneous msvcrt functions
3  *
4  * Copyright 2010 Andrew Nguyen
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "wine/test.h"
22 #include <errno.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include "msvcrt.h"
26 #include <process.h>
27 
28 static inline float __port_infinity(void)
29 {
30  static const unsigned __inf_bytes = 0x7f800000;
31  return *(const float *)&__inf_bytes;
32 }
33 #ifdef __REACTOS__
34 #undef INFINITY
35 #endif
36 #define INFINITY __port_infinity()
37 
38 static inline float __port_nan(void)
39 {
40  static const unsigned __nan_bytes = 0x7fc00000;
41  return *(const float *)&__nan_bytes;
42 }
43 #ifdef __REACTOS__
44 #undef NAN
45 #endif
46 #define NAN __port_nan()
47 
48 static inline BOOL almost_equal(double d1, double d2) {
49  if(d1-d2>-1e-30 && d1-d2<1e-30)
50  return TRUE;
51  return FALSE;
52 }
53 
54 static int (__cdecl *prand_s)(unsigned int *);
55 static int (__cdecl *pI10_OUTPUT)(long double, int, int, void*);
56 static int (__cdecl *pstrerror_s)(char *, MSVCRT_size_t, int);
57 static int (__cdecl *p_get_doserrno)(int *);
58 static int (__cdecl *p_get_errno)(int *);
59 static int (__cdecl *p_set_doserrno)(int);
60 static int (__cdecl *p_set_errno)(int);
61 static void (__cdecl *p__invalid_parameter)(const wchar_t*,
62  const wchar_t*, const wchar_t*, unsigned int, uintptr_t);
63 static void (__cdecl *p_qsort_s)(void*, MSVCRT_size_t, MSVCRT_size_t,
64  int (__cdecl*)(void*, const void*, const void*), void*);
65 static double (__cdecl *p_atan)(double);
66 static double (__cdecl *p_exp)(double);
67 static double (__cdecl *p_tanh)(double);
68 static void *(__cdecl *p_lfind_s)(const void*, const void*, unsigned int*,
69  size_t, int (__cdecl *)(void*, const void*, const void*), void*);
70 
71 static void init(void)
72 {
73  HMODULE hmod = GetModuleHandleA("msvcrt.dll");
74 
75  prand_s = (void *)GetProcAddress(hmod, "rand_s");
76  pI10_OUTPUT = (void*)GetProcAddress(hmod, "$I10_OUTPUT");
77  pstrerror_s = (void *)GetProcAddress(hmod, "strerror_s");
78  p_get_doserrno = (void *)GetProcAddress(hmod, "_get_doserrno");
79  p_get_errno = (void *)GetProcAddress(hmod, "_get_errno");
80  p_set_doserrno = (void *)GetProcAddress(hmod, "_set_doserrno");
81  p_set_errno = (void *)GetProcAddress(hmod, "_set_errno");
82  p__invalid_parameter = (void *)GetProcAddress(hmod, "_invalid_parameter");
83  p_qsort_s = (void *)GetProcAddress(hmod, "qsort_s");
84  p_atan = (void *)GetProcAddress(hmod, "atan");
85  p_exp = (void *)GetProcAddress(hmod, "exp");
86  p_tanh = (void *)GetProcAddress(hmod, "tanh");
87  p_lfind_s = (void *)GetProcAddress(hmod, "_lfind_s");
88 }
89 
90 static void test_rand_s(void)
91 {
92  int ret;
93  unsigned int rand;
94 
95  if (!prand_s)
96  {
97  win_skip("rand_s is not available\n");
98  return;
99  }
100 
101  errno = EBADF;
102  ret = prand_s(NULL);
103  ok(ret == EINVAL, "Expected rand_s to return EINVAL, got %d\n", ret);
104  ok(errno == EINVAL, "Expected errno to return EINVAL, got %d\n", errno);
105 
106  ret = prand_s(&rand);
107  ok(ret == 0, "Expected rand_s to return 0, got %d\n", ret);
108 }
109 
110 typedef struct _I10_OUTPUT_data {
111  short pos;
112  char sign;
114  char str[100];
116 
117 typedef struct _I10_OUTPUT_test {
118  long double d;
119  int size;
120  int flags;
121 
123  int ret;
124  const char *remain;
126 
128  /* arg3 = 0 */
129  { 0.0, 10, 0, {0, ' ', 1, "0"}, 1, "" },
130  { 1.0, 10, 0, {1, ' ', 1, "1"}, 1, "000000009" },
131  { -1.0, 10, 0, {1, '-', 1, "1"}, 1, "000000009" },
132  { 1.23, 10, 0, {1, ' ', 3, "123"}, 1, "0000009" },
133  { 1e13, 10, 0, {14, ' ', 1, "1"}, 1, "000000009" },
134  { 1e30, 30, 0, {31, ' ', 21, "100000000000000001988"}, 1, "" },
135  { 1e-13, 10, 0, {-12, ' ', 1, "1"}, 1, "000000000" },
136  { 0.25, 10, 0, {0, ' ', 2, "25"}, 1, "00000000" },
137  { 1.0000001, 10, 0, {1, ' ', 8, "10000001"}, 1, "00" },
138  /* arg3 = 1 */
139  { 0.0, 10, 1, {0, ' ', 1, "0"}, 1, "" },
140  { 1.0, 10, 1, {1, ' ', 1, "1"}, 1, "0000000009" },
141  { -1.0, 10, 1, {1, '-', 1, "1"}, 1, "0000000009" },
142  { 1.23, 10, 1, {1, ' ', 3, "123"}, 1, "00000009" },
143  { 1e13, 10, 1, {14, ' ', 1, "1"}, 1, "00000000000000000009" },
144  { 1e30, 30, 1, {31, ' ', 21, "100000000000000001988"}, 1, "" },
145  { 1e-13, 10, 1, {0, ' ', 1, "0"}, 1, "" },
146  { 1e-7, 10, 1, {-6, ' ', 1, "1"}, 1, "09" },
147  { 0.25, 10, 1, {0, ' ', 2, "25"}, 1, "00000000" },
148  { 1.0000001, 10, 1, {1, ' ', 8, "10000001"}, 1, "000" },
149  /* too small buffer */
150  { 0.0, 0, 0, {0, ' ', 1, "0"}, 1, "" },
151  { 0.0, 0, 1, {0, ' ', 1, "0"}, 1, "" },
152  { 123.0, 2, 0, {3, ' ', 2, "12"}, 1, "" },
153  { 123.0, 0, 0, {0, ' ', 1, "0"}, 1, "" },
154  { 123.0, 2, 1, {3, ' ', 3, "123"}, 1, "09" },
155  { 0.99, 1, 0, {1, ' ', 1, "1"}, 1, "" },
156  { 1264567.0, 2, 0, {7, ' ', 2, "13"}, 1, "" },
157  { 1264567.0, 2, 1, {7, ' ', 7, "1264567"}, 1, "00" },
158  { 1234567891.0, 2, 1, {10, ' ', 10, "1234567891"}, 1, "09" }
159 };
160 
161 static void test_I10_OUTPUT(void)
162 {
164  int i, j = sizeof(long double), ret;
165 
166  if(!pI10_OUTPUT) {
167  win_skip("I10_OUTPUT not available\n");
168  return;
169  }
170  if (j != 12)
171  trace("sizeof(long double) = %d on this machine\n", j);
172 
173  for(i=0; i<ARRAY_SIZE(I10_OUTPUT_tests); i++) {
174  memset(out.str, '#', sizeof(out.str));
175 
176  if (sizeof(long double) == 12)
178  else {
179  /* MS' "long double" is an 80 bit FP that takes 12 bytes*/
180  typedef struct { ULONG x80[3]; } uld; /* same calling convention */
181  union { long double ld; uld ld12; } fp80;
182  int (__cdecl *pI10_OUTPUT12)(uld, int, int, void*) = (void*)pI10_OUTPUT;
183  fp80.ld = I10_OUTPUT_tests[i].d;
184  ret = pI10_OUTPUT12(fp80.ld12, I10_OUTPUT_tests[i].size, I10_OUTPUT_tests[i].flags, &out);
185  }
186  ok(ret == I10_OUTPUT_tests[i].ret, "%d: ret = %d\n", i, ret);
187  ok(out.pos == I10_OUTPUT_tests[i].out.pos, "%d: out.pos = %hd\n", i, out.pos);
188  ok(out.sign == I10_OUTPUT_tests[i].out.sign, "%d: out.size = %c\n", i, out.sign);
189  ok(out.len == I10_OUTPUT_tests[i].out.len, "%d: out.len = %d\n", i, (int)out.len);
190  ok(!strcmp(out.str, I10_OUTPUT_tests[i].out.str), "%d: out.str = %s\n", i, out.str);
191 
192  j = strlen(I10_OUTPUT_tests[i].remain);
193  todo_wine_if(j && I10_OUTPUT_tests[i].remain[j-1]=='9')
194  ok(!strncmp(out.str+out.len+1, I10_OUTPUT_tests[i].remain, j),
195  "%d: &out.str[%d] = %.25s...\n", i, out.len+1, out.str+out.len+1);
196 
197  for(j=out.len+strlen(I10_OUTPUT_tests[i].remain)+1; j<sizeof(out.str); j++)
198  if(out.str[j] != '#')
199  ok(0, "%d: out.str[%d] = %c (expected \'#\')\n", i, j, out.str[j]);
200  }
201 }
202 
203 static void test_strerror_s(void)
204 {
205  int ret;
206  char buf[256];
207 
208  if (!pstrerror_s)
209  {
210  win_skip("strerror_s is not available\n");
211  return;
212  }
213 
214  errno = EBADF;
215  ret = pstrerror_s(NULL, 0, 0);
216  ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret);
217  ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
218 
219  errno = EBADF;
220  ret = pstrerror_s(NULL, sizeof(buf), 0);
221  ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret);
222  ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
223 
224  memset(buf, 'X', sizeof(buf));
225  errno = EBADF;
226  ret = pstrerror_s(buf, 0, 0);
227  ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret);
228  ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
229  ok(buf[0] == 'X', "Expected output buffer to be untouched\n");
230 
231  memset(buf, 'X', sizeof(buf));
232  ret = pstrerror_s(buf, 1, 0);
233  ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
234  ok(strlen(buf) == 0, "Expected output buffer to be null terminated\n");
235 
236  memset(buf, 'X', sizeof(buf));
237  ret = pstrerror_s(buf, 2, 0);
238  ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
239  ok(strlen(buf) == 1, "Expected output buffer to be truncated\n");
240 
241  memset(buf, 'X', sizeof(buf));
242  ret = pstrerror_s(buf, sizeof(buf), 0);
243  ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
244 
245  memset(buf, 'X', sizeof(buf));
246  ret = pstrerror_s(buf, sizeof(buf), -1);
247  ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
248 }
249 
250 static void test__get_doserrno(void)
251 {
252  int ret, out;
253 
254  if (!p_get_doserrno)
255  {
256  win_skip("_get_doserrno is not available\n");
257  return;
258  }
259 
261  errno = EBADF;
262  ret = p_get_doserrno(NULL);
263  ok(ret == EINVAL, "Expected _get_doserrno to return EINVAL, got %d\n", ret);
264  ok(_doserrno == ERROR_INVALID_CMM, "Expected _doserrno to be ERROR_INVALID_CMM, got %d\n", _doserrno);
265  ok(errno == EBADF, "Expected errno to be EBADF, got %d\n", errno);
266 
268  errno = EBADF;
269  out = 0xdeadbeef;
270  ret = p_get_doserrno(&out);
271  ok(ret == 0, "Expected _get_doserrno to return 0, got %d\n", ret);
272  ok(out == ERROR_INVALID_CMM, "Expected output variable to be ERROR_INVALID_CMM, got %d\n", out);
273 }
274 
275 static void test__get_errno(void)
276 {
277  int ret, out;
278 
279  if (!p_get_errno)
280  {
281  win_skip("_get_errno is not available\n");
282  return;
283  }
284 
285  errno = EBADF;
286  ret = p_get_errno(NULL);
287  ok(ret == EINVAL, "Expected _get_errno to return EINVAL, got %d\n", ret);
288  ok(errno == EBADF, "Expected errno to be EBADF, got %d\n", errno);
289 
290  errno = EBADF;
291  out = 0xdeadbeef;
292  ret = p_get_errno(&out);
293  ok(ret == 0, "Expected _get_errno to return 0, got %d\n", ret);
294  ok(out == EBADF, "Expected output variable to be EBADF, got %d\n", out);
295 }
296 
297 static void test__set_doserrno(void)
298 {
299  int ret;
300 
301  if (!p_set_doserrno)
302  {
303  win_skip("_set_doserrno is not available\n");
304  return;
305  }
306 
308  ret = p_set_doserrno(ERROR_FILE_NOT_FOUND);
309  ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret);
311  "Expected _doserrno to be ERROR_FILE_NOT_FOUND, got %d\n", _doserrno);
312 
314  ret = p_set_doserrno(-1);
315  ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret);
316  ok(_doserrno == -1,
317  "Expected _doserrno to be -1, got %d\n", _doserrno);
318 
320  ret = p_set_doserrno(0xdeadbeef);
321  ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret);
322  ok(_doserrno == 0xdeadbeef,
323  "Expected _doserrno to be 0xdeadbeef, got %d\n", _doserrno);
324 }
325 
326 static void test__set_errno(void)
327 {
328  int ret;
329 
330  if (!p_set_errno)
331  {
332  win_skip("_set_errno is not available\n");
333  return;
334  }
335 
336  errno = EBADF;
337  ret = p_set_errno(EINVAL);
338  ok(ret == 0, "Expected _set_errno to return 0, got %d\n", ret);
339  ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
340 
341  errno = EBADF;
342  ret = p_set_errno(-1);
343  ok(ret == 0, "Expected _set_errno to return 0, got %d\n", ret);
344  ok(errno == -1, "Expected errno to be -1, got %d\n", errno);
345 
346  errno = EBADF;
347  ret = p_set_errno(0xdeadbeef);
348  ok(ret == 0, "Expected _set_errno to return 0, got %d\n", ret);
349  ok(errno == 0xdeadbeef, "Expected errno to be 0xdeadbeef, got %d\n", errno);
350 }
351 
352 static void test__popen_child(void)
353 {
354  /* don't execute any tests here */
355  /* ExitProcess is used to set return code of _pclose */
356  printf("child output\n");
357  ExitProcess(0x37);
358 }
359 
360 static void test__popen(const char *name)
361 {
362  FILE *pipe;
363  char buf[1024];
364  int ret;
365 
366  sprintf(buf, "\"%s\" misc popen", name);
367  pipe = _popen(buf, "r");
368  ok(pipe != NULL, "_popen failed with error: %d\n", errno);
369 
370  fgets(buf, sizeof(buf), pipe);
371  ok(!strcmp(buf, "child output\n"), "buf = %s\n", buf);
372 
373  ret = _pclose(pipe);
374  ok(ret == 0x37, "_pclose returned %x, expected 0x37\n", ret);
375 
376  errno = 0xdeadbeef;
377  ret = _pclose((FILE*)0xdeadbeef);
378  ok(ret == -1, "_pclose returned %x, expected -1\n", ret);
379  if(p_set_errno)
380  ok(errno == EBADF, "errno = %d\n", errno);
381 }
382 
383 static void test__invalid_parameter(void)
384 {
385  if(!p__invalid_parameter) {
386  win_skip("_invalid_parameter not available\n");
387  return;
388  }
389 
390  p__invalid_parameter(NULL, NULL, NULL, 0, 0);
391 }
392 
394 {
395  int pos;
396  int *base;
397 
398  struct {
399  int l;
400  int r;
401  } cmp[64];
402 };
403 
404 static int __cdecl qsort_comp(void *ctx, const void *l, const void *r)
405 {
406  struct qsort_test *qt = ctx;
407 
408  if(qt) {
409  ok(qt->pos < 64, "qt->pos = %d\n", qt->pos);
410  ok(qt->cmp[qt->pos].l == (int*)l-qt->base,
411  "%d) l on %ld position\n", qt->pos, (long)((int*)l - qt->base));
412  ok(qt->cmp[qt->pos].r == (int*)r-qt->base,
413  "%d) r on %ld position\n", qt->pos, (long)((int*)r - qt->base));
414  qt->pos++;
415  }
416 
417  return *(int*)l%1000 - *(int*)r%1000;
418 }
419 
420 static void test_qsort_s(void)
421 {
422  static const int nonstable_test[] = {9000, 8001, 7002, 6003, 1003, 5004, 4005, 3006, 2007};
423  int tab[100], i;
424 
425  struct qsort_test small_sort = {
426  0, tab, {
427  {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 4}, {6, 5}, {7, 6},
428  {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 4}, {6, 5},
429  {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 4},
430  {1, 0}, {2, 1}, {3, 2}, {4, 3},
431  {1, 0}, {2, 1}, {3, 2},
432  {1, 0}, {2, 1},
433  {1, 0}
434  }
435  }, small_sort2 = {
436  0, tab, {
437  {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0},
438  {1, 0}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1},
439  {1, 0}, {2, 1}, {3, 2}, {4, 2}, {5, 2},
440  {1, 0}, {2, 1}, {3, 2}, {4, 3},
441  {1, 0}, {2, 1}, {3, 2},
442  {1, 0}, {2, 1},
443  {1, 0}
444  }
445  }, quick_sort = {
446  0, tab, {
447  {0, 4}, {0, 8}, {4, 8},
448  {1, 4}, {2, 4}, {3, 4}, {5, 4}, {6, 4}, {7, 4}, {7, 4}, {6, 4},
449  {6, 4},
450  {8, 7},
451  {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 4}, {6, 4},
452  {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 3},
453  {1, 0}, {2, 1}, {3, 2}, {4, 2},
454  {1, 0}, {2, 1}, {3, 2},
455  {1, 0}, {2, 1},
456  {1, 0}
457  }
458  };
459 
460  if(!p_qsort_s) {
461  win_skip("qsort_s not available\n");
462  return;
463  }
464 
465  for(i=0; i<8; i++) tab[i] = i;
466  p_qsort_s(tab, 8, sizeof(int), qsort_comp, &small_sort);
467  ok(small_sort.pos == 28, "small_sort.pos = %d\n", small_sort.pos);
468  for(i=0; i<8; i++)
469  ok(tab[i] == i, "tab[%d] = %d\n", i, tab[i]);
470 
471  for(i=0; i<8; i++) tab[i] = 7-i;
472  p_qsort_s(tab, 8, sizeof(int), qsort_comp, &small_sort2);
473  ok(small_sort2.pos == 28, "small_sort2.pos = %d\n", small_sort2.pos);
474  for(i=0; i<8; i++)
475  ok(tab[i] == i, "tab[%d] = %d\n", i, tab[i]);
476 
477  for(i=0; i<9; i++) tab[i] = i;
478  tab[5] = 1;
479  tab[6] = 2;
480  p_qsort_s(tab, 9, sizeof(int), qsort_comp, &quick_sort);
481  ok(quick_sort.pos == 34, "quick_sort.pos = %d\n", quick_sort.pos);
482 
483  /* show that qsort is not stable */
484  for(i=0; i<9; i++) tab[i] = 8-i + 1000*(i+1);
485  tab[0] = 1003;
486  p_qsort_s(tab, 9, sizeof(int), qsort_comp, NULL);
487  for(i=0; i<9; i++)
488  ok(tab[i] == nonstable_test[i], "tab[%d] = %d, expected %d\n", i, tab[i], nonstable_test[i]);
489 
490  /* check if random data is sorted */
491  srand(0);
492  for(i=0; i<100; i++) tab[i] = rand()%1000;
493  p_qsort_s(tab, 100, sizeof(int), qsort_comp, NULL);
494  for(i=1; i<100; i++)
495  ok(tab[i-1] <= tab[i], "data sorted incorrectly on position %d: %d <= %d\n", i, tab[i-1], tab[i]);
496 
497  /* test if random permutation is sorted correctly */
498  for(i=0; i<100; i++) tab[i] = i;
499  for(i=0; i<100; i++) {
500  int b = rand()%100;
501  int e = rand()%100;
502 
503  if(b == e) continue;
504  tab[b] ^= tab[e];
505  tab[e] ^= tab[b];
506  tab[b] ^= tab[e];
507  }
508  p_qsort_s(tab, 100, sizeof(int), qsort_comp, NULL);
509  for(i=0; i<100; i++)
510  ok(tab[i] == i, "data sorted incorrectly on position %d: %d\n", i, tab[i]);
511 }
512 
513 static void test_math_functions(void)
514 {
515  double ret;
516 
517  errno = 0xdeadbeef;
518  p_atan(NAN);
519  ok(errno == EDOM, "errno = %d\n", errno);
520 
521  errno = 0xdeadbeef;
522  ret = p_atan(INFINITY);
523  ok(almost_equal(ret, 1.57079632679489661923), "ret = %lf\n", ret);
524  ok(errno == 0xdeadbeef, "errno = %d\n", errno);
525 
526  errno = 0xdeadbeef;
527  ret = p_atan(-INFINITY);
528  ok(almost_equal(ret, -1.57079632679489661923), "ret = %lf\n", ret);
529  ok(errno == 0xdeadbeef, "errno = %d\n", errno);
530 
531  errno = 0xdeadbeef;
532  p_tanh(NAN);
533  ok(errno == EDOM, "errno = %d\n", errno);
534 
535  errno = 0xdeadbeef;
536  ret = p_tanh(INFINITY);
537  ok(almost_equal(ret, 1.0), "ret = %lf\n", ret);
538  ok(errno == 0xdeadbeef, "errno = %d\n", errno);
539 
540  errno = 0xdeadbeef;
541  p_exp(NAN);
542  ok(errno == EDOM, "errno = %d\n", errno);
543 
544  errno = 0xdeadbeef;
545  p_exp(INFINITY);
546  ok(errno == 0xdeadbeef, "errno = %d\n", errno);
547 }
548 
549 static void __cdecl test_thread_func(void *end_thread_type)
550 {
551  if (end_thread_type == (void*)1)
552  _endthread();
553  else if (end_thread_type == (void*)2)
554  ExitThread(0);
555  else if (end_thread_type == (void*)3)
556  _endthreadex(0);
557 }
558 
559 static unsigned __stdcall test_thread_func_ex(void *arg)
560 {
561  _endthread();
562  return 0;
563 }
564 
565 static void test_thread_handle_close(void)
566 {
567  HANDLE hThread;
568  DWORD ret;
569 
570  /* _beginthread: handle is not closed on ExitThread and _endthreadex */
572  ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
575  ok(!ret, "ret = %d\n", ret);
576 
577  hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)1);
578  ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
581  ok(!ret, "ret = %d\n", ret);
582 
583  hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)2);
584  ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
585  Sleep(150);
587  ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret);
589  ok(ret, "ret = %d\n", ret);
590 
591  hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)3);
592  ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
593  Sleep(150);
595  ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret);
597  ok(ret, "ret = %d\n", ret);
598 
599  /* _beginthreadex: handle is not closed on _endthread */
601  ok(hThread != NULL, "_beginthreadex failed (%d)\n", errno);
602  Sleep(150);
604  ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret);
606  ok(ret, "ret = %d\n", ret);
607 }
608 
609 static int __cdecl _lfind_s_comp(void *ctx, const void *l, const void *r)
610 {
611  *(int *)ctx = 0xdeadc0de;
612  return *(int *)l - *(int *)r;
613 }
614 
615 static void test__lfind_s(void)
616 {
617  static const int tests[] = {9000, 8001, 7002, 6003, 1003, 5004, 4005, 3006, 2007};
618  unsigned int num;
619  void *found;
620  int ctx;
621  int key;
622 
623  if (!p_lfind_s)
624  {
625  win_skip("_lfind_s is not available\n");
626  return;
627  }
628 
629  key = 1234;
630  num = ARRAY_SIZE(tests);
631 
632  errno = 0xdeadbeef;
633  found = p_lfind_s(NULL, tests, &num, sizeof(int), _lfind_s_comp, NULL);
634  ok(errno == EINVAL, "errno = %d\n", errno);
635  ok(!found, "Expected NULL, got %p\n", found);
636 
637  errno = 0xdeadbeef;
638  found = p_lfind_s(&key, NULL, &num, sizeof(int), _lfind_s_comp, NULL);
639  ok(errno == EINVAL, "errno = %d\n", errno);
640  ok(!found, "Expected NULL, got %p\n", found);
641 
642  errno = 0xdeadbeef;
643  found = p_lfind_s(&key, tests, &num, 0, _lfind_s_comp, NULL);
644  ok(errno == EINVAL, "errno = %d\n", errno);
645  ok(!found, "Expected NULL, got %p\n", found);
646 
647  errno = 0xdeadbeef;
648  found = p_lfind_s(&key, tests, &num, sizeof(int), NULL, NULL);
649  ok(errno == EINVAL, "errno = %d\n", errno);
650  ok(!found, "Expected NULL, got %p\n", found);
651 
652  ctx = -1;
653  key = 9000;
654  errno = 0xdeadbeef;
655  found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
656  ok(errno == 0xdeadbeef, "errno = %d\n", errno);
657  ok(found == tests, "Expected %p, got %p\n", tests, found);
658  ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
659 
660  ctx = -1;
661  key = 2007;
662  errno = 0xdeadbeef;
663  found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
664  ok(errno == 0xdeadbeef, "errno = %d\n", errno);
665  ok(found == tests+8, "Expected %p, got %p\n", tests+8, found);
666  ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
667 
668  ctx = -1;
669  key = 1234;
670  errno = 0xdeadbeef;
671  found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
672  ok(errno == 0xdeadbeef, "errno = %d\n", errno);
673  ok(!found, "Expected NULL, got %p\n", found);
674  ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
675 }
676 
678 {
679  int arg_c;
680  char** arg_v;
681 
682  init();
683 
684  arg_c = winetest_get_mainargs(&arg_v);
685  if(arg_c >= 3) {
686  if(!strcmp(arg_v[2], "popen"))
688  else
689  ok(0, "invalid argument '%s'\n", arg_v[2]);
690 
691  return;
692  }
693 
694  test_rand_s();
695  test_I10_OUTPUT();
696  test_strerror_s();
698  test__get_errno();
700  test__set_errno();
701  test__popen(arg_v[0]);
703  test_qsort_s();
706  test__lfind_s();
707 }
char str[100]
Definition: misc.c:114
const char * remain
Definition: misc.c:124
static int __cdecl _lfind_s_comp(void *ctx, const void *l, const void *r)
Definition: misc.c:609
#define trace(...)
Definition: kmt_test.h:217
struct param_test tests[]
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
_CRTIMP void __cdecl _endthread(void)
Definition: thread.c:95
#define __cdecl
Definition: accygwin.h:79
static void test_strerror_s(void)
Definition: misc.c:203
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
Definition: arc.h:39
static void test_qsort_s(void)
Definition: misc.c:420
_Check_return_opt_ _CRTIMP int __cdecl _pclose(_Inout_ FILE *_File)
struct _I10_OUTPUT_test I10_OUTPUT_test
void __cdecl srand(_In_ unsigned int _Seed)
I10_OUTPUT_data out
Definition: misc.c:122
_Check_return_ _CRTIMP FILE *__cdecl _popen(_In_z_ const char *_Command, _In_z_ const char *_Mode)
static void test__lfind_s(void)
Definition: misc.c:615
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1517
int errno
_CRTIMP uintptr_t __cdecl _beginthreadex(_In_opt_ void *_Security, _In_ unsigned _StackSize, _In_ unsigned(__stdcall *_StartAddress)(void *), _In_opt_ void *_ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned *_ThrdAddr)
static void test__popen(const char *name)
Definition: misc.c:360
Definition: arc.h:36
static int init
Definition: wintirpc.c:33
#define _doserrno
Definition: stdlib.h:143
int * base
Definition: misc.c:396
static int
Definition: misc.c:55
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static void test_I10_OUTPUT(void)
Definition: misc.c:161
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void test_math_functions(void)
Definition: misc.c:513
static float __port_nan(void)
Definition: misc.c:38
#define EDOM
Definition: errno.h:39
unsigned int BOOL
Definition: ntddk_ex.h:94
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
#define e
Definition: ke_i.h:82
_CRTIMP void __cdecl _endthreadex(_In_ unsigned _Retval)
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
static unsigned __stdcall test_thread_func_ex(void *arg)
Definition: misc.c:559
smooth NULL
Definition: ftsmooth.c:416
static void test_thread_handle_close(void)
Definition: misc.c:565
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:327
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define b
Definition: ke_i.h:79
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define ok(value,...)
Definition: CComObject.cpp:34
static void test__set_doserrno(void)
Definition: misc.c:297
r l[0]
Definition: byte_order.h:167
#define todo_wine_if(is_todo)
Definition: test.h:155
static void test__set_errno(void)
Definition: misc.c:326
#define ERROR_INVALID_CMM
Definition: winerror.h:1185
int l
Definition: misc.c:399
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLsizeiptr size
Definition: glext.h:5919
static void test__popen_child(void)
Definition: misc.c:352
static const I10_OUTPUT_test I10_OUTPUT_tests[]
Definition: misc.c:127
#define d
Definition: ke_i.h:81
static void test__get_doserrno(void)
Definition: misc.c:250
static void *static MSVCRT_size_t
Definition: misc.c:56
START_TEST(misc)
Definition: misc.c:416
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static BOOL almost_equal(double d1, double d2)
Definition: misc.c:48
static FILE * out
Definition: regtests2xml.c:44
PVOID HANDLE
Definition: typedefs.h:71
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
#define NAN
Definition: misc.c:46
#define __stdcall
Definition: typedefs.h:25
static int __cdecl qsort_comp(void *ctx, const void *l, const void *r)
Definition: misc.c:404
long double d
Definition: misc.c:118
int winetest_get_mainargs(char ***pargv)
GLbitfield flags
Definition: glext.h:7161
static void test__get_errno(void)
Definition: misc.c:275
int ret
int r
Definition: misc.c:400
HKEY key
Definition: reg.c:42
unsigned char BYTE
Definition: mem.h:68
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
static void test_rand_s(void)
Definition: misc.c:90
struct _I10_OUTPUT_data I10_OUTPUT_data
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
static const wchar_t const wchar_t unsigned uintptr_t
Definition: misc.c:62
int pos
Definition: misc.c:395
#define ARRAY_SIZE(a)
Definition: main.h:24
struct qsort_test::@1605 cmp[64]
static void __cdecl test_thread_func(void *end_thread_type)
Definition: misc.c:549
HANDLE hThread
Definition: wizard.c:27
static void test__invalid_parameter(void)
Definition: misc.c:383
_CRTIMP uintptr_t __cdecl _beginthread(_In_ void(__cdecl *_StartAddress)(void *), _In_ unsigned _StackSize, _In_opt_ void *_ArgList)
Definition: name.c:36
short pos
Definition: misc.c:111
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define GetProcAddress(x, y)
Definition: compat.h:410
#define INFINITE
Definition: serial.h:102
#define memset(x, y, z)
Definition: compat.h:39
#define win_skip
Definition: test.h:141
static void(__cdecl *p__invalid_parameter)(const wchar_t *
static float __port_infinity(void)
Definition: misc.c:28
#define INFINITY
Definition: misc.c:36
Definition: path.c:42
#define printf
Definition: config.h:203