chiark / gitweb /
vars.am: Quote `$(manext)', or things break if it's empty.
[mLib] / sys / t / mdup-test.c
1 #include <errno.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include "macros.h"
10 #include "mdup.h"
11
12 #define MAXFD 256
13
14 /* For some reason, Cygwin has started leaving cruft in the top bits of inode
15  * numbers, which breaks this test.  Mask them off.
16  */
17 #if defined(__CYGWIN__) && defined(__amd64__)
18 #  define HACK_INODE(ino) ((ino)&0xffffffffffff)
19 #else
20 #  define HACK_INODE(ino) (ino)
21 #endif
22
23 static void fail(const char *what) { perror(what); exit(1); }
24
25 int main(int argc, char *argv[])
26 {
27   int i, n, j;
28   int fd, fd2;
29   struct stat st;
30   int ino[MAXFD];
31   int flag[MAXFD];
32   mdup_fd fds[MAXFD];
33   int win = 1;
34   int verbose = 0;
35
36   for (i = 1, j = 0; i < argc; i++) {
37     if (STRCMP(argv[i], ==, "-v")) { verbose++; continue; }
38     if (j >= MAXFD) { fprintf(stderr, "too many\n"); exit(1); }
39     if (sscanf(argv[i], "%d:%d", &fds[j].cur, &fds[j].want) < 2 ||
40         fds[j].cur >= MAXFD)
41       { fprintf(stderr, "bad syntax\n"); exit(1); }
42     j++;
43   }
44   n = j;
45   for (i = 0; i < MAXFD; i++) flag[i] = -1;
46   for (i = 0; i < n; i++) {
47     fd = fds[i].cur;
48     if (flag[fd] >= 0) {
49       ino[i] = ino[flag[fd]];
50       if (verbose)
51         printf("exist fd %d[%d] = ino %lu\n", fd, i, (unsigned long)ino[i]);
52     } else {
53       flag[fd] = i;
54       if ((fd2 = open(",delete-me",
55                       O_WRONLY | O_CREAT | O_EXCL,
56                       0700)) < 0)
57         fail("creat");
58       unlink(",delete-me");
59       if (fd2 != fd) { if (dup2(fd2, fd) < 0) fail("dup2"); close(fd2); }
60       if (fstat(fd, &st)) fail("fstat");
61       ino[i] = HACK_INODE(st.st_ino);
62       if (verbose)
63         printf("open fd %d[%d] = ino %lu\n", fd, i, (unsigned long)ino[i]);
64     }
65   }
66
67   if (mdup(fds, n)) fail("mdup");
68
69   for (i = 0; i < n; i++) {
70     fd = fds[i].cur;
71     if (fds[i].want != -1 && fds[i].want != fd) {
72       printf("fd %d[%d] != %d\n", fd, i, fds[i].want);
73       win = 0;
74     } else if (fstat(fd, &st)) {
75       printf("fstat %d[%d] failed: %s\n", fd, i, strerror(errno));
76       win = 0;
77     } else if (HACK_INODE(st.st_ino) != ino[i]) {
78       if (!verbose) printf("ino %d[%d] wrong\n", fd, i);
79       else printf("ino %d[%d] = %lu != %lu\n", fd, i,
80                   (unsigned long)HACK_INODE(st.st_ino),
81                   (unsigned long)ino[i]);
82       win = 0;
83     }
84   }
85
86   return (!win);
87 }