source: trunk/libtransmission/file-test.c @ 14332

Last change on this file since 14332 was 14332, checked in by jordan, 8 years ago

(trunk, libT) #4160: apply mike.dld's patch: 4160-05a-file-fmt.patch

File size: 38.4 KB
Line 
1/*
2 * This file Copyright (C) 2013-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id$
8 */
9
10#include <string.h>
11
12#ifndef WIN32
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <unistd.h>
16#else
17 #include <windows.h>
18#endif
19
20#include "transmission.h"
21#include "error.h"
22#include "file.h"
23
24#include "libtransmission-test.h"
25
26#ifndef WIN32
27 #define NATIVE_PATH_SEP "/"
28#else
29 #define NATIVE_PATH_SEP "\\"
30#endif
31
32static tr_session * session;
33
34static char *
35create_test_dir (const char * name)
36{
37  char * const test_dir = tr_buildPath (tr_sessionGetConfigDir (session), name, NULL);
38  tr_sys_dir_create (test_dir, 0, 0777, NULL);
39  return test_dir;
40}
41
42static bool
43create_symlink (const char * dst_path, const char * src_path, bool dst_is_dir)
44{
45#ifndef WIN32
46
47  (void) dst_is_dir;
48
49  return symlink (src_path, dst_path) != -1;
50
51#else
52
53  wchar_t * wide_src_path;
54  wchar_t * wide_dst_path;
55  bool ret = false;
56
57  wide_src_path = tr_win32_utf8_to_native (src_path, -1);
58  wide_dst_path = tr_win32_utf8_to_native (dst_path, -1);
59
60  ret = CreateSymbolicLinkW (wide_dst_path, wide_src_path,
61                             dst_is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0);
62
63  tr_free (wide_dst_path);
64  tr_free (wide_src_path);
65
66  return ret;
67
68#endif
69}
70
71static bool
72create_hardlink (const char * dst_path, const char * src_path)
73{
74#ifndef WIN32
75
76  return link (src_path, dst_path) != -1;
77
78#else
79
80  wchar_t * wide_src_path = tr_win32_utf8_to_native (src_path, -1);
81  wchar_t * wide_dst_path = tr_win32_utf8_to_native (dst_path, -1);
82
83  bool ret = CreateHardLinkW (wide_dst_path, wide_src_path, NULL);
84
85  tr_free (wide_dst_path);
86  tr_free (wide_src_path);
87
88  return ret;
89
90#endif
91}
92
93static void
94clear_path_info (tr_sys_path_info * info)
95{
96  info->type = (tr_sys_path_type_t)-1;
97  info->size = (uint64_t)-1;
98  info->last_modified_at = (time_t)-1;
99}
100
101static bool
102path_contains_no_symlinks (const char * path)
103{
104  const char * p = path;
105
106  while (*p != '\0')
107    {
108      tr_sys_path_info info;
109      char * pathPart;
110      const char * slashPos = strchr (p, '/');
111
112#ifdef WIN32
113
114      const char * backslashPos = strchr (p, '\\');
115      if (slashPos == NULL || (backslashPos != NULL && backslashPos < slashPos))
116        slashPos = backslashPos;
117
118#endif
119
120      if (slashPos == NULL)
121        slashPos = p + strlen (p) - 1;
122
123      pathPart = tr_strndup (path, slashPos - path + 1);
124
125      if (!tr_sys_path_get_info (pathPart, TR_SYS_PATH_NO_FOLLOW, &info, NULL) ||
126          (info.type != TR_SYS_PATH_IS_FILE && info.type != TR_SYS_PATH_IS_DIRECTORY))
127        {
128          tr_free (pathPart);
129          return false;
130        }
131
132      tr_free (pathPart);
133
134      p = slashPos + 1;
135    }
136
137  return true;
138}
139
140static bool
141validate_permissions (const char   * path,
142                      unsigned int   permissions)
143{
144#ifndef _WIN32
145
146  struct stat sb;
147  return stat (path, &sb) != -1 && (sb.st_mode & 0777) == permissions;
148
149#else
150
151  /* No UNIX permissions on Windows */
152  return true;
153
154#endif
155}
156
157static int
158test_get_info (void)
159{
160  char * const test_dir = create_test_dir (__FUNCTION__);
161  tr_sys_path_info info;
162  tr_sys_file_t fd;
163  tr_error * err = NULL;
164  char * path1, * path2;
165
166  path1 = tr_buildPath (test_dir, "a", NULL);
167  path2 = tr_buildPath (test_dir, "b", NULL);
168
169  /* Can't get info of non-existent file/directory */
170  check (!tr_sys_path_get_info (path1, 0, &info, &err));
171  check (err != NULL);
172  tr_error_clear (&err);
173
174  libtest_create_file_with_string_contents (path1, "test");
175
176  /* Good file info */
177  clear_path_info (&info);
178  check (tr_sys_path_get_info (path1, 0, &info, &err));
179  check (err == NULL);
180  check_int_eq (TR_SYS_PATH_IS_FILE, info.type);
181  check_int_eq (4, info.size);
182  check (info.last_modified_at >= time(0) - 1 && info.last_modified_at <= time(0));
183
184  /* Good file info (by handle) */
185  fd = tr_sys_file_open (path1, TR_SYS_FILE_READ, 0, NULL);
186  clear_path_info (&info);
187  check (tr_sys_file_get_info (fd, &info, &err));
188  check (err == NULL);
189  check_int_eq (TR_SYS_PATH_IS_FILE, info.type);
190  check_int_eq (4, info.size);
191  check (info.last_modified_at >= time(0) - 1 && info.last_modified_at <= time(0));
192  tr_sys_file_close (fd, NULL);
193
194  tr_sys_path_remove (path1, NULL);
195
196  /* Good directory info */
197  tr_sys_dir_create (path1, 0, 0777, NULL);
198  clear_path_info (&info);
199  check (tr_sys_path_get_info (path1, 0, &info, &err));
200  check (err == NULL);
201  check_int_eq (TR_SYS_PATH_IS_DIRECTORY, info.type);
202  check (info.size != (uint64_t)-1);
203  check (info.last_modified_at >= time(0) - 1 && info.last_modified_at <= time(0));
204  tr_sys_path_remove (path1, NULL);
205
206  if (create_symlink (path1, path2, false))
207    {
208      /* Can't get info of non-existent file/directory */
209      check (!tr_sys_path_get_info (path1, 0, &info, &err));
210      check (err != NULL);
211      tr_error_clear (&err);
212
213      libtest_create_file_with_string_contents (path2, "test");
214
215      /* Good file info */
216      clear_path_info (&info);
217      check (tr_sys_path_get_info (path1, 0, &info, &err));
218      check (err == NULL);
219      check_int_eq (TR_SYS_PATH_IS_FILE, info.type);
220      check_int_eq (4, info.size);
221      check (info.last_modified_at >= time(0) - 1 && info.last_modified_at <= time(0));
222
223      /* Good file info (by handle) */
224      fd = tr_sys_file_open (path1, TR_SYS_FILE_READ, 0, NULL);
225      clear_path_info (&info);
226      check (tr_sys_file_get_info (fd, &info, &err));
227      check (err == NULL);
228      check_int_eq (TR_SYS_PATH_IS_FILE, info.type);
229      check_int_eq (4, info.size);
230      check (info.last_modified_at >= time(0) - 1 && info.last_modified_at <= time(0));
231      tr_sys_file_close (fd, NULL);
232
233      tr_sys_path_remove (path2, NULL);
234
235      /* Good directory info */
236      tr_sys_dir_create (path2, 0, 0777, NULL);
237      clear_path_info (&info);
238      check (tr_sys_path_get_info (path1, 0, &info, &err));
239      check (err == NULL);
240      check_int_eq (TR_SYS_PATH_IS_DIRECTORY, info.type);
241      check (info.size != (uint64_t)-1);
242      check (info.last_modified_at >= time(0) - 1 && info.last_modified_at <= time(0));
243
244      tr_sys_path_remove (path2, NULL);
245      tr_sys_path_remove (path1, NULL);
246    }
247  else
248    {
249      fprintf (stderr, "WARNING: [%s] unable to run symlink tests\n", __FUNCTION__);
250    }
251
252  tr_free (path2);
253  tr_free (path1);
254
255  tr_free (test_dir);
256  return 0;
257}
258
259static int
260test_path_exists (void)
261{
262  char * const test_dir = create_test_dir (__FUNCTION__);
263  tr_error * err = NULL;
264  char * path1, * path2;
265
266  path1 = tr_buildPath (test_dir, "a", NULL);
267  path2 = tr_buildPath (test_dir, "b", NULL);
268
269  /* Non-existent file does not exist */
270  check (!tr_sys_path_exists (path1, &err));
271  check (err == NULL);
272
273  /* Create file and see that it exists */
274  libtest_create_file_with_string_contents (path1, "test");
275  check (tr_sys_path_exists (path1, &err));
276  check (err == NULL);
277
278  tr_sys_path_remove (path1, NULL);
279
280  /* Create directory and see that it exists */
281  tr_sys_dir_create (path1, 0, 0777, NULL);
282  check (tr_sys_path_exists (path1, &err));
283  check (err == NULL);
284
285  tr_sys_path_remove (path1, NULL);
286
287  if (create_symlink (path1, path2, false))
288    {
289      /* Non-existent file does not exist (via symlink) */
290      check (!tr_sys_path_exists (path1, &err));
291      check (err == NULL);
292
293      /* Create file and see that it exists (via symlink) */
294      libtest_create_file_with_string_contents (path2, "test");
295      check (tr_sys_path_exists (path1, &err));
296      check (err == NULL);
297
298      tr_sys_path_remove (path2, NULL);
299
300      /* Create directory and see that it exists (via symlink) */
301      tr_sys_dir_create (path2, 0, 0777, NULL);
302      check (tr_sys_path_exists (path1, &err));
303      check (err == NULL);
304
305      tr_sys_path_remove (path2, NULL);
306      tr_sys_path_remove (path1, NULL);
307    }
308  else
309    {
310      fprintf (stderr, "WARNING: [%s] unable to run symlink tests\n", __FUNCTION__);
311    }
312
313  tr_free (path2);
314  tr_free (path1);
315
316  tr_free (test_dir);
317  return 0;
318}
319
320static int
321test_path_is_same (void)
322{
323  char * const test_dir = create_test_dir (__FUNCTION__);
324  tr_error * err = NULL;
325  char * path1, * path2, * path3;
326
327  path1 = tr_buildPath (test_dir, "a", NULL);
328  path2 = tr_buildPath (test_dir, "b", NULL);
329  path3 = tr_buildPath (path2, "c", NULL);
330
331  /* Two non-existent files are not the same */
332  check (!tr_sys_path_is_same (path1, path1, &err));
333  check (err == NULL);
334  check (!tr_sys_path_is_same (path1, path2, &err));
335  check (err == NULL);
336
337  /* Two same files are the same */
338  libtest_create_file_with_string_contents (path1, "test");
339  check (tr_sys_path_is_same (path1, path1, &err));
340  check (err == NULL);
341
342  /* Existent and non-existent files are not the same */
343  check (!tr_sys_path_is_same (path1, path2, &err));
344  check (err == NULL);
345  check (!tr_sys_path_is_same (path2, path1, &err));
346  check (err == NULL);
347
348  /* Two separate files (even with same content) are not the same */
349  libtest_create_file_with_string_contents (path2, "test");
350  check (!tr_sys_path_is_same (path1, path2, &err));
351  check (err == NULL);
352
353  tr_sys_path_remove (path1, NULL);
354
355  /* Two same directories are the same */
356  tr_sys_dir_create (path1, 0, 0777, NULL);
357  check (tr_sys_path_is_same (path1, path1, &err));
358  check (err == NULL);
359
360  /* File and directory are not the same */
361  check (!tr_sys_path_is_same (path1, path2, &err));
362  check (err == NULL);
363  check (!tr_sys_path_is_same (path2, path1, &err));
364  check (err == NULL);
365
366  tr_sys_path_remove (path2, NULL);
367
368  /* Two separate directories are not the same */
369  tr_sys_dir_create (path2, 0, 0777, NULL);
370  check (!tr_sys_path_is_same (path1, path2, &err));
371  check (err == NULL);
372
373  tr_sys_path_remove (path1, NULL);
374  tr_sys_path_remove (path2, NULL);
375
376  if (create_symlink (path1, ".", true))
377    {
378      /* Directory and symlink pointing to it are the same */
379      check (tr_sys_path_is_same (path1, test_dir, &err));
380      check (err == NULL);
381      check (tr_sys_path_is_same (test_dir, path1, &err));
382      check (err == NULL);
383
384      /* Non-existent file and symlink are not the same */
385      check (!tr_sys_path_is_same (path1, path2, &err));
386      check (err == NULL);
387      check (!tr_sys_path_is_same (path2, path1, &err));
388      check (err == NULL);
389
390      /* Symlinks pointing to different directories are not the same */
391      create_symlink (path2, "..", true);
392      check (!tr_sys_path_is_same (path1, path2, &err));
393      check (err == NULL);
394      check (!tr_sys_path_is_same (path2, path1, &err));
395      check (err == NULL);
396
397      tr_sys_path_remove (path2, NULL);
398
399      /* Symlinks pointing to same directory are the same */
400      create_symlink (path2, ".", true);
401      check (tr_sys_path_is_same (path1, path2, &err));
402      check (err == NULL);
403
404      tr_sys_path_remove (path2, NULL);
405
406      /* Directory and symlink pointing to another directory are not the same */
407      tr_sys_dir_create (path2, 0, 0777, NULL);
408      check (!tr_sys_path_is_same (path1, path2, &err));
409      check (err == NULL);
410      check (!tr_sys_path_is_same (path2, path1, &err));
411      check (err == NULL);
412
413      /* Symlinks pointing to same directory are the same */
414      create_symlink (path3, "..", true);
415      check (tr_sys_path_is_same (path1, path3, &err));
416      check (err == NULL);
417
418      tr_sys_path_remove (path1, NULL);
419
420      /* File and symlink pointing to directory are not the same */
421      libtest_create_file_with_string_contents (path1, "test");
422      check (!tr_sys_path_is_same (path1, path3, &err));
423      check (err == NULL);
424      check (!tr_sys_path_is_same (path3, path1, &err));
425      check (err == NULL);
426
427      tr_sys_path_remove (path3, NULL);
428
429      /* File and symlink pointing to same file are the same */
430      create_symlink (path3, path1, false);
431      check (tr_sys_path_is_same (path1, path3, &err));
432      check (err == NULL);
433      check (tr_sys_path_is_same (path3, path1, &err));
434      check (err == NULL);
435
436      /* Symlinks pointing to non-existent files are not the same */
437      tr_sys_path_remove (path1, NULL);
438      create_symlink (path1, "missing", false);
439      tr_sys_path_remove (path3, NULL);
440      create_symlink (path3, "missing", false);
441      check (!tr_sys_path_is_same (path1, path3, &err));
442      check (err == NULL);
443      check (!tr_sys_path_is_same (path3, path1, &err));
444      check (err == NULL);
445
446      tr_sys_path_remove (path3, NULL);
447
448      /* Symlinks pointing to same non-existent file are not the same */
449      create_symlink (path3, ".." NATIVE_PATH_SEP "missing", false);
450      check (!tr_sys_path_is_same (path1, path3, &err));
451      check (err == NULL);
452      check (!tr_sys_path_is_same (path3, path1, &err));
453      check (err == NULL);
454
455      /* Non-existent file and symlink pointing to non-existent file are not the same */
456      tr_sys_path_remove (path3, NULL);
457      check (!tr_sys_path_is_same (path1, path3, &err));
458      check (err == NULL);
459      check (!tr_sys_path_is_same (path3, path1, &err));
460      check (err == NULL);
461
462      tr_sys_path_remove (path2, NULL);
463      tr_sys_path_remove (path1, NULL);
464    }
465  else
466    {
467      fprintf (stderr, "WARNING: [%s] unable to run symlink tests\n", __FUNCTION__);
468    }
469
470  tr_free (path3);
471  path3 = tr_buildPath (test_dir, "c", NULL);
472
473  libtest_create_file_with_string_contents (path1, "test");
474
475  if (create_hardlink (path2, path1))
476    {
477      /* File and hardlink to it are the same */
478      check (tr_sys_path_is_same (path1, path2, &err));
479      check (err == NULL);
480
481      /* Two hardlinks to the same file are the same */
482      create_hardlink (path3, path2);
483      check (tr_sys_path_is_same (path2, path3, &err));
484      check (err == NULL);
485      check (tr_sys_path_is_same (path1, path3, &err));
486      check (err == NULL);
487
488      tr_sys_path_remove (path2, NULL);
489
490      check (tr_sys_path_is_same (path1, path3, &err));
491      check (err == NULL);
492
493      tr_sys_path_remove (path3, NULL);
494
495      /* File and hardlink to another file are not the same */
496      libtest_create_file_with_string_contents (path3, "test");
497      create_hardlink (path2, path3);
498      check (!tr_sys_path_is_same (path1, path2, &err));
499      check (err == NULL);
500      check (!tr_sys_path_is_same (path2, path1, &err));
501      check (err == NULL);
502
503      tr_sys_path_remove (path3, NULL);
504      tr_sys_path_remove (path2, NULL);
505    }
506  else
507    {
508      fprintf (stderr, "WARNING: [%s] unable to run hardlink tests\n", __FUNCTION__);
509    }
510
511  if (create_symlink (path2, path1, false) && create_hardlink (path3, path1))
512    {
513      check (tr_sys_path_is_same (path2, path3, &err));
514      check (err == NULL);
515    }
516  else
517    {
518      fprintf (stderr, "WARNING: [%s] unable to run combined symlink and hardlink tests\n", __FUNCTION__);
519    }
520
521  tr_sys_path_remove (path3, NULL);
522  tr_sys_path_remove (path2, NULL);
523  tr_sys_path_remove (path1, NULL);
524
525  tr_free (path3);
526  tr_free (path2);
527  tr_free (path1);
528
529  tr_free (test_dir);
530  return 0;
531}
532
533static int
534test_path_resolve (void)
535{
536  char * const test_dir = create_test_dir (__FUNCTION__);
537  tr_error * err = NULL;
538  char * path1, * path2;
539
540  path1 = tr_buildPath (test_dir, "a", NULL);
541  path2 = tr_buildPath (test_dir, "b", NULL);
542
543  libtest_create_file_with_string_contents (path1, "test");
544  if (create_symlink (path2, path1, false))
545    {
546      char * tmp;
547
548      tmp = tr_sys_path_resolve (path2, &err);
549      check (tmp != NULL);
550      check (err == NULL);
551      check (path_contains_no_symlinks (tmp));
552      tr_free (tmp);
553
554      tr_sys_path_remove (path1, NULL);
555      tr_sys_dir_create (path1, 0, 0755, NULL);
556
557      tmp = tr_sys_path_resolve (path2, &err);
558      check (tmp != NULL);
559      check (err == NULL);
560      check (path_contains_no_symlinks (tmp));
561      tr_free (tmp);
562    }
563  else
564    {
565      fprintf (stderr, "WARNING: [%s] unable to run symlink tests\n", __FUNCTION__);
566    }
567
568  tr_sys_path_remove (path2, NULL);
569  tr_sys_path_remove (path1, NULL);
570
571  tr_free (path2);
572  tr_free (path1);
573
574  tr_free (test_dir);
575  return 0;
576}
577
578static int
579test_path_basename_dirname (void)
580{
581  tr_error * err = NULL;
582  char * name;
583
584  name = tr_sys_path_basename ("/a/b/c", &err);
585  check (name != NULL);
586  check (err == NULL);
587  check_streq ("c", name);
588  tr_free (name);
589
590  name = tr_sys_path_basename ("", &err);
591  check (name != NULL);
592  check (err == NULL);
593  check_streq (".", name);
594  tr_free (name);
595
596  name = tr_sys_path_dirname ("/a/b/c", &err);
597  check (name != NULL);
598  check (err == NULL);
599  check_streq ("/a/b", name);
600  tr_free (name);
601
602  name = tr_sys_path_dirname ("a/b/c", &err);
603  check (name != NULL);
604  check (err == NULL);
605  check_streq ("a/b", name);
606  tr_free (name);
607
608  name = tr_sys_path_dirname ("a", &err);
609  check (name != NULL);
610  check (err == NULL);
611  check_streq (".", name);
612  tr_free (name);
613
614  name = tr_sys_path_dirname ("", &err);
615  check (name != NULL);
616  check (err == NULL);
617  check_streq (".", name);
618  tr_free (name);
619
620#ifdef WIN32
621
622  name = tr_sys_path_basename ("c:\\a\\b\\c", &err);
623  check (name != NULL);
624  check (err == NULL);
625  check_streq ("c", name);
626  tr_free (name);
627
628  name = tr_sys_path_dirname ("C:\\a/b\\c", &err);
629  check (name != NULL);
630  check (err == NULL);
631  check_streq ("C:\\a/b", name);
632  tr_free (name);
633
634  name = tr_sys_path_dirname ("a/b\\c", &err);
635  check (name != NULL);
636  check (err == NULL);
637  check_streq ("a/b", name);
638  tr_free (name);
639
640#endif
641
642  return 0;
643}
644
645static int
646test_path_rename (void)
647{
648  char * const test_dir = create_test_dir (__FUNCTION__);
649  tr_error * err = NULL;
650  char * path1, * path2, * path3;
651
652  path1 = tr_buildPath (test_dir, "a", NULL);
653  path2 = tr_buildPath (test_dir, "b", NULL);
654  path3 = tr_buildPath (path2, "c", NULL);
655
656  libtest_create_file_with_string_contents (path1, "test");
657
658  /* Preconditions */
659  check (tr_sys_path_exists (path1, NULL));
660  check (!tr_sys_path_exists (path2, NULL));
661
662  /* Forward rename works */
663  check (tr_sys_path_rename (path1, path2, &err));
664  check (!tr_sys_path_exists (path1, NULL));
665  check (tr_sys_path_exists (path2, NULL));
666  check (err == NULL);
667
668  /* Backward rename works */
669  check (tr_sys_path_rename (path2, path1, &err));
670  check (tr_sys_path_exists (path1, NULL));
671  check (!tr_sys_path_exists (path2, NULL));
672  check (err == NULL);
673
674  /* Another backward rename [of non-existent file] does not work */
675  check (!tr_sys_path_rename (path2, path1, &err));
676  check (err != NULL);
677  tr_error_clear (&err);
678
679  /* Rename to file which couldn't be created does not work */
680  check (!tr_sys_path_rename (path1, path3, &err));
681  check (err != NULL);
682  tr_error_clear (&err);
683
684  /* Rename of non-existent file does not work */
685  check (!tr_sys_path_rename (path3, path2, &err));
686  check (err != NULL);
687  tr_error_clear (&err);
688
689  libtest_create_file_with_string_contents (path2, "test");
690
691  /* Renaming file does overwrite existing file */
692  check (tr_sys_path_rename (path2, path1, &err));
693  check (err == NULL);
694
695  tr_sys_dir_create (path2, 0, 0777, NULL);
696
697  /* Renaming file does not overwrite existing directory, and vice versa */
698  check (!tr_sys_path_rename (path1, path2, &err));
699  check (err != NULL);
700  tr_error_clear (&err);
701  check (!tr_sys_path_rename (path2, path1, &err));
702  check (err != NULL);
703  tr_error_clear (&err);
704
705  tr_sys_path_remove (path2, NULL);
706
707  tr_free (path3);
708  path3 = tr_buildPath (test_dir, "c", NULL);
709
710  if (create_symlink (path2, path1, false))
711    {
712      /* Preconditions */
713      check (tr_sys_path_exists (path2, NULL));
714      check (!tr_sys_path_exists (path3, NULL));
715      check (tr_sys_path_is_same (path1, path2, NULL));
716
717      /* Rename of symlink works, files stay the same */
718      check (tr_sys_path_rename (path2, path3, &err));
719      check (err == NULL);
720      check (!tr_sys_path_exists (path2, NULL));
721      check (tr_sys_path_exists (path3, NULL));
722      check (tr_sys_path_is_same (path1, path3, NULL));
723
724      tr_sys_path_remove (path3, NULL);
725    }
726  else
727    {
728      fprintf (stderr, "WARNING: [%s] unable to run symlink tests\n", __FUNCTION__);
729    }
730
731  if (create_hardlink (path2, path1))
732    {
733      /* Preconditions */
734      check (tr_sys_path_exists (path2, NULL));
735      check (!tr_sys_path_exists (path3, NULL));
736      check (tr_sys_path_is_same (path1, path2, NULL));
737
738      /* Rename of hardlink works, files stay the same */
739      check (tr_sys_path_rename (path2, path3, &err));
740      check (err == NULL);
741      check (!tr_sys_path_exists (path2, NULL));
742      check (tr_sys_path_exists (path3, NULL));
743      check (tr_sys_path_is_same (path1, path3, NULL));
744
745      tr_sys_path_remove (path3, NULL);
746    }
747  else
748    {
749      fprintf (stderr, "WARNING: [%s] unable to run hardlink tests\n", __FUNCTION__);
750    }
751
752  tr_sys_path_remove (path1, NULL);
753
754  tr_free (path3);
755  tr_free (path2);
756  tr_free (path1);
757
758  tr_free (test_dir);
759  return 0;
760}
761
762static int
763test_path_remove (void)
764{
765  char * const test_dir = create_test_dir (__FUNCTION__);
766  tr_error * err = NULL;
767  char * path1, * path2, * path3;
768
769  path1 = tr_buildPath (test_dir, "a", NULL);
770  path2 = tr_buildPath (test_dir, "b", NULL);
771  path3 = tr_buildPath (path2, "c", NULL);
772
773  /* Can't remove non-existent file/directory */
774  check (!tr_sys_path_exists (path1, NULL));
775  check (!tr_sys_path_remove (path1, &err));
776  check (err != NULL);
777  check (!tr_sys_path_exists (path1, NULL));
778  tr_error_clear (&err);
779
780  /* Removing file works */
781  libtest_create_file_with_string_contents (path1, "test");
782  check (tr_sys_path_exists (path1, NULL));
783  check (tr_sys_path_remove (path1, &err));
784  check (err == NULL);
785  check (!tr_sys_path_exists (path1, NULL));
786
787  /* Removing empty directory works */
788  tr_sys_dir_create (path1, 0, 0777, NULL);
789  check (tr_sys_path_exists (path1, NULL));
790  check (tr_sys_path_remove (path1, &err));
791  check (err == NULL);
792  check (!tr_sys_path_exists (path1, NULL));
793
794  /* Removing non-empty directory fails */
795  tr_sys_dir_create (path2, 0, 0777, NULL);
796  libtest_create_file_with_string_contents (path3, "test");
797  check (tr_sys_path_exists (path2, NULL));
798  check (tr_sys_path_exists (path3, NULL));
799  check (!tr_sys_path_remove (path2, &err));
800  check (err != NULL);
801  check (tr_sys_path_exists (path2, NULL));
802  check (tr_sys_path_exists (path3, NULL));
803  tr_error_clear (&err);
804
805  tr_sys_path_remove (path3, NULL);
806  tr_sys_path_remove (path2, NULL);
807
808  tr_free (path3);
809  tr_free (path2);
810  tr_free (path1);
811
812  tr_free (test_dir);
813  return 0;
814}
815
816static int
817test_file_open (void)
818{
819  char * const test_dir = create_test_dir (__FUNCTION__);
820  tr_error * err = NULL;
821  char * path1;
822  tr_sys_file_t fd;
823  uint64_t n;
824  tr_sys_path_info info;
825
826  path1 = tr_buildPath (test_dir, "a", NULL);
827
828  /* Can't open non-existent file */
829  check (!tr_sys_path_exists (path1, NULL));
830  check (tr_sys_file_open (path1, TR_SYS_FILE_READ, 0600, &err) == TR_BAD_SYS_FILE);
831  check (err != NULL);
832  check (!tr_sys_path_exists (path1, NULL));
833  tr_error_clear (&err);
834  check (tr_sys_file_open (path1, TR_SYS_FILE_WRITE, 0600, &err) == TR_BAD_SYS_FILE);
835  check (err != NULL);
836  check (!tr_sys_path_exists (path1, NULL));
837  tr_error_clear (&err);
838
839  /* Can't open directory */
840  tr_sys_dir_create (path1, 0, 0777, NULL);
841#ifdef _WIN32
842  /* This works on *NIX */
843  check (tr_sys_file_open (path1, TR_SYS_FILE_READ, 0600, &err) == TR_BAD_SYS_FILE);
844  check (err != NULL);
845  tr_error_clear (&err);
846#endif
847  check (tr_sys_file_open (path1, TR_SYS_FILE_WRITE, 0600, &err) == TR_BAD_SYS_FILE);
848  check (err != NULL);
849  tr_error_clear (&err);
850
851  tr_sys_path_remove (path1, NULL);
852
853  /* Can create non-existent file */
854  fd = tr_sys_file_open (path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0640, &err);
855  check (fd != TR_BAD_SYS_FILE);
856  check (err == NULL);
857  tr_sys_file_close (fd, NULL);
858  check (tr_sys_path_exists (path1, NULL));
859  check (validate_permissions (path1, 0640));
860
861  /* Can open existing file */
862  check (tr_sys_path_exists (path1, NULL));
863  fd = tr_sys_file_open (path1, TR_SYS_FILE_READ, 0600, &err);
864  check (fd != TR_BAD_SYS_FILE);
865  check (err == NULL);
866  tr_sys_file_close (fd, NULL);
867  fd = tr_sys_file_open (path1, TR_SYS_FILE_WRITE, 0600, &err);
868  check (fd != TR_BAD_SYS_FILE);
869  check (err == NULL);
870  tr_sys_file_close (fd, NULL);
871
872  tr_sys_path_remove (path1, NULL);
873  libtest_create_file_with_string_contents (path1, "test");
874
875  /* Can't create new file if it already exists */
876  fd = tr_sys_file_open (path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE_NEW, 0640, &err);
877  check (fd == TR_BAD_SYS_FILE);
878  check (err != NULL);
879  tr_error_clear (&err);
880  tr_sys_path_get_info (path1, TR_SYS_PATH_NO_FOLLOW, &info, NULL);
881  check_int_eq (4, info.size);
882
883  /* Pointer is at the end of file */
884  tr_sys_path_get_info (path1, TR_SYS_PATH_NO_FOLLOW, &info, NULL);
885  check_int_eq (4, info.size);
886  fd = tr_sys_file_open (path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_APPEND, 0600, &err);
887  check (fd != TR_BAD_SYS_FILE);
888  check (err == NULL);
889  tr_sys_file_write (fd, "s", 1, NULL, NULL); /* On *NIX, pointer is positioned on each write but not initially */
890  tr_sys_file_seek (fd, 0, TR_SEEK_CUR, &n, NULL);
891  check_int_eq (5, n);
892  tr_sys_file_close (fd, NULL);
893
894  /* File gets truncated */
895  tr_sys_path_get_info (path1, TR_SYS_PATH_NO_FOLLOW, &info, NULL);
896  check_int_eq (5, info.size);
897  fd = tr_sys_file_open (path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_TRUNCATE, 0600, &err);
898  check (fd != TR_BAD_SYS_FILE);
899  check (err == NULL);
900  tr_sys_file_get_info (fd, &info, NULL);
901  check_int_eq (0, info.size);
902  tr_sys_file_close (fd, NULL);
903  tr_sys_path_get_info (path1, TR_SYS_PATH_NO_FOLLOW, &info, NULL);
904  check_int_eq (0, info.size);
905
906  /* TODO: symlink and hardlink tests */
907
908  tr_sys_path_remove (path1, NULL);
909
910  tr_free (path1);
911
912  tr_free (test_dir);
913  return 0;
914}
915
916static int
917test_file_read_write_seek (void)
918{
919  char * const test_dir = create_test_dir (__FUNCTION__);
920  tr_error * err = NULL;
921  char * path1;
922  tr_sys_file_t fd;
923  uint64_t n;
924  char buf[100];
925
926  path1 = tr_buildPath (test_dir, "a", NULL);
927
928  fd = tr_sys_file_open (path1, TR_SYS_FILE_READ | TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0600, NULL);
929
930  check (tr_sys_file_seek (fd, 0, TR_SEEK_CUR, &n, &err));
931  check (err == NULL);
932  check_int_eq (0, n);
933
934  check (tr_sys_file_write (fd, "test", 4, &n, &err));
935  check (err == NULL);
936  check_int_eq (4, n);
937
938  check (tr_sys_file_seek (fd, 0, TR_SEEK_CUR, &n, &err));
939  check (err == NULL);
940  check_int_eq (4, n);
941
942  check (tr_sys_file_seek (fd, 0, TR_SEEK_SET, &n, &err));
943  check (err == NULL);
944  check_int_eq (0, n);
945
946  check (tr_sys_file_read (fd, buf, sizeof (buf), &n, &err));
947  check (err == NULL);
948  check_int_eq (4, n);
949
950  check_int_eq (0, memcmp (buf, "test", 4));
951
952  check (tr_sys_file_seek (fd, -3, TR_SEEK_CUR, &n, &err));
953  check (err == NULL);
954  check_int_eq (1, n);
955
956  check (tr_sys_file_write (fd, "E", 1, &n, &err));
957  check (err == NULL);
958  check_int_eq (1, n);
959
960  check (tr_sys_file_seek (fd, -2, TR_SEEK_CUR, &n, &err));
961  check (err == NULL);
962  check_int_eq (0, n);
963
964  check (tr_sys_file_read (fd, buf, sizeof (buf), &n, &err));
965  check (err == NULL);
966  check_int_eq (4, n);
967
968  check_int_eq (0, memcmp (buf, "tEst", 4));
969
970  check (tr_sys_file_seek (fd, 0, TR_SEEK_END, &n, &err));
971  check (err == NULL);
972  check_int_eq (4, n);
973
974  check (tr_sys_file_write (fd, " ok", 3, &n, &err));
975  check (err == NULL);
976  check_int_eq (3, n);
977
978  check (tr_sys_file_seek (fd, 0, TR_SEEK_SET, &n, &err));
979  check (err == NULL);
980  check_int_eq (0, n);
981
982  check (tr_sys_file_read (fd, buf, sizeof (buf), &n, &err));
983  check (err == NULL);
984  check_int_eq (7, n);
985
986  check_int_eq (0, memcmp (buf, "tEst ok", 7));
987
988  check (tr_sys_file_write_at (fd, "-", 1, 4, &n, &err));
989  check (err == NULL);
990  check_int_eq (1, n);
991
992  check (tr_sys_file_read_at (fd, buf, 5, 2, &n, &err));
993  check (err == NULL);
994  check_int_eq (5, n);
995
996  check_int_eq (0, memcmp (buf, "st-ok", 5));
997
998  tr_sys_file_close (fd, NULL);
999
1000  tr_sys_path_remove (path1, NULL);
1001
1002  tr_free (path1);
1003
1004  tr_free (test_dir);
1005  return 0;
1006}
1007
1008static int
1009test_file_truncate (void)
1010{
1011  char * const test_dir = create_test_dir (__FUNCTION__);
1012  tr_error * err = NULL;
1013  char * path1;
1014  tr_sys_file_t fd;
1015  tr_sys_path_info info;
1016
1017  path1 = tr_buildPath (test_dir, "a", NULL);
1018
1019  fd = tr_sys_file_open (path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0600, NULL);
1020
1021  check (tr_sys_file_truncate (fd, 10, &err));
1022  check (err == NULL);
1023  tr_sys_file_get_info (fd, &info, NULL);
1024  check_int_eq (10, info.size);
1025
1026  check (tr_sys_file_truncate (fd, 20, &err));
1027  check (err == NULL);
1028  tr_sys_file_get_info (fd, &info, NULL);
1029  check_int_eq (20, info.size);
1030
1031  check (tr_sys_file_truncate (fd, 0, &err));
1032  check (err == NULL);
1033  tr_sys_file_get_info (fd, &info, NULL);
1034  check_int_eq (0, info.size);
1035
1036  check (tr_sys_file_truncate (fd, 50, &err));
1037  check (err == NULL);
1038
1039  tr_sys_file_close (fd, NULL);
1040
1041  tr_sys_path_get_info (path1, 0, &info, NULL);
1042  check_int_eq (50, info.size);
1043
1044  fd = tr_sys_file_open (path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0600, NULL);
1045
1046  check (tr_sys_file_truncate (fd, 25, &err));
1047  check (err == NULL);
1048
1049  tr_sys_file_close (fd, NULL);
1050
1051  tr_sys_path_get_info (path1, 0, &info, NULL);
1052  check_int_eq (25, info.size);
1053
1054  tr_sys_path_remove (path1, NULL);
1055
1056  tr_free (path1);
1057
1058  tr_free (test_dir);
1059  return 0;
1060}
1061
1062static int
1063test_file_preallocate (void)
1064{
1065  char * const test_dir = create_test_dir (__FUNCTION__);
1066  tr_error * err = NULL;
1067  char * path1;
1068  tr_sys_file_t fd;
1069  tr_sys_path_info info;
1070
1071  path1 = tr_buildPath (test_dir, "a", NULL);
1072
1073  fd = tr_sys_file_open (path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0600, NULL);
1074
1075  if (tr_sys_file_preallocate (fd, 50, 0, &err))
1076    {
1077      check (err == NULL);
1078      tr_sys_file_get_info (fd, &info, NULL);
1079      check_int_eq (50, info.size);
1080    }
1081  else
1082    {
1083      check (err != NULL);
1084      fprintf (stderr, "WARNING: [%s] unable to preallocate file (full): %s (%d)\n", __FUNCTION__, err->message, err->code);
1085      tr_error_clear (&err);
1086    }
1087
1088  tr_sys_file_close (fd, NULL);
1089
1090  tr_sys_path_remove (path1, NULL);
1091
1092  fd = tr_sys_file_open (path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0600, NULL);
1093
1094  if (tr_sys_file_preallocate (fd, 500 * 1024 * 1024, TR_SYS_FILE_PREALLOC_SPARSE, &err))
1095    {
1096      check (err == NULL);
1097      tr_sys_file_get_info (fd, &info, NULL);
1098      check_int_eq (500 * 1024 * 1024, info.size);
1099    }
1100  else
1101    {
1102      check (err != NULL);
1103      fprintf (stderr, "WARNING: [%s] unable to preallocate file (sparse): %s (%d)\n", __FUNCTION__, err->message, err->code);
1104      tr_error_clear (&err);
1105    }
1106
1107  tr_sys_file_close (fd, NULL);
1108
1109  tr_sys_path_remove (path1, NULL);
1110
1111  tr_free (path1);
1112
1113  tr_free (test_dir);
1114  return 0;
1115}
1116
1117static int
1118test_file_map (void)
1119{
1120  char * const test_dir = create_test_dir (__FUNCTION__);
1121  tr_error * err = NULL;
1122  char * path1;
1123  tr_sys_file_t fd;
1124  char * view;
1125
1126  path1 = tr_buildPath (test_dir, "a", NULL);
1127
1128  libtest_create_file_with_string_contents (path1, "test");
1129
1130  fd = tr_sys_file_open (path1, TR_SYS_FILE_READ | TR_SYS_FILE_WRITE, 0600, NULL);
1131
1132  view = tr_sys_file_map_for_reading (fd, 0, 4, &err);
1133  check (view != NULL);
1134  check (err == NULL);
1135
1136  check_int_eq (0, memcmp (view, "test", 4));
1137
1138  tr_sys_file_write_at (fd, "E", 1, 1, NULL, NULL);
1139
1140  check_int_eq (0, memcmp (view, "tEst", 4));
1141
1142  check (tr_sys_file_unmap (view, 4, &err));
1143  check (err == NULL);
1144
1145  tr_sys_file_close (fd, NULL);
1146
1147  tr_sys_path_remove (path1, NULL);
1148
1149  tr_free (path1);
1150
1151  tr_free (test_dir);
1152  return 0;
1153}
1154
1155static int
1156test_file_utilities (void)
1157{
1158  char * const test_dir = create_test_dir (__FUNCTION__);
1159  tr_error * err = NULL;
1160  char * path1;
1161  tr_sys_file_t fd;
1162  char buffer[16];
1163
1164  path1 = tr_buildPath (test_dir, "a", NULL);
1165
1166  libtest_create_file_with_string_contents (path1, "a\nbc\r\ndef\nghij\r\n\n\nklmno\r");
1167
1168  fd = tr_sys_file_open (path1, TR_SYS_FILE_READ, 0, NULL);
1169
1170  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1171  check (err == NULL);
1172  check_streq ("a", buffer);
1173  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1174  check (err == NULL);
1175  check_streq ("bc", buffer);
1176  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1177  check (err == NULL);
1178  check_streq ("def", buffer);
1179  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1180  check (err == NULL);
1181  check_streq ("ghij", buffer);
1182  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1183  check (err == NULL);
1184  check_streq ("", buffer);
1185  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1186  check (err == NULL);
1187  check_streq ("", buffer);
1188  check (tr_sys_file_read_line (fd, buffer, 4, &err));
1189  check (err == NULL);
1190  check_streq ("klmn", buffer);
1191  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1192  check (err == NULL);
1193  check_streq ("o", buffer);
1194  check (!tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1195  check (err == NULL);
1196  check_streq ("o", buffer); /* on EOF, buffer stays unchanged */
1197
1198  tr_sys_file_close (fd, NULL);
1199
1200  fd = tr_sys_file_open (path1, TR_SYS_FILE_READ | TR_SYS_FILE_WRITE | TR_SYS_FILE_TRUNCATE, 0, NULL);
1201
1202  check (tr_sys_file_write_line (fd, "p", &err));
1203  check (err == NULL);
1204  check (tr_sys_file_write_line (fd, "", &err));
1205  check (err == NULL);
1206  check (tr_sys_file_write_line (fd, "qr", &err));
1207  check (err == NULL);
1208  check (tr_sys_file_write_fmt (fd, "s%cu\r\n", &err, 't'));
1209  check (err == NULL);
1210  check (tr_sys_file_write_line (fd, "", &err));
1211  check (err == NULL);
1212  check (tr_sys_file_write_line (fd, "", &err));
1213  check (err == NULL);
1214  check (tr_sys_file_write_fmt (fd, "v%sy%d", &err, "wx", 2));
1215  check (err == NULL);
1216
1217  tr_sys_file_seek (fd, 0, TR_SEEK_SET, NULL, NULL);
1218
1219  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1220  check (err == NULL);
1221  check_streq ("p", buffer);
1222  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1223  check (err == NULL);
1224  check_streq ("", buffer);
1225  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1226  check (err == NULL);
1227  check_streq ("qr", buffer);
1228  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1229  check (err == NULL);
1230  check_streq ("stu", buffer);
1231  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1232  check (err == NULL);
1233  check_streq ("", buffer);
1234  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1235  check (err == NULL);
1236  check_streq ("", buffer);
1237  check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1238  check (err == NULL);
1239  check_streq ("vwxy2", buffer);
1240  check (!tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
1241  check (err == NULL);
1242  check_streq ("vwxy2", buffer); /* on EOF, buffer stays unchanged */
1243
1244  tr_sys_file_close (fd, NULL);
1245
1246  tr_sys_path_remove (path1, NULL);
1247
1248  tr_free (path1);
1249
1250  tr_free (test_dir);
1251  return 0;
1252}
1253
1254static int
1255test_dir_create (void)
1256{
1257  char * const test_dir = create_test_dir (__FUNCTION__);
1258  tr_error * err = NULL;
1259  char * path1, * path2;
1260
1261  path1 = tr_buildPath (test_dir, "a", NULL);
1262  path2 = tr_buildPath (path1, "b", NULL);
1263
1264  /* Can create directory which has parent */
1265  check (tr_sys_dir_create (path1, 0, 0700, &err));
1266  check (err == NULL);
1267  check (tr_sys_path_exists (path1, NULL));
1268  check (validate_permissions (path1, 0700));
1269
1270  tr_sys_path_remove (path1, NULL);
1271  libtest_create_file_with_string_contents (path1, "test");
1272
1273  /* Can't create directory where file already exists */
1274  check (!tr_sys_dir_create (path1, 0, 0700, &err));
1275  check (err != NULL);
1276  tr_error_clear (&err);
1277  check (!tr_sys_dir_create (path1, TR_SYS_DIR_CREATE_PARENTS, 0700, &err));
1278  check (err != NULL);
1279  tr_error_clear (&err);
1280
1281  tr_sys_path_remove (path1, NULL);
1282
1283  /* Can't create directory which has no parent */
1284  check (!tr_sys_dir_create (path2, 0, 0700, &err));
1285  check (err != NULL);
1286  check (!tr_sys_path_exists (path2, NULL));
1287  tr_error_clear (&err);
1288
1289  /* Can create directory with parent directories */
1290  check (tr_sys_dir_create (path2, TR_SYS_DIR_CREATE_PARENTS, 0751, &err));
1291  check (err == NULL);
1292  check (tr_sys_path_exists (path1, NULL));
1293  check (tr_sys_path_exists (path2, NULL));
1294  check (validate_permissions (path1, 0751));
1295  check (validate_permissions (path2, 0751));
1296
1297  /* Can create existing directory (no-op) */
1298  check (tr_sys_dir_create (path1, 0, 0700, &err));
1299  check (err == NULL);
1300  check (tr_sys_dir_create (path1, TR_SYS_DIR_CREATE_PARENTS, 0700, &err));
1301  check (err == NULL);
1302
1303  tr_sys_path_remove (path2, NULL);
1304  tr_sys_path_remove (path1, NULL);
1305
1306  tr_free (path2);
1307  tr_free (path1);
1308
1309  tr_free (test_dir);
1310  return 0;
1311}
1312
1313static int
1314test_dir_read_impl (const char * path,
1315                      bool       * have1,
1316                      bool       * have2)
1317{
1318  tr_error * err = NULL;
1319  tr_sys_dir_t dd;
1320  const char * name;
1321
1322  *have1 = *have2 = false;
1323
1324  dd = tr_sys_dir_open (path, &err);
1325  check (dd != TR_BAD_SYS_DIR);
1326  check (err == NULL);
1327
1328  while ((name = tr_sys_dir_read_name (dd, &err)) != NULL)
1329    {
1330      check (err == NULL);
1331
1332      if (strcmp (name, ".") == 0 || strcmp (name, "..") == 0)
1333        continue;
1334
1335      if (strcmp (name, "a") == 0)
1336        *have1 = true;
1337      else if (strcmp (name, "b") == 0)
1338        *have2 = true;
1339      else
1340        check (false);
1341    }
1342
1343  check (err == NULL);
1344
1345  check (tr_sys_dir_close (dd, &err));
1346  check (err == NULL);
1347
1348  return 0;
1349}
1350
1351static int
1352test_dir_read (void)
1353{
1354  char * const test_dir = create_test_dir (__FUNCTION__);
1355  char * path1, * path2;
1356  bool have1, have2;
1357
1358  path1 = tr_buildPath (test_dir, "a", NULL);
1359  path2 = tr_buildPath (test_dir, "b", NULL);
1360
1361  if (test_dir_read_impl (test_dir, &have1, &have2) != 0)
1362    return 1;
1363  check (!have1);
1364  check (!have2);
1365
1366  libtest_create_file_with_string_contents (path1, "test");
1367
1368  if (test_dir_read_impl (test_dir, &have1, &have2) != 0)
1369    return 1;
1370  check (have1);
1371  check (!have2);
1372
1373  libtest_create_file_with_string_contents (path2, "test");
1374
1375  if (test_dir_read_impl (test_dir, &have1, &have2) != 0)
1376    return 1;
1377  check (have1);
1378  check (have2);
1379
1380  tr_sys_path_remove (path1, NULL);
1381
1382  if (test_dir_read_impl (test_dir, &have1, &have2) != 0)
1383    return 1;
1384  check (!have1);
1385  check (have2);
1386
1387  tr_free (path2);
1388  tr_free (path1);
1389
1390  tr_free (test_dir);
1391  return 0;
1392}
1393
1394int
1395main (void)
1396{
1397  const testFunc tests[] =
1398    {
1399      test_get_info,
1400      test_path_exists,
1401      test_path_is_same,
1402      test_path_resolve,
1403      test_path_basename_dirname,
1404      test_path_rename,
1405      test_path_remove,
1406      test_file_open,
1407      test_file_read_write_seek,
1408      test_file_truncate,
1409      test_file_preallocate,
1410      test_file_map,
1411      test_file_utilities,
1412      test_dir_create,
1413      test_dir_read
1414    };
1415  int ret;
1416
1417  /* init the session */
1418  session = libttest_session_init (NULL);
1419
1420  ret = runTests (tests, NUM_TESTS (tests));
1421
1422  if (ret == 0)
1423    libttest_session_close (session);
1424
1425  return ret;
1426}
Note: See TracBrowser for help on using the repository browser.