Date: Mon, 24 Mar 2003 18:54:47 +0000 From: "Richard Dawe" Sender: rich AT phekda DOT freeserve DOT co DOT uk To: djgpp-workers AT delorie DOT com X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6 Subject: open(), symlinks and O_CREAT|O_EXCL Message-Id: Reply-To: djgpp-workers AT delorie DOT com Hello. I think that open() on symlinks does not honour O_CREAT|O_EXCL in the way required by POSIX: "If O_EXCL and O_CREAT are set, and path names a symbolic link, open( ) shall fail and set errno to [EEXIST], regardless of the contents of the symbolic link." (This is taken from the pages for open() in draft 7 of new POSIX.) Example: Create a symlink 'test3' pointing to 'doesnotexist', which does not exist. Now open() 'test3'. I think this open call should fail with errno == EEXIST, as described above. Below is a diff to add this test case. Is my interpretation correct? Bye, Rich =] Index: tests/libc/posix/fcntl/open.c =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/posix/fcntl/open.c,v retrieving revision 1.4 diff -p -u -3 -r1.4 open.c --- tests/libc/posix/fcntl/open.c 11 Mar 2001 05:22:18 -0000 1.4 +++ tests/libc/posix/fcntl/open.c 24 Mar 2003 18:45:25 -0000 @@ -45,28 +45,58 @@ static int testnum; int main(void) { int fd; + if (!__file_exists("file1") || !__file_exists("test1") || !__file_exists("test2") || !__file_exists("dir/file1")) { fprintf(stderr, "Required data file is missing\n"); exit(1); } + + if (__file_exists("doesnotexist")) + { + fprintf(stderr, + "File 'doesnotexist' is in the way - " + "please remove it!\n"); + exit(1); + } + test_success("test1", O_RDONLY, "file1"); test_success("test1", O_RDONLY | O_NOLINK, "!"); test_success("test2/file1", O_RDONLY | O_NOFOLLOW, "file1"); + ++testnum; fd = open("test2/test1", O_RDONLY | O_NOFOLLOW); if (fd != -1) { - fprintf(stderr, "Test 4 failed - unexpected open() success.\n"); + fprintf(stderr, "Test %d failed - unexpected open() success.\n", + testnum); exit(1); } if (errno != ELOOP) { - perror("Test 4 failed - wrong errno returned "); + fprintf(stderr, "Test %d failed - wrong errno returned: %s\n", + testnum, strerror(errno)); + exit(1); + } + printf("Test %d passed\n", testnum); + + ++testnum; + fd = open("test3", O_RDONLY | O_CREAT | O_EXCL); + if (fd != -1) + { + fprintf(stderr, "Test %d failed - unexpected open() success.\n", + testnum); + exit(1); + } + if (errno != EEXIST) + { + fprintf(stderr, "Test %d failed - wrong errno returned: %s\n", + testnum, strerror(errno)); exit(1); } - printf("Test 4 passed\n"); + printf("Test %d passed\n", testnum); + test_success("test2/test1", O_RDONLY | O_NOLINK, "!"); test_success("dir/test2", O_RDONLY, "tstlink2"); test_o_temporary(); --- /dev/null 2003-03-24 18:49:41.000000000 +0000 +++ tests/libc/posix/fcntl/test3 2003-03-24 17:25:02.000000000 +0000 @@ -0,0 +1,2 @@ +!doesnotexist +This is just a text to force symlink file to be 510 bytes long. Do not delete it nor spaces following it. \ No newline at end of file