1// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s 2#include "test.h" 3#include <sys/types.h> 4#include <sys/stat.h> 5#include <fcntl.h> 6#include <errno.h> 7 8// dup2(oldfd, newfd) races with read(newfd). 9// This is not reported as race because: 10// 1. Some software dups a closed pipe in place of a socket before closing 11// the socket (to prevent races actually). 12// 2. Some daemons dup /dev/null in place of stdin/stdout. 13 14int fd; 15 16void *Thread(void *x) { 17 char buf; 18 int n = read(fd, &buf, 1); 19 if (n != 1) { 20 // This read can "legitimately" fail regadless of the fact that glibc claims 21 // that "there is no instant in the middle of calling dup2 at which new is 22 // closed and not yet a duplicate of old". Strace of the failing runs 23 // looks as follows: 24 // 25 // [pid 122196] open("/dev/urandom", O_RDONLY) = 3 26 // [pid 122196] open("/dev/urandom", O_RDONLY) = 4 27 // Process 122382 attached 28 // [pid 122382] read(3, <unfinished ...> 29 // [pid 122196] dup2(4, 3 <unfinished ...> 30 // [pid 122382] <... read resumed> 0x7fcd139960b7, 1) = -1 EBADF (Bad file descriptor) 31 // [pid 122196] <... dup2 resumed> ) = 3 32 // read failed: n=-1 errno=9 33 // 34 // The failing read does not interfere with what this test tests, 35 // so we just ignore the failure. 36 // 37 // exit(printf("read failed: n=%d errno=%d\n", n, errno)); 38 } 39 return 0; 40} 41 42int main() { 43 fd = open("/dev/urandom", O_RDONLY); 44 int fd2 = open("/dev/urandom", O_RDONLY); 45 if (fd == -1 || fd2 == -1) 46 exit(printf("open failed\n")); 47 pthread_t th; 48 pthread_create(&th, 0, Thread, 0); 49 if (dup2(fd2, fd) == -1) 50 exit(printf("dup2 failed\n")); 51 pthread_join(th, 0); 52 if (close(fd) == -1) 53 exit(printf("close failed\n")); 54 if (close(fd2) == -1) 55 exit(printf("close failed\n")); 56 fprintf(stderr, "DONE\n"); 57} 58 59// CHECK-NOT: WARNING: ThreadSanitizer: data race 60// CHECK: DONE 61