int main(int argc, char **argv) { pid_t tid; int ret; pthread_t th; test_init(argc, argv); pthread_mutex_init(&init_lock, NULL); pthread_mutex_lock(&init_lock); pthread_mutex_init(&exit_lock, NULL); pthread_mutex_lock(&exit_lock); if (pthread_create(&th, NULL, thread_func, &tid)) { fail("Can't pthread_create"); return 1; } pthread_mutex_lock(&init_lock); ret = kcmp(KCMP_FS, gettid(), tid, 0, 0); if (ret) exit(1); test_daemon(); test_waitsig(); ret = kcmp(KCMP_FS, gettid(), tid, 0, 0); if (ret) { fail(); exit(1); } pthread_mutex_unlock(&exit_lock); pthread_join(th, NULL); pass(); return 0; }
static void do_child(const struct test_case *test) { pid2 = getpid(); fd2 = dup(fd1); fd3 = SAFE_OPEN(cleanup_child, TEST_FILE2, O_CREAT | O_RDWR, 0666); TEST(kcmp(*(test->pid1), *(test->pid2), test->type, *(test->fd1), *(test->fd2))); if (TEST_RETURN == -1) tst_resm(TFAIL | TTERRNO, "kcmp() failed unexpectedly"); if ((test->exp_different && TEST_RETURN == 0) || (test->exp_different == 0 && TEST_RETURN)) tst_resm(TFAIL, "kcmp() returned %lu instead of %d", TEST_RETURN, test->exp_different); if ((test->exp_different == 0 && TEST_RETURN == 0) || (test->exp_different && TEST_RETURN)) tst_resm(TPASS, "kcmp() returned the expected value"); tst_exit(); }
int same_fd(int a, int b) { struct stat sta, stb; pid_t pid; int r, fa, fb; assert(a >= 0); assert(b >= 0); /* Compares two file descriptors. Note that semantics are * quite different depending on whether we have kcmp() or we * don't. If we have kcmp() this will only return true for * dup()ed file descriptors, but not otherwise. If we don't * have kcmp() this will also return true for two fds of the same * file, created by separate open() calls. Since we use this * call mostly for filtering out duplicates in the fd store * this difference hopefully doesn't matter too much. */ if (a == b) return true; /* Try to use kcmp() if we have it. */ pid = getpid(); r = kcmp(pid, pid, KCMP_FILE, a, b); if (r == 0) return true; if (r > 0) return false; if (errno != ENOSYS) return -errno; /* We don't have kcmp(), use fstat() instead. */ if (fstat(a, &sta) < 0) return -errno; if (fstat(b, &stb) < 0) return -errno; if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT)) return false; /* We consider all device fds different, since two device fds * might refer to quite different device contexts even though * they share the same inode and backing dev_t. */ if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode)) return false; if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino) return false; /* The fds refer to the same inode on disk, let's also check * if they have the same fd flags. This is useful to * distinguish the read and write side of a pipe created with * pipe(). */ fa = fcntl(a, F_GETFL); if (fa < 0) return -errno; fb = fcntl(b, F_GETFL); if (fb < 0) return -errno; return fa == fb; }