xref: /netbsd-src/external/mit/libuv/dist/test/test-fs-open-flags.c (revision 5f2f42719cd62ff11fd913b40b7ce19f07c4fd25)
10e552da7Schristos /* Copyright libuv project contributors. All rights reserved.
20e552da7Schristos  *
30e552da7Schristos  * Permission is hereby granted, free of charge, to any person obtaining a copy
40e552da7Schristos  * of this software and associated documentation files (the "Software"), to
50e552da7Schristos  * deal in the Software without restriction, including without limitation the
60e552da7Schristos  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
70e552da7Schristos  * sell copies of the Software, and to permit persons to whom the Software is
80e552da7Schristos  * furnished to do so, subject to the following conditions:
90e552da7Schristos  *
100e552da7Schristos  * The above copyright notice and this permission notice shall be included in
110e552da7Schristos  * all copies or substantial portions of the Software.
120e552da7Schristos  *
130e552da7Schristos  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
140e552da7Schristos  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
150e552da7Schristos  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
160e552da7Schristos  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
170e552da7Schristos  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
180e552da7Schristos  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
190e552da7Schristos  * IN THE SOFTWARE.
200e552da7Schristos  */
210e552da7Schristos 
220e552da7Schristos #ifdef _WIN32
230e552da7Schristos 
240e552da7Schristos #include "uv.h"
250e552da7Schristos #include "task.h"
260e552da7Schristos 
270e552da7Schristos #if defined(__unix__) || defined(__POSIX__) || \
280e552da7Schristos     defined(__APPLE__) || defined(__sun) || \
290e552da7Schristos     defined(_AIX) || defined(__MVS__) || \
300e552da7Schristos     defined(__HAIKU__)
310e552da7Schristos # include <unistd.h> /* unlink, rmdir */
320e552da7Schristos #else
330e552da7Schristos # include <direct.h>
340e552da7Schristos # define rmdir _rmdir
350e552da7Schristos # define unlink _unlink
360e552da7Schristos #endif
370e552da7Schristos 
380e552da7Schristos static int flags;
390e552da7Schristos 
400e552da7Schristos static uv_fs_t close_req;
410e552da7Schristos static uv_fs_t mkdir_req;
420e552da7Schristos static uv_fs_t open_req;
430e552da7Schristos static uv_fs_t read_req;
440e552da7Schristos static uv_fs_t rmdir_req;
450e552da7Schristos static uv_fs_t unlink_req;
460e552da7Schristos static uv_fs_t write_req;
470e552da7Schristos 
480e552da7Schristos static char buf[32];
490e552da7Schristos static uv_buf_t iov;
500e552da7Schristos 
510e552da7Schristos /* Opening the same file multiple times quickly can cause uv_fs_open to fail
520e552da7Schristos  * with EBUSY, so append an identifier to the file name for each operation */
530e552da7Schristos static int sid = 0;
540e552da7Schristos 
550e552da7Schristos #define FILE_NAME_SIZE 128
560e552da7Schristos static char absent_file[FILE_NAME_SIZE];
570e552da7Schristos static char empty_file[FILE_NAME_SIZE];
580e552da7Schristos static char dummy_file[FILE_NAME_SIZE];
590e552da7Schristos static char empty_dir[] = "empty_dir";
600e552da7Schristos 
setup(void)61*5f2f4271Schristos static void setup(void) {
620e552da7Schristos   int r;
630e552da7Schristos 
640e552da7Schristos   /* empty_dir */
650e552da7Schristos   r = uv_fs_rmdir(NULL, &rmdir_req, empty_dir, NULL);
660e552da7Schristos   ASSERT(r == 0 || r == UV_ENOENT);
670e552da7Schristos   ASSERT(rmdir_req.result == 0 || rmdir_req.result == UV_ENOENT);
680e552da7Schristos   uv_fs_req_cleanup(&rmdir_req);
690e552da7Schristos 
700e552da7Schristos   r = uv_fs_mkdir(NULL, &mkdir_req, empty_dir, 0755, NULL);
710e552da7Schristos   ASSERT(r == 0);
720e552da7Schristos   ASSERT(mkdir_req.result == 0);
730e552da7Schristos   uv_fs_req_cleanup(&mkdir_req);
740e552da7Schristos }
750e552da7Schristos 
refresh(void)76*5f2f4271Schristos static void refresh(void) {
770e552da7Schristos   int r;
780e552da7Schristos 
790e552da7Schristos   /* absent_file */
800e552da7Schristos   sprintf(absent_file, "test_file_%d", sid++);
810e552da7Schristos 
820e552da7Schristos   r = uv_fs_unlink(NULL, &unlink_req, absent_file, NULL);
830e552da7Schristos   ASSERT(r == 0 || r == UV_ENOENT);
840e552da7Schristos   ASSERT(unlink_req.result == 0 || unlink_req.result == UV_ENOENT);
850e552da7Schristos   uv_fs_req_cleanup(&unlink_req);
860e552da7Schristos 
870e552da7Schristos   /* empty_file */
880e552da7Schristos   sprintf(empty_file, "test_file_%d", sid++);
890e552da7Schristos 
900e552da7Schristos   r = uv_fs_open(NULL, &open_req, empty_file,
910e552da7Schristos     UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, NULL);
920e552da7Schristos   ASSERT(r >= 0);
930e552da7Schristos   ASSERT(open_req.result >= 0);
940e552da7Schristos   uv_fs_req_cleanup(&open_req);
950e552da7Schristos 
960e552da7Schristos   r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
970e552da7Schristos   ASSERT(r == 0);
980e552da7Schristos   ASSERT(close_req.result == 0);
990e552da7Schristos   uv_fs_req_cleanup(&close_req);
1000e552da7Schristos 
1010e552da7Schristos   /* dummy_file */
1020e552da7Schristos   sprintf(dummy_file, "test_file_%d", sid++);
1030e552da7Schristos 
1040e552da7Schristos   r = uv_fs_open(NULL, &open_req, dummy_file,
1050e552da7Schristos     UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, NULL);
1060e552da7Schristos   ASSERT(r >= 0);
1070e552da7Schristos   ASSERT(open_req.result >= 0);
1080e552da7Schristos   uv_fs_req_cleanup(&open_req);
1090e552da7Schristos 
1100e552da7Schristos   iov = uv_buf_init("a", 1);
1110e552da7Schristos   r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
1120e552da7Schristos   ASSERT(r == 1);
1130e552da7Schristos   ASSERT(write_req.result == 1);
1140e552da7Schristos   uv_fs_req_cleanup(&write_req);
1150e552da7Schristos 
1160e552da7Schristos   r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
1170e552da7Schristos   ASSERT(r == 0);
1180e552da7Schristos   ASSERT(close_req.result == 0);
1190e552da7Schristos   uv_fs_req_cleanup(&close_req);
1200e552da7Schristos }
1210e552da7Schristos 
cleanup(void)122*5f2f4271Schristos static void cleanup(void) {
1230e552da7Schristos   unlink(absent_file);
1240e552da7Schristos   unlink(empty_file);
1250e552da7Schristos   unlink(dummy_file);
1260e552da7Schristos }
1270e552da7Schristos 
openFail(char * file,int error)1280e552da7Schristos static void openFail(char *file, int error) {
1290e552da7Schristos   int r;
1300e552da7Schristos 
1310e552da7Schristos   refresh();
1320e552da7Schristos 
1330e552da7Schristos   r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL);
1340e552da7Schristos   ASSERT(r == error);
1350e552da7Schristos   ASSERT(open_req.result == error);
1360e552da7Schristos   uv_fs_req_cleanup(&open_req);
1370e552da7Schristos 
1380e552da7Schristos   /* Ensure the first call does not create the file */
1390e552da7Schristos   r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL);
1400e552da7Schristos   ASSERT(r == error);
1410e552da7Schristos   ASSERT(open_req.result == error);
1420e552da7Schristos   uv_fs_req_cleanup(&open_req);
1430e552da7Schristos 
1440e552da7Schristos   cleanup();
1450e552da7Schristos }
1460e552da7Schristos 
refreshOpen(char * file)1470e552da7Schristos static void refreshOpen(char *file) {
1480e552da7Schristos   int r;
1490e552da7Schristos 
1500e552da7Schristos   refresh();
1510e552da7Schristos 
1520e552da7Schristos   r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL);
1530e552da7Schristos   ASSERT(r >= 0);
1540e552da7Schristos   ASSERT(open_req.result >= 0);
1550e552da7Schristos   uv_fs_req_cleanup(&open_req);
1560e552da7Schristos }
1570e552da7Schristos 
writeExpect(char * file,char * expected,int size)1580e552da7Schristos static void writeExpect(char *file, char *expected, int size) {
1590e552da7Schristos   int r;
1600e552da7Schristos 
1610e552da7Schristos   refreshOpen(file);
1620e552da7Schristos 
1630e552da7Schristos   iov = uv_buf_init("b", 1);
1640e552da7Schristos   r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
1650e552da7Schristos   ASSERT(r == 1);
1660e552da7Schristos   ASSERT(write_req.result == 1);
1670e552da7Schristos   uv_fs_req_cleanup(&write_req);
1680e552da7Schristos 
1690e552da7Schristos   iov = uv_buf_init("c", 1);
1700e552da7Schristos   r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
1710e552da7Schristos   ASSERT(r == 1);
1720e552da7Schristos   ASSERT(write_req.result == 1);
1730e552da7Schristos   uv_fs_req_cleanup(&write_req);
1740e552da7Schristos 
1750e552da7Schristos   r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
1760e552da7Schristos   ASSERT(r == 0);
1770e552da7Schristos   ASSERT(close_req.result == 0);
1780e552da7Schristos   uv_fs_req_cleanup(&close_req);
1790e552da7Schristos 
1800e552da7Schristos   /* Check contents */
1810e552da7Schristos   r = uv_fs_open(NULL, &open_req, file, UV_FS_O_RDONLY, S_IWUSR | S_IRUSR, NULL);
1820e552da7Schristos   ASSERT(r >= 0);
1830e552da7Schristos   ASSERT(open_req.result >= 0);
1840e552da7Schristos   uv_fs_req_cleanup(&open_req);
1850e552da7Schristos 
1860e552da7Schristos   iov = uv_buf_init(buf, sizeof(buf));
1870e552da7Schristos   r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL);
1880e552da7Schristos   ASSERT(r == size);
1890e552da7Schristos   ASSERT(read_req.result == size);
1900e552da7Schristos   ASSERT(strncmp(buf, expected, size) == 0);
1910e552da7Schristos   uv_fs_req_cleanup(&read_req);
1920e552da7Schristos 
1930e552da7Schristos   r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
1940e552da7Schristos   ASSERT(r == 0);
1950e552da7Schristos   ASSERT(close_req.result == 0);
1960e552da7Schristos   uv_fs_req_cleanup(&close_req);
1970e552da7Schristos 
1980e552da7Schristos   cleanup();
1990e552da7Schristos }
2000e552da7Schristos 
writeFail(char * file,int error)2010e552da7Schristos static void writeFail(char *file, int error) {
2020e552da7Schristos   int r;
2030e552da7Schristos 
2040e552da7Schristos   refreshOpen(file);
2050e552da7Schristos 
2060e552da7Schristos   iov = uv_buf_init("z", 1);
2070e552da7Schristos   r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
2080e552da7Schristos   ASSERT(r == error);
2090e552da7Schristos   ASSERT(write_req.result == error);
2100e552da7Schristos   uv_fs_req_cleanup(&write_req);
2110e552da7Schristos 
2120e552da7Schristos   iov = uv_buf_init("z", 1);
2130e552da7Schristos   r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
2140e552da7Schristos   ASSERT(r == error);
2150e552da7Schristos   ASSERT(write_req.result == error);
2160e552da7Schristos   uv_fs_req_cleanup(&write_req);
2170e552da7Schristos 
2180e552da7Schristos   r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
2190e552da7Schristos   ASSERT(r == 0);
2200e552da7Schristos   ASSERT(close_req.result == 0);
2210e552da7Schristos   uv_fs_req_cleanup(&close_req);
2220e552da7Schristos 
2230e552da7Schristos   cleanup();
2240e552da7Schristos }
2250e552da7Schristos 
readExpect(char * file,char * expected,int size)2260e552da7Schristos static void readExpect(char *file, char *expected, int size) {
2270e552da7Schristos   int r;
2280e552da7Schristos 
2290e552da7Schristos   refreshOpen(file);
2300e552da7Schristos 
2310e552da7Schristos   iov = uv_buf_init(buf, sizeof(buf));
2320e552da7Schristos   r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL);
2330e552da7Schristos   ASSERT(r == size);
2340e552da7Schristos   ASSERT(read_req.result == size);
2350e552da7Schristos   ASSERT(strncmp(buf, expected, size) == 0);
2360e552da7Schristos   uv_fs_req_cleanup(&read_req);
2370e552da7Schristos 
2380e552da7Schristos   r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
2390e552da7Schristos   ASSERT(r == 0);
2400e552da7Schristos   ASSERT(close_req.result == 0);
2410e552da7Schristos   uv_fs_req_cleanup(&close_req);
2420e552da7Schristos 
2430e552da7Schristos   cleanup();
2440e552da7Schristos }
2450e552da7Schristos 
readFail(char * file,int error)2460e552da7Schristos static void readFail(char *file, int error) {
2470e552da7Schristos   int r;
2480e552da7Schristos 
2490e552da7Schristos   refreshOpen(file);
2500e552da7Schristos 
2510e552da7Schristos   iov = uv_buf_init(buf, sizeof(buf));
2520e552da7Schristos   r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL);
2530e552da7Schristos   ASSERT(r == error);
2540e552da7Schristos   ASSERT(read_req.result == error);
2550e552da7Schristos   uv_fs_req_cleanup(&read_req);
2560e552da7Schristos 
2570e552da7Schristos   iov = uv_buf_init(buf, sizeof(buf));
2580e552da7Schristos   r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL);
2590e552da7Schristos   ASSERT(r == error);
2600e552da7Schristos   ASSERT(read_req.result == error);
2610e552da7Schristos   uv_fs_req_cleanup(&read_req);
2620e552da7Schristos 
2630e552da7Schristos   r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
2640e552da7Schristos   ASSERT(r == 0);
2650e552da7Schristos   ASSERT(close_req.result == 0);
2660e552da7Schristos   uv_fs_req_cleanup(&close_req);
2670e552da7Schristos 
2680e552da7Schristos   cleanup();
2690e552da7Schristos }
2700e552da7Schristos 
fs_open_flags(int add_flags)2710e552da7Schristos static void fs_open_flags(int add_flags) {
2720e552da7Schristos   /* Follow the order from
2730e552da7Schristos    * https://github.com/nodejs/node/blob/1a96abe849/lib/internal/fs/utils.js#L329-L354
2740e552da7Schristos    */
2750e552da7Schristos 
2760e552da7Schristos   /* r */
2770e552da7Schristos   flags = add_flags | UV_FS_O_RDONLY;
2780e552da7Schristos   openFail(absent_file, UV_ENOENT);
279*5f2f4271Schristos   writeFail(empty_file, UV_EBADF);
2800e552da7Schristos   readExpect(empty_file, "", 0);
281*5f2f4271Schristos   writeFail(dummy_file, UV_EBADF);
2820e552da7Schristos   readExpect(dummy_file, "a", 1);
283*5f2f4271Schristos   writeFail(empty_dir, UV_EBADF);
2840e552da7Schristos   readFail(empty_dir, UV_EISDIR);
2850e552da7Schristos 
2860e552da7Schristos   /* rs */
2870e552da7Schristos   flags = add_flags | UV_FS_O_RDONLY | UV_FS_O_SYNC;
2880e552da7Schristos   openFail(absent_file, UV_ENOENT);
289*5f2f4271Schristos   writeFail(empty_file, UV_EBADF);
2900e552da7Schristos   readExpect(empty_file, "", 0);
291*5f2f4271Schristos   writeFail(dummy_file, UV_EBADF);
2920e552da7Schristos   readExpect(dummy_file, "a", 1);
293*5f2f4271Schristos   writeFail(empty_dir, UV_EBADF);
2940e552da7Schristos   readFail(empty_dir, UV_EISDIR);
2950e552da7Schristos 
2960e552da7Schristos   /* r+ */
2970e552da7Schristos   flags = add_flags | UV_FS_O_RDWR;
2980e552da7Schristos   openFail(absent_file, UV_ENOENT);
2990e552da7Schristos   writeExpect(empty_file, "bc", 2);
3000e552da7Schristos   readExpect(empty_file, "", 0);
3010e552da7Schristos   writeExpect(dummy_file, "bc", 2);
3020e552da7Schristos   readExpect(dummy_file, "a", 1);
3030e552da7Schristos   writeFail(empty_dir, UV_EISDIR);
3040e552da7Schristos   readFail(empty_dir, UV_EISDIR);
3050e552da7Schristos 
3060e552da7Schristos   /* rs+ */
3070e552da7Schristos   flags = add_flags | UV_FS_O_RDWR | UV_FS_O_SYNC;
3080e552da7Schristos   openFail(absent_file, UV_ENOENT);
3090e552da7Schristos   writeExpect(empty_file, "bc", 2);
3100e552da7Schristos   readExpect(empty_file, "", 0);
3110e552da7Schristos   writeExpect(dummy_file, "bc", 2);
3120e552da7Schristos   readExpect(dummy_file, "a", 1);
3130e552da7Schristos   writeFail(empty_dir, UV_EISDIR);
3140e552da7Schristos   readFail(empty_dir, UV_EISDIR);
3150e552da7Schristos 
3160e552da7Schristos   /* w */
3170e552da7Schristos   flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY;
3180e552da7Schristos   writeExpect(absent_file, "bc", 2);
319*5f2f4271Schristos   readFail(absent_file, UV_EBADF);
3200e552da7Schristos   writeExpect(empty_file, "bc", 2);
321*5f2f4271Schristos   readFail(empty_file, UV_EBADF);
3220e552da7Schristos   writeExpect(dummy_file, "bc", 2);
323*5f2f4271Schristos   readFail(dummy_file, UV_EBADF);
3240e552da7Schristos   openFail(empty_dir, UV_EISDIR);
3250e552da7Schristos 
3260e552da7Schristos   /* wx */
3270e552da7Schristos   flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY |
3280e552da7Schristos     UV_FS_O_EXCL;
3290e552da7Schristos   writeExpect(absent_file, "bc", 2);
330*5f2f4271Schristos   readFail(absent_file, UV_EBADF);
3310e552da7Schristos   openFail(empty_file, UV_EEXIST);
3320e552da7Schristos   openFail(dummy_file, UV_EEXIST);
3330e552da7Schristos   openFail(empty_dir, UV_EEXIST);
3340e552da7Schristos 
3350e552da7Schristos   /* w+ */
3360e552da7Schristos   flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_RDWR;
3370e552da7Schristos   writeExpect(absent_file, "bc", 2);
3380e552da7Schristos   readExpect(absent_file, "", 0);
3390e552da7Schristos   writeExpect(empty_file, "bc", 2);
3400e552da7Schristos   readExpect(empty_file, "", 0);
3410e552da7Schristos   writeExpect(dummy_file, "bc", 2);
3420e552da7Schristos   readExpect(dummy_file, "", 0);
3430e552da7Schristos   openFail(empty_dir, UV_EISDIR);
3440e552da7Schristos 
3450e552da7Schristos   /* wx+ */
3460e552da7Schristos   flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_RDWR |
3470e552da7Schristos     UV_FS_O_EXCL;
3480e552da7Schristos   writeExpect(absent_file, "bc", 2);
3490e552da7Schristos   readExpect(absent_file, "", 0);
3500e552da7Schristos   openFail(empty_file, UV_EEXIST);
3510e552da7Schristos   openFail(dummy_file, UV_EEXIST);
3520e552da7Schristos   openFail(empty_dir, UV_EEXIST);
3530e552da7Schristos 
3540e552da7Schristos   /* a */
3550e552da7Schristos   flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY;
3560e552da7Schristos   writeExpect(absent_file, "bc", 2);
357*5f2f4271Schristos   readFail(absent_file, UV_EBADF);
3580e552da7Schristos   writeExpect(empty_file, "bc", 2);
359*5f2f4271Schristos   readFail(empty_file, UV_EBADF);
3600e552da7Schristos   writeExpect(dummy_file, "abc", 3);
361*5f2f4271Schristos   readFail(dummy_file, UV_EBADF);
3620e552da7Schristos   writeFail(empty_dir, UV_EISDIR);
363*5f2f4271Schristos   readFail(empty_dir, UV_EBADF);
3640e552da7Schristos 
3650e552da7Schristos   /* ax */
3660e552da7Schristos   flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY |
3670e552da7Schristos     UV_FS_O_EXCL;
3680e552da7Schristos   writeExpect(absent_file, "bc", 2);
369*5f2f4271Schristos   readFail(absent_file, UV_EBADF);
3700e552da7Schristos   openFail(empty_file, UV_EEXIST);
3710e552da7Schristos   openFail(dummy_file, UV_EEXIST);
3720e552da7Schristos   openFail(empty_dir, UV_EEXIST);
3730e552da7Schristos 
3740e552da7Schristos   /* as */
3750e552da7Schristos   flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY |
3760e552da7Schristos     UV_FS_O_SYNC;
3770e552da7Schristos   writeExpect(absent_file, "bc", 2);
378*5f2f4271Schristos   readFail(absent_file, UV_EBADF);
3790e552da7Schristos   writeExpect(empty_file, "bc", 2);
380*5f2f4271Schristos   readFail(empty_file, UV_EBADF);
3810e552da7Schristos   writeExpect(dummy_file, "abc", 3);
382*5f2f4271Schristos   readFail(dummy_file, UV_EBADF);
3830e552da7Schristos   writeFail(empty_dir, UV_EISDIR);
384*5f2f4271Schristos   readFail(empty_dir, UV_EBADF);
3850e552da7Schristos 
3860e552da7Schristos   /* a+ */
3870e552da7Schristos   flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR;
3880e552da7Schristos   writeExpect(absent_file, "bc", 2);
3890e552da7Schristos   readExpect(absent_file, "", 0);
3900e552da7Schristos   writeExpect(empty_file, "bc", 2);
3910e552da7Schristos   readExpect(empty_file, "", 0);
3920e552da7Schristos   writeExpect(dummy_file, "abc", 3);
3930e552da7Schristos   readExpect(dummy_file, "a", 1);
3940e552da7Schristos   writeFail(empty_dir, UV_EISDIR);
3950e552da7Schristos   readFail(empty_dir, UV_EISDIR);
3960e552da7Schristos 
3970e552da7Schristos   /* ax+ */
3980e552da7Schristos   flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR |
3990e552da7Schristos     UV_FS_O_EXCL;
4000e552da7Schristos   writeExpect(absent_file, "bc", 2);
4010e552da7Schristos   readExpect(absent_file, "", 0);
4020e552da7Schristos   openFail(empty_file, UV_EEXIST);
4030e552da7Schristos   openFail(dummy_file, UV_EEXIST);
4040e552da7Schristos   openFail(empty_dir, UV_EEXIST);
4050e552da7Schristos 
4060e552da7Schristos   /* as+ */
4070e552da7Schristos   flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR |
4080e552da7Schristos     UV_FS_O_SYNC;
4090e552da7Schristos   writeExpect(absent_file, "bc", 2);
4100e552da7Schristos   readExpect(absent_file, "", 0);
4110e552da7Schristos   writeExpect(empty_file, "bc", 2);
4120e552da7Schristos   readExpect(empty_file, "", 0);
4130e552da7Schristos   writeExpect(dummy_file, "abc", 3);
4140e552da7Schristos   readExpect(dummy_file, "a", 1);
4150e552da7Schristos   writeFail(empty_dir, UV_EISDIR);
4160e552da7Schristos   readFail(empty_dir, UV_EISDIR);
4170e552da7Schristos }
TEST_IMPL(fs_open_flags)4180e552da7Schristos TEST_IMPL(fs_open_flags) {
4190e552da7Schristos   setup();
4200e552da7Schristos 
4210e552da7Schristos   fs_open_flags(0);
4220e552da7Schristos   fs_open_flags(UV_FS_O_FILEMAP);
4230e552da7Schristos 
4240e552da7Schristos   /* Cleanup. */
4250e552da7Schristos   rmdir(empty_dir);
4260e552da7Schristos 
4270e552da7Schristos   MAKE_VALGRIND_HAPPY();
4280e552da7Schristos   return 0;
4290e552da7Schristos }
4300e552da7Schristos 
4310e552da7Schristos #else
4320e552da7Schristos 
4330e552da7Schristos typedef int file_has_no_tests;  /* ISO C forbids an empty translation unit. */
4340e552da7Schristos 
4350e552da7Schristos #endif  /* ifndef _WIN32 */
436