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