#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include "macros.h"
#include "mdup.h"
#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) {
- fprintf(stderr, "bad syntax\n");
- exit(1);
- }
+ for (i = 1, j = 0; i < argc; i++) {
+ if (STRCMP(argv[i], ==, "-v")) { 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,
0700)) < 0)
fail("creat");
unlink(",delete-me");
- if (fd2 != fd) {
- if (dup2(fd2, fd) < 0) fail("dup2");
- close(fd2);
- }
+ 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]);
}
}
} 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;
}
}