chiark / gitweb /
sys/t/mdup-test.c: Cope with Cygwin setting top inode-number bits.
[mLib] / sys / t / mdup-test.c
index 3169247ae4d3037039e3a54d0c2429383af78b61..43aa45d8d05584f8cba09283b4bf08aa437b3788 100644 (file)
 
 #define MAXFD 256
 
+/* For some reason, Cygwin has started leaving cruft in the top bits of inode
+ * numbers, which breaks this test.  Mask them off.
+ */
+#if defined(__CYGWIN__) && defined(__amd64__)
+#  define HACK_INODE(ino) ((ino)&0xffffffffffff)
+#else
+#  define HACK_INODE(ino) (ino)
+#endif
+
 static void fail(const char *what) { perror(what); exit(1); }
 
 int main(int argc, char *argv[])
 {
-  int i, n;
+  int i, n, j;
   int fd, fd2;
   struct stat st;
   int ino[MAXFD];
   int flag[MAXFD];
   mdup_fd fds[MAXFD];
   int win = 1;
+  int verbose = 0;
 
-  for (i = 0; i < argc - 1; i++) {
-    if (i >= MAXFD) { fprintf(stderr, "too many\n"); exit(1); }
-    if (sscanf(argv[i + 1], "%d:%d", &fds[i].cur, &fds[i].want) < 2 ||
-       fds[i].cur >= MAXFD)
+  for (i = 1, j = 0; i < argc; i++) {
+    if (strcmp(argv[i], "-v") == 0) { verbose++; continue; }
+    if (j >= MAXFD) { fprintf(stderr, "too many\n"); exit(1); }
+    if (sscanf(argv[i], "%d:%d", &fds[j].cur, &fds[j].want) < 2 ||
+       fds[j].cur >= MAXFD)
       { fprintf(stderr, "bad syntax\n"); exit(1); }
+    j++;
   }
-  n = argc - 1;
+  n = j;
   for (i = 0; i < MAXFD; i++) flag[i] = -1;
   for (i = 0; i < n; i++) {
     fd = fds[i].cur;
-    if (flag[fd] >= 0)
+    if (flag[fd] >= 0) {
       ino[i] = ino[flag[fd]];
-    else {
+      if (verbose)
+       printf("exist fd %d[%d] = ino %lu\n", fd, i, (unsigned long)ino[i]);
+    } else {
       flag[fd] = i;
       if ((fd2 = open(",delete-me",
                      O_WRONLY | O_CREAT | O_EXCL,
@@ -43,7 +57,9 @@ int main(int argc, char *argv[])
       unlink(",delete-me");
       if (fd2 != fd) { if (dup2(fd2, fd) < 0) fail("dup2"); close(fd2); }
       if (fstat(fd, &st)) fail("fstat");
-      ino[i] = st.st_ino;
+      ino[i] = HACK_INODE(st.st_ino);
+      if (verbose)
+       printf("open fd %d[%d] = ino %lu\n", fd, i, (unsigned long)ino[i]);
     }
   }
 
@@ -57,8 +73,11 @@ int main(int argc, char *argv[])
     } else if (fstat(fd, &st)) {
       printf("fstat %d[%d] failed: %s\n", fd, i, strerror(errno));
       win = 0;
-    } else if (st.st_ino != ino[i]) {
-      printf("ino %d[%d] wrong\n", fd, i);
+    } else if (HACK_INODE(st.st_ino) != ino[i]) {
+      if (!verbose) printf("ino %d[%d] wrong\n", fd, i);
+      else printf("ino %d[%d] = %lu != %lu\n", fd, i,
+                 (unsigned long)HACK_INODE(st.st_ino),
+                 (unsigned long)ino[i]);
       win = 0;
     }
   }