kernel32: Add message resource for TRUST_E_NOSIGNATURE.
[wine.git] / dlls / msvcrt / tests / file.c
blob136ee1563e659afe04989ee07c8e27ed61d33b00
1 /*
2 * Unit test suite for file functions
4 * Copyright 2002 Bill Currie
5 * Copyright 2005 Paul Rupe
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/test.h"
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <fcntl.h>
27 #include <share.h>
28 #include <sys/stat.h>
29 #include <io.h>
30 #include <direct.h>
31 #include <windef.h>
32 #include <winbase.h>
33 #include <winnls.h>
34 #include <winreg.h>
35 #include <process.h>
36 #include <errno.h>
37 #include <locale.h>
39 #define MSVCRT_FD_BLOCK_SIZE 32
40 typedef struct {
41 HANDLE handle;
42 unsigned char wxflag;
43 char lookahead[3];
44 int exflag;
45 CRITICAL_SECTION crit;
46 } ioinfo;
47 static ioinfo **__pioinfo;
49 static HANDLE proc_handles[2];
51 static int (__cdecl *p_fopen_s)(FILE**, const char*, const char*);
52 static int (__cdecl *p__wfopen_s)(FILE**, const wchar_t*, const wchar_t*);
53 static errno_t (__cdecl *p__get_fmode)(int*);
54 static errno_t (__cdecl *p__set_fmode)(int);
56 static const char* get_base_name(const char *path)
58 const char *ret = path+strlen(path)-1;
60 while(ret >= path) {
61 if(*ret=='\\' || *ret=='/')
62 break;
63 ret--;
65 return ret+1;
68 static void init(void)
70 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
72 setlocale(LC_CTYPE, "C");
74 p_fopen_s = (void*)GetProcAddress(hmod, "fopen_s");
75 p__wfopen_s = (void*)GetProcAddress(hmod, "_wfopen_s");
76 __pioinfo = (void*)GetProcAddress(hmod, "__pioinfo");
77 p__get_fmode = (void*)GetProcAddress(hmod, "_get_fmode");
78 p__set_fmode = (void*)GetProcAddress(hmod, "_set_fmode");
81 static void test_filbuf( void )
83 FILE *fp;
84 int c;
85 fpos_t pos;
87 fp = fopen("filbuf.tst", "wb");
88 fwrite("\n\n\n\n", 1, 4, fp);
89 fclose(fp);
91 fp = fopen("filbuf.tst", "rt");
92 c = _filbuf(fp);
93 ok(c == '\n', "read wrong byte\n");
94 /* See bug 16970 for why we care about _filbuf.
95 * ftell returns screwy values on files with lots
96 * of bare LFs in ascii mode because it assumes
97 * that ascii files contain only CRLFs, removes
98 * the CR's early in _filbuf, and adjusts the return
99 * value of ftell to compensate.
100 * native _filbuf will read the whole file, then consume and return
101 * the first one. That leaves fp->_fd at offset 4, and fp->_ptr
102 * pointing to a buffer of three bare LFs, so
103 * ftell will return 4 - 3 - 3 = -2.
105 ok(ftell(fp) == -2, "ascii crlf removal does not match native\n");
106 ok(fgetpos(fp, &pos) == 0, "fgetpos fail\n");
107 ok(pos == -2, "ftell does not match fgetpos\n");
108 fclose(fp);
109 unlink("filbuf.tst");
112 static void test_fdopen( void )
114 static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
115 char ibuf[10];
116 int fd;
117 FILE *file;
119 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
120 write (fd, buffer, sizeof (buffer));
121 close (fd);
123 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
124 lseek (fd, 5, SEEK_SET);
125 file = fdopen (fd, "rb");
126 ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
127 ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
128 fclose (file);
129 unlink ("fdopen.tst");
132 static void test_fileops( void )
134 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
135 char buffer[256];
136 WCHAR wbuffer[256];
137 int fd;
138 FILE *file;
139 fpos_t pos;
140 int i, c, bufmode;
141 static const int bufmodes[] = {_IOFBF,_IONBF};
143 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
144 write (fd, outbuffer, sizeof (outbuffer));
145 close (fd);
147 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
149 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
150 file = fdopen (fd, "rb");
151 setvbuf(file,NULL,bufmodes[bufmode],2048);
152 if(bufmodes[bufmode] == _IOFBF)
153 ok(file->_bufsiz == 2048, "file->_bufsiz = %d\n", file->_bufsiz);
154 ok(file->_base != NULL, "file->_base = NULL\n");
155 ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes[bufmode]);
156 ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
157 ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
158 ok(feof(file) !=0,"feof doesn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
159 rewind(file);
160 ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
161 ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size for bufmode=%x\n", bufmodes[bufmode]);
162 ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
163 ok(strlen(buffer) == 1,"fgets dropped chars for bufmode=%x\n", bufmodes[bufmode]);
164 ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars for bufmode=%x\n", bufmodes[bufmode]);
166 rewind(file);
167 for (i = 0; i < sizeof(outbuffer); i++)
169 ok(fgetc(file) == outbuffer[i], "fgetc returned wrong data for bufmode=%x\n", bufmodes[bufmode]);
171 ok((c = fgetc(file)) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
172 ok(feof(file), "feof did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
173 ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
174 ok(feof(file), "feof after ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
175 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
176 c = outbuffer[sizeof(outbuffer) - 1];
177 ok(ungetc(c, file) == c, "ungetc did not return its input for bufmode=%x\n", bufmodes[bufmode]);
178 ok(!feof(file), "feof after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
179 ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
180 ok(c == outbuffer[sizeof(outbuffer) - 1],
181 "getc did not return ungetc'd data for bufmode=%x\n", bufmodes[bufmode]);
182 ok(!feof(file), "feof after getc returned EOF prematurely for bufmode=%x\n", bufmodes[bufmode]);
183 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
184 ok(feof(file), "feof after getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
186 rewind(file);
187 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
188 ok(pos == 0, "Unexpected result of fgetpos %s for bufmode=%x\n", wine_dbgstr_longlong(pos), bufmodes[bufmode]);
189 pos = sizeof (outbuffer);
190 ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
191 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
192 ok(pos == sizeof (outbuffer), "Unexpected result of fgetpos %s for bufmode=%x\n", wine_dbgstr_longlong(pos), bufmodes[bufmode]);
194 fclose (file);
196 fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
197 file = fdopen (fd, "rt"); /* open in TEXT mode */
198 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n");
199 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n");
200 ok(feof(file) !=0,"feof doesn't signal EOF\n");
201 rewind(file);
202 ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
203 ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
204 ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n");
205 ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
206 fclose (file);
208 file = fopen("fdopen.tst", "rb");
209 ok( file != NULL, "fopen failed\n");
210 /* sizeof(buffer) > content of file */
211 ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n");
212 /* feof should be set now */
213 ok(feof(file), "feof after fread failed\n");
214 fclose (file);
216 unlink ("fdopen.tst");
219 #define IOMODE (ao?"ascii mode":"binary mode")
220 static void test_readmode( BOOL ascii_mode )
222 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9\r\n\r\nA,B,C,D,E\r\nX,Y,Z";
223 static const char padbuffer[] = "ghjghjghjghj";
224 static const char nlbuffer[] = "\r\n";
225 static char buffer[8192];
226 const char *optr;
227 int fd;
228 FILE *file;
229 const int *ip;
230 int i, j, m, ao, pl;
231 unsigned int fp;
232 LONG l;
234 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
235 /* an internal buffer of BUFSIZ is maintained, so make a file big
236 * enough to test operations that cross the buffer boundary
238 j = (2*BUFSIZ-4)/strlen(padbuffer);
239 for (i=0; i<j; i++)
240 write (fd, padbuffer, strlen(padbuffer));
241 j = (2*BUFSIZ-4)%strlen(padbuffer);
242 for (i=0; i<j; i++)
243 write (fd, &padbuffer[i], 1);
244 write (fd, nlbuffer, strlen(nlbuffer));
245 write (fd, outbuffer, sizeof (outbuffer));
246 close (fd);
248 if (ascii_mode) {
249 /* Open file in ascii mode */
250 fd = open ("fdopen.tst", O_RDONLY);
251 file = fdopen (fd, "r");
252 ao = -1; /* on offset to account for carriage returns */
254 else {
255 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
256 file = fdopen (fd, "rb");
257 ao = 0;
260 /* first is a test of fgets, ftell, fseek */
261 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
262 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
263 l = ftell(file);
264 pl = 2*BUFSIZ-2;
265 ok(l == pl,"padding line ftell got %d should be %d in %s\n", l, pl, IOMODE);
266 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
267 lstrlenA(buffer), pl+ao, IOMODE);
268 for (fp=0; fp<strlen(outbuffer); fp++)
269 if (outbuffer[fp] == '\n') break;
270 fp++;
271 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
272 l = ftell(file);
273 ok(l == pl+fp,"line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
274 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
275 lstrlenA(buffer), fp+ao, IOMODE);
276 /* test a seek back across the buffer boundary */
277 l = pl;
278 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
279 l = ftell(file);
280 ok(l == pl,"ftell after seek got %d should be %d in %s\n", l, pl, IOMODE);
281 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
282 l = ftell(file);
283 ok(l == pl+fp,"second read of line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
284 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
285 lstrlenA(buffer), fp+ao, IOMODE);
286 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
287 fp += 2;
288 l = ftell(file);
289 ok(l == pl+fp,"line 2 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
290 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
291 lstrlenA(buffer), 2+ao, IOMODE);
293 /* test fread across buffer boundary */
294 rewind(file);
295 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
296 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
297 j=strlen(outbuffer);
298 i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file);
299 ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE);
300 l = ftell(file);
301 ok(l == pl+j-(ao*4)-5,"ftell after fread got %d should be %d in %s\n", l, pl+j-(ao*4)-5, IOMODE);
302 for (m=0; m<3; m++)
303 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
304 m+=BUFSIZ+2+ao;
305 optr = outbuffer;
306 for (; m<i; m++) {
307 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
308 optr++;
309 if (ao && (*optr == '\r'))
310 optr++;
312 /* fread should return the requested number of bytes if available */
313 rewind(file);
314 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
315 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
316 j = fp+10;
317 i=fread(buffer,1,j,file);
318 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
319 /* test fread eof */
320 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
321 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
322 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
323 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
324 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
325 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
326 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
327 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
328 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
329 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
331 /* test some additional functions */
332 rewind(file);
333 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
334 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
335 i = _getw(file);
336 ip = (const int *)outbuffer;
337 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
338 for (fp=0; fp<strlen(outbuffer); fp++)
339 if (outbuffer[fp] == '\n') break;
340 fp++;
341 /* this will cause the next _getw to cross carriage return characters */
342 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
343 for (i=0, j=0; i<6; i++) {
344 if (ao==0 || outbuffer[fp-3+i] != '\r')
345 buffer[j++] = outbuffer[fp-3+i];
347 i = _getw(file);
348 ip = (int *)buffer;
349 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
351 fclose (file);
352 unlink ("fdopen.tst");
354 /* test INTERNAL_BUFSIZ read containing 0x1a character (^Z) */
355 fd = open("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
356 ok(fd != -1, "open failed\n");
357 memset(buffer, 'a', sizeof(buffer));
358 buffer[1] = 0x1a;
359 ok(write(fd, buffer, sizeof(buffer)) == sizeof(buffer), "write failed\n");
360 ok(close(fd) != -1, "close failed\n");
362 fd = open("fdopen.tst", O_RDONLY);
363 ok(fd != -1, "open failed\n");
364 file = fdopen(fd, ascii_mode ? "r" : "rb");
365 ok(file != NULL, "fdopen failed\n");
367 memset(buffer, 0, sizeof(buffer));
368 i = fread(buffer, 4096, 1, file);
369 ok(!i, "fread succeeded\n");
370 ok(file->_bufsiz == 4096, "file->_bufsiz = %d\n", file->_bufsiz);
371 for(i=0; i<4096; i++)
372 if(buffer[i] != (i==1 ? 0x1a : 'a')) break;
373 ok(i==4096, "buffer[%d] = %d\n", i, buffer[i]);
375 fclose(file);
376 unlink("fdopen.tst");
379 static void test_asciimode(void)
381 FILE *fp;
382 char buf[64];
383 int c, i, j;
385 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
386 fp = fopen("ascii.tst", "wb");
387 fputs("\r\r\n", fp);
388 fclose(fp);
389 fp = fopen("ascii.tst", "rt");
390 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets\n");
391 ok(0 == strcmp(buf, "\r\n"), "CR CR LF not read as CR LF\n");
392 rewind(fp);
393 ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n");
394 fclose(fp);
395 unlink("ascii.tst");
397 /* Simple test of foo ^Z [more than one block] bar handling */
398 fp = fopen("ascii.tst", "wb");
399 fputs("foo\032", fp); /* foo, logical EOF, ... */
400 fseek(fp, 65536L, SEEK_SET); /* ... more than MSVCRT_BUFSIZ, ... */
401 fputs("bar", fp); /* ... bar */
402 fclose(fp);
403 fp = fopen("ascii.tst", "rt");
404 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets foo\n");
405 ok(0 == strcmp(buf, "foo"), "foo ^Z not read as foo by fgets\n");
406 ok(fgets(buf, sizeof(buf), fp) == NULL, "fgets after logical EOF\n");
407 rewind(fp);
408 ok((fread(buf, 1, sizeof(buf), fp) == 3) && (0 == strcmp(buf, "foo")), "foo ^Z not read as foo by fread\n");
409 ok((fread(buf, 1, sizeof(buf), fp) == 0), "fread after logical EOF\n");
410 fclose(fp);
412 /* Show ASCII mode handling*/
413 fp= fopen("ascii.tst","wb");
414 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp);
415 fclose(fp);
417 fp = fopen("ascii.tst", "r");
418 c= fgetc(fp);
419 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
420 c= fgetc(fp);
421 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
422 fseek(fp,0,SEEK_CUR);
423 for(i=1; i<10; i++) {
424 ok((j = ftell(fp)) == i*3, "ftell fails in TEXT mode\n");
425 fseek(fp,0,SEEK_CUR);
426 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek failed in line %d\n", i);
427 c= fgetc(fp);
428 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
430 /* Show that fseek doesn't skip \\r !*/
431 rewind(fp);
432 c= fgetc(fp);
433 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
434 fseek(fp, 2 ,SEEK_CUR);
435 for(i=1; i<10; i++) {
436 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with pos Offset failed in line %d\n", i);
437 fseek(fp, 2 ,SEEK_CUR);
439 fseek(fp, 9*3 ,SEEK_SET);
440 c = fgetc(fp);
441 ok(c == '9', "fgetc failed, expected '9', got '%c'\n", c);
442 fseek(fp, -4 ,SEEK_CUR);
443 for(i= 8; i>=0; i--) {
444 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with neg Offset failed in line %d\n", i);
445 fseek(fp, -4 ,SEEK_CUR);
447 /* Show what happens if fseek positions filepointer on \\r */
448 fclose(fp);
449 fp = fopen("ascii.tst", "r");
450 fseek(fp, 3 ,SEEK_SET);
451 ok((c = fgetc(fp)) == '1', "fgetc fails to read next char when positioned on \\r\n");
452 fclose(fp);
454 unlink("ascii.tst");
457 static void test_asciimode2(void)
459 /* Error sequence from one app was getchar followed by small fread
460 * with one \r removed had last byte of buffer filled with
461 * next byte of *unbuffered* data rather than next byte from buffer
462 * Test case is a short string of one byte followed by a newline
463 * followed by filler to fill out the sector, then a sector of
464 * some different byte.
467 FILE *fp;
468 char ibuf[4];
469 int i;
470 static const char obuf[] =
471 "00\n"
472 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
473 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
474 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
475 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
476 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
477 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
478 "000000000000000000\n"
479 "1111111111111111111";
481 fp = fopen("ascii2.tst", "wt");
482 fwrite(obuf, 1, sizeof(obuf), fp);
483 fclose(fp);
485 fp = fopen("ascii2.tst", "rt");
486 ok(getc(fp) == '0', "first char not 0\n");
487 memset(ibuf, 0, sizeof(ibuf));
488 i = fread(ibuf, 1, sizeof(ibuf), fp);
489 ok(i == sizeof(ibuf), "fread i %d != sizeof(ibuf)\n", i);
490 ok(0 == strncmp(ibuf, obuf+1, sizeof(ibuf)), "ibuf != obuf\n");
491 fclose(fp);
492 unlink("ascii2.tst");
495 static void test_filemodeT(void)
497 char DATA [] = {26, 't', 'e', 's' ,'t'};
498 char DATA2 [100];
499 char temppath[MAX_PATH];
500 char tempfile[MAX_PATH];
501 FILE* f;
502 size_t bytesWritten;
503 size_t bytesRead;
504 WIN32_FIND_DATAA findData;
505 HANDLE h;
507 GetTempPathA(MAX_PATH, temppath);
508 GetTempFileNameA(temppath, "", 0, tempfile);
510 f = fopen(tempfile, "w+bDT");
511 bytesWritten = fwrite(DATA, 1, sizeof(DATA), f);
512 rewind(f);
513 bytesRead = fread(DATA2, 1, sizeof(DATA2), f);
514 fclose(f);
516 ok (bytesRead == bytesWritten && bytesRead == sizeof(DATA),
517 "fopen file mode 'T' wrongly interpreted as 't'\n" );
519 h = FindFirstFileA(tempfile, &findData);
521 ok (h == INVALID_HANDLE_VALUE, "file wasn't deleted when closed.\n" );
523 if (h != INVALID_HANDLE_VALUE) FindClose(h);
526 static WCHAR* AtoW( const char* p )
528 WCHAR* buffer;
529 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
530 buffer = malloc( len * sizeof(WCHAR) );
531 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
532 return buffer;
535 /* Test reading in text mode when the 512'th character read is \r*/
536 static void test_readboundary(void)
538 FILE *fp;
539 char buf[513], rbuf[513];
540 int i, j;
541 for (i = 0; i < 511; i++)
543 j = (i%('~' - ' ')+ ' ');
544 buf[i] = j;
546 buf[511] = '\n';
547 buf[512] =0;
548 fp = fopen("boundary.tst", "wt");
549 fwrite(buf, 512,1,fp);
550 fclose(fp);
551 fp = fopen("boundary.tst", "rt");
552 for(i=0; i<512; i++)
554 fseek(fp,0 , SEEK_CUR);
555 rbuf[i] = fgetc(fp);
557 rbuf[512] =0;
558 fclose(fp);
559 unlink("boundary.tst");
561 ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n");
564 static void test_fgetc( void )
566 char* tempf;
567 FILE *tempfh;
568 int ich=0xe0, ret;
570 tempf=_tempnam(".","wne");
571 tempfh = fopen(tempf,"w+");
572 fputc(ich, tempfh);
573 fputc(ich, tempfh);
574 rewind(tempfh);
575 ret = fgetc(tempfh);
576 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
577 ret = fgetc(tempfh);
578 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
579 fclose(tempfh);
580 tempfh = fopen(tempf,"wt");
581 fputc('\n', tempfh);
582 fclose(tempfh);
583 tempfh = fopen(tempf,"wt");
584 setbuf(tempfh, NULL);
585 ret = fgetc(tempfh);
586 ok(ret == -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
587 fclose(tempfh);
588 unlink(tempf);
589 free(tempf);
592 static void test_fputc( void )
594 char* tempf;
595 FILE *tempfh;
596 int ret;
598 tempf=_tempnam(".","wne");
599 tempfh = fopen(tempf,"wb");
600 ret = fputc(0,tempfh);
601 ok(0 == ret, "fputc(0,tempfh) expected %x got %x\n", 0, ret);
602 ret = fputc(0xff,tempfh);
603 ok(0xff == ret, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret);
604 ret = fputc(0xffffffff,tempfh);
605 ok(0xff == ret, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret);
606 fclose(tempfh);
608 tempfh = fopen(tempf,"rb");
609 ret = fputc(0,tempfh);
610 ok(EOF == ret, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
611 fclose(tempfh);
613 unlink(tempf);
614 free(tempf);
617 static void test_flsbuf( void )
619 char* tempf;
620 FILE *tempfh;
621 int c;
622 int ret;
623 int bufmode;
624 static const int bufmodes[] = {_IOFBF,_IONBF};
626 tempf=_tempnam(".","wne");
627 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
629 tempfh = fopen(tempf,"wb");
630 setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
631 ret = _flsbuf(0,tempfh);
632 ok(0 == ret, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
633 bufmodes[bufmode], 0, ret);
634 ret = _flsbuf(0xff,tempfh);
635 ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
636 bufmodes[bufmode], 0xff, ret);
637 ret = _flsbuf(0xffffffff,tempfh);
638 ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
639 bufmodes[bufmode], 0xff, ret);
640 if(tempfh->_base) {
641 fputc('x', tempfh);
642 tempfh->_cnt = -1;
643 tempfh->_base[1] = 'a';
644 ret = _flsbuf(0xab,tempfh);
645 ok(ret == 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got %x\n",
646 bufmodes[bufmode], ret);
647 ok(tempfh->_base[1] == 'a', "tempfh->_base[1] should not be changed (%d)\n",
648 tempfh->_base[1]);
651 fclose(tempfh);
654 tempfh = fopen(tempf,"rb");
655 ret = _flsbuf(0,tempfh);
656 ok(EOF == ret, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
657 fclose(tempfh);
659 /* See bug 17123, exposed by WinAVR's make */
660 tempfh = fopen(tempf,"w");
661 ok(tempfh->_cnt == 0, "_cnt on freshly opened file was %d\n", tempfh->_cnt);
662 setbuf(tempfh, NULL);
663 ok(tempfh->_cnt == 0, "_cnt on unbuffered file was %d\n", tempfh->_cnt);
664 ok(tempfh->_bufsiz == 2, "_bufsiz = %d\n", tempfh->_bufsiz);
665 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
666 tempfh->_cnt = 1234;
667 ret = _flsbuf('Q',tempfh);
668 ok('Q' == ret, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret);
669 /* ... and reset it to zero */
670 ok(tempfh->_cnt == 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh->_cnt);
671 fclose(tempfh);
672 /* And just for grins, make sure the file is correct */
673 tempfh = fopen(tempf,"r");
674 c = fgetc(tempfh);
675 ok(c == 'Q', "first byte should be 'Q'\n");
676 c = fgetc(tempfh);
677 ok(c == EOF, "there should only be one byte\n");
678 fclose(tempfh);
680 unlink(tempf);
681 free(tempf);
684 static void test_fflush( void )
686 static const char obuf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
687 char buf1[16], buf2[24];
688 char *tempf;
689 FILE *tempfh;
690 int ret;
692 tempf=_tempnam(".","wne");
694 /* Prepare the file. */
695 tempfh = fopen(tempf,"wb");
696 ok(tempfh != NULL, "Can't open test file.\n");
697 fwrite(obuf, 1, sizeof(obuf), tempfh);
698 fclose(tempfh);
700 /* Open the file for input. */
701 tempfh = fopen(tempf,"rb");
702 ok(tempfh != NULL, "Can't open test file.\n");
703 fread(buf1, 1, sizeof(buf1), tempfh);
705 /* Using fflush() on input stream is undefined in ANSI.
706 * But MSDN says that it clears input buffer. */
707 _lseek(_fileno(tempfh), 0, SEEK_SET);
708 ret = fflush(tempfh);
709 ok(ret == 0, "expected 0, got %d\n", ret);
710 memset(buf2, '?', sizeof(buf2));
711 fread(buf2, 1, sizeof(buf2), tempfh);
712 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
714 /* fflush(NULL) doesn't clear input buffer. */
715 _lseek(_fileno(tempfh), 0, SEEK_SET);
716 ret = fflush(NULL);
717 ok(ret == 0, "expected 0, got %d\n", ret);
718 memset(buf2, '?', sizeof(buf2));
719 fread(buf2, 1, sizeof(buf2), tempfh);
720 ok(memcmp(buf1, buf2, sizeof(buf1)) != 0, "Got unexpected data (%c)\n", buf2[0]);
722 /* _flushall() clears input buffer. */
723 _lseek(_fileno(tempfh), 0, SEEK_SET);
724 ret = _flushall();
725 ok(ret >= 0, "unexpected ret %d\n", ret);
726 memset(buf2, '?', sizeof(buf2));
727 fread(buf2, 1, sizeof(buf2), tempfh);
728 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
730 fclose(tempfh);
732 unlink(tempf);
733 free(tempf);
736 static void test_fgetwc( void )
738 #define LLEN 512
740 char* tempf;
741 FILE *tempfh;
742 static const char mytext[]= "This is test_fgetwc\r\n";
743 WCHAR wtextW[BUFSIZ+LLEN+1];
744 WCHAR *mytextW = NULL, *aptr, *wptr;
745 BOOL diff_found = FALSE;
746 int j;
747 unsigned int i;
748 LONG l;
750 tempf=_tempnam(".","wne");
751 tempfh = fopen(tempf,"wb");
752 j = 'a';
753 /* pad to almost the length of the internal buffer */
754 for (i=0; i<BUFSIZ-4; i++)
755 fputc(j,tempfh);
756 j = '\r';
757 fputc(j,tempfh);
758 j = '\n';
759 fputc(j,tempfh);
760 fputs(mytext,tempfh);
761 fclose(tempfh);
762 /* in text mode, getws/c expects multibyte characters */
763 /*currently Wine only supports plain ascii, and that is all that is tested here */
764 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
765 fgetws(wtextW,LLEN,tempfh);
766 l=ftell(tempfh);
767 ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l);
768 fgetws(wtextW,LLEN,tempfh);
769 l=ftell(tempfh);
770 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlenA(mytext), l);
771 mytextW = AtoW (mytext);
772 aptr = mytextW;
773 wptr = wtextW;
774 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
776 diff_found |= (*aptr != *wptr);
778 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
779 ok(*wptr == '\n', "Carriage return was not skipped\n");
780 fclose(tempfh);
781 unlink(tempf);
783 tempfh = fopen(tempf,"wb");
784 j = 'a';
785 /* pad to almost the length of the internal buffer. Use an odd number of bytes
786 to test that we can read wchars that are split across the internal buffer
787 boundary */
788 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
789 fputc(j,tempfh);
790 j = '\r';
791 fputwc(j,tempfh);
792 j = '\n';
793 fputwc(j,tempfh);
794 fputws(wtextW,tempfh);
795 fputws(wtextW,tempfh);
796 fclose(tempfh);
797 /* in binary mode, getws/c expects wide characters */
798 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
799 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
800 fgetws(wtextW,j,tempfh);
801 l=ftell(tempfh);
802 j=(j-1)*sizeof(WCHAR);
803 ok(l==j, "ftell expected %d got %d\n", j, l);
804 i=fgetc(tempfh);
805 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
806 l=ftell(tempfh);
807 j++;
808 ok(l==j, "ftell expected %d got %d\n", j, l);
809 fgetws(wtextW,3,tempfh);
810 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
811 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
812 l=ftell(tempfh);
813 j += 4;
814 ok(l==j, "ftell expected %d got %d\n", j, l);
815 for(i=0; i<strlen(mytext); i++)
816 wtextW[i] = 0;
817 /* the first time we get the string, it should be entirely within the local buffer */
818 fgetws(wtextW,LLEN,tempfh);
819 l=ftell(tempfh);
820 j += (strlen(mytext)-1)*sizeof(WCHAR);
821 ok(l==j, "ftell expected %d got %d\n", j, l);
822 diff_found = FALSE;
823 aptr = mytextW;
824 wptr = wtextW;
825 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
827 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
828 diff_found |= (*aptr != *wptr);
830 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
831 ok(*wptr == '\n', "Should get newline\n");
832 for(i=0; i<strlen(mytext); i++)
833 wtextW[i] = 0;
834 /* the second time we get the string, it should cross the local buffer boundary.
835 One of the wchars should be split across the boundary */
836 fgetws(wtextW,LLEN,tempfh);
837 diff_found = FALSE;
838 aptr = mytextW;
839 wptr = wtextW;
840 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
842 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
843 diff_found |= (*aptr != *wptr);
845 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
846 ok(*wptr == '\n', "Should get newline\n");
848 free(mytextW);
849 fclose(tempfh);
850 unlink(tempf);
851 free(tempf);
854 static void test_fgetwc_locale(const char* text, const char* locale, int codepage)
856 char temppath[MAX_PATH], tempfile[MAX_PATH];
857 FILE *tempfh;
858 static const WCHAR wchar_text[] = { 0xfeff, 0xff1f, '!' };
859 WCHAR wtextW[BUFSIZ];
860 int ret = 0, i;
861 wint_t ch;
863 if (!setlocale(LC_CTYPE, locale))
865 win_skip("%s locale not available\n", locale);
866 return;
869 GetTempPathA(MAX_PATH, temppath);
870 GetTempFileNameA(temppath, "", 0, tempfile);
872 tempfh = fopen(tempfile, "wb");
873 ok(tempfh != NULL, "can't open tempfile\n");
874 fwrite(text, 1, strlen(text), tempfh);
875 fclose(tempfh);
877 if (codepage != 0)
879 /* mbstowcs rejects invalid multibyte sequence,
880 so we use MultiByteToWideChar here. */
881 ret = MultiByteToWideChar(codepage, 0, text, -1,
882 wtextW, sizeof(wtextW)/sizeof(wtextW[0]));
883 ok(ret > 0, "MultiByteToWideChar failed\n");
885 else
887 /* C locale */
888 const char *p;
889 for (p = text; *p != '\0'; p++)
890 wtextW[ret++] = (unsigned char)*p;
891 wtextW[ret++] = 0;
894 tempfh = fopen(tempfile, "rt");
895 ok(tempfh != NULL, "can't open tempfile\n");
897 for (i = 0; i < ret-1; i++)
899 ch = fgetwc(tempfh);
900 ok(ch == wtextW[i], "got %04hx, expected %04hx (cp%d[%d])\n", ch, wtextW[i], codepage, i);
902 ch = fgetwc(tempfh);
903 ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage);
904 fclose(tempfh);
906 tempfh = fopen(tempfile, "wb");
907 ok(tempfh != NULL, "can't open tempfile\n");
908 fwrite(wchar_text, 1, sizeof(wchar_text), tempfh);
909 fclose(tempfh);
911 tempfh = fopen(tempfile, "rb");
912 ok(tempfh != NULL, "can't open tempfile\n");
913 for (i = 0; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
915 ch = fgetwc(tempfh);
916 ok(ch == wchar_text[i], "got %04hx, expected %04x (cp%d[%d])\n", ch, wchar_text[i], codepage, i);
918 ch = fgetwc(tempfh);
919 ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage);
920 fclose(tempfh);
921 unlink(tempfile);
924 static void test_fgetwc_unicode(void)
926 char temppath[MAX_PATH], tempfile[MAX_PATH];
927 FILE *tempfh;
928 static const WCHAR wchar_text[] = { 0xfeff, 0xff1f, '!' };
929 char utf8_text[BUFSIZ];
930 int ret, i;
931 wint_t ch;
933 GetTempPathA(MAX_PATH, temppath);
934 GetTempFileNameA(temppath, "", 0, tempfile);
936 if (!p_fopen_s)
938 win_skip("fopen_s not available\n");
939 return;
942 tempfh = fopen(tempfile, "wb");
943 ok(tempfh != NULL, "can't open tempfile\n");
944 fwrite(wchar_text, 1, sizeof(wchar_text), tempfh);
945 fclose(tempfh);
947 tempfh = fopen(tempfile, "rt,ccs=unicode");
948 ok(tempfh != NULL, "can't open tempfile\n");
949 for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
951 ch = fgetwc(tempfh);
952 ok(ch == wchar_text[i],
953 "got %04hx, expected %04x (unicode[%d])\n", ch, wchar_text[i], i-1);
955 ch = fgetwc(tempfh);
956 ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch);
957 fclose(tempfh);
959 tempfh = fopen(tempfile, "wb");
960 ok(tempfh != NULL, "can't open tempfile\n");
961 ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, sizeof(wchar_text)/sizeof(wchar_text[0]),
962 utf8_text, sizeof(utf8_text), NULL, NULL);
963 ok(ret > 0, "utf-8 conversion failed\n");
964 fwrite(utf8_text, sizeof(char), ret, tempfh);
965 fclose(tempfh);
967 tempfh = fopen(tempfile, "rt, ccs=UTF-8");
968 ok(tempfh != NULL, "can't open tempfile\n");
969 for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
971 ch = fgetwc(tempfh);
972 ok(ch == wchar_text[i],
973 "got %04hx, expected %04x (utf8[%d])\n", ch, wchar_text[i], i-1);
975 ch = fgetwc(tempfh);
976 ok(ch == WEOF, "got %04hx, expected WEOF (utf8)\n", ch);
977 fclose(tempfh);
978 unlink(temppath);
981 static void test_fputwc(void)
983 char temppath[MAX_PATH];
984 char tempfile[MAX_PATH];
985 FILE *f;
986 char buf[1024];
987 int ret;
989 GetTempPathA(MAX_PATH, temppath);
990 GetTempFileNameA(temppath, "", 0, tempfile);
992 f = fopen(tempfile, "w");
993 ret = fputwc('a', f);
994 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
995 ret = fputwc('\n', f);
996 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
997 fclose(f);
999 f = fopen(tempfile, "rb");
1000 ret = fread(buf, 1, sizeof(buf), f);
1001 ok(ret == 3, "fread returned %d, expected 3\n", ret);
1002 ok(!memcmp(buf, "a\r\n", 3), "incorrect file data\n");
1003 fclose(f);
1005 if(p_fopen_s) {
1006 f = fopen(tempfile, "w,ccs=unicode");
1007 ret = fputwc('a', f);
1008 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
1009 ret = fputwc('\n', f);
1010 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
1011 fclose(f);
1013 f = fopen(tempfile, "rb");
1014 ret = fread(buf, 1, sizeof(buf), f);
1015 ok(ret == 8, "fread returned %d, expected 8\n", ret);
1016 ok(!memcmp(buf, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n");
1017 fclose(f);
1019 f = fopen(tempfile, "w,ccs=utf-8");
1020 ret = fputwc('a', f);
1021 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
1022 ret = fputwc('\n', f);
1023 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
1024 fclose(f);
1026 f = fopen(tempfile, "rb");
1027 ret = fread(buf, 1, sizeof(buf), f);
1028 ok(ret == 6, "fread returned %d, expected 6\n", ret);
1029 ok(!memcmp(buf, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n");
1030 fclose(f);
1031 }else {
1032 win_skip("fputwc tests on unicode files\n");
1035 _unlink(tempfile);
1038 static void test_ctrlz( void )
1040 char* tempf;
1041 FILE *tempfh;
1042 static const char mytext[]= "This is test_ctrlz";
1043 char buffer[256];
1044 int i, j;
1045 LONG l;
1047 tempf=_tempnam(".","wne");
1048 tempfh = fopen(tempf,"wb");
1049 fputs(mytext,tempfh);
1050 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
1051 fputc(j,tempfh);
1052 j = '\r';
1053 fputc(j,tempfh);
1054 j = '\n';
1055 fputc(j,tempfh);
1056 j = 'a';
1057 fputc(j,tempfh);
1058 fclose(tempfh);
1059 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1060 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1061 i=strlen(buffer);
1062 j=strlen(mytext);
1063 ok(i==j, "returned string length expected %d got %d\n", j, i);
1064 j+=4; /* ftell should indicate the true end of file */
1065 l=ftell(tempfh);
1066 ok(l==j, "ftell expected %d got %d\n", j, l);
1067 ok(feof(tempfh), "did not get EOF\n");
1068 fclose(tempfh);
1070 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
1071 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1072 i=strlen(buffer);
1073 j=strlen(mytext)+3; /* should get through newline */
1074 ok(i==j, "returned string length expected %d got %d\n", j, i);
1075 l=ftell(tempfh);
1076 ok(l==j, "ftell expected %d got %d\n", j, l);
1077 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1078 i=strlen(buffer);
1079 ok(i==1, "returned string length expected %d got %d\n", 1, i);
1080 ok(feof(tempfh), "did not get EOF\n");
1081 fclose(tempfh);
1082 unlink(tempf);
1083 free(tempf);
1086 static void test_file_put_get( void )
1088 char* tempf;
1089 FILE *tempfh;
1090 static const char mytext[]= "This is a test_file_put_get\n";
1091 static const char dostext[]= "This is a test_file_put_get\r\n";
1092 char btext[LLEN];
1093 WCHAR wtextW[LLEN+1];
1094 WCHAR *mytextW = NULL, *aptr, *wptr;
1095 BOOL diff_found = FALSE;
1096 unsigned int i;
1098 tempf=_tempnam(".","wne");
1099 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
1100 fputs(mytext,tempfh);
1101 fclose(tempfh);
1102 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
1103 fgets(btext,LLEN,tempfh);
1104 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
1105 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
1106 fclose(tempfh);
1107 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
1108 fputs(dostext,tempfh);
1109 fclose(tempfh);
1110 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1111 fgets(btext,LLEN,tempfh);
1112 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
1113 fclose(tempfh);
1114 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
1115 fgets(btext,LLEN,tempfh);
1116 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
1118 fclose(tempfh);
1119 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1120 fgetws(wtextW,LLEN,tempfh);
1121 mytextW = AtoW (mytext);
1122 aptr = mytextW;
1123 wptr = wtextW;
1125 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
1127 diff_found |= (*aptr != *wptr);
1129 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
1130 free(mytextW);
1131 fclose(tempfh);
1132 unlink(tempf);
1133 free(tempf);
1136 static void test_file_write_read( void )
1138 char* tempf;
1139 int tempfd;
1140 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
1141 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
1142 char btext[LLEN];
1143 int ret, i;
1145 tempf=_tempnam(".","wne");
1146 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
1147 _S_IREAD | _S_IWRITE);
1148 ok( tempfd != -1,
1149 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1150 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1151 "_write _O_BINARY bad return value\n");
1152 _close(tempfd);
1153 i = lstrlenA(mytext);
1154 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1155 ok(_read(tempfd,btext,i) == i,
1156 "_read _O_BINARY got bad length\n");
1157 ok( memcmp(dostext,btext,i) == 0,
1158 "problems with _O_BINARY _write / _read\n");
1159 _close(tempfd);
1160 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1161 ok(_read(tempfd,btext,i) == i-1,
1162 "_read _O_TEXT got bad length\n");
1163 ok( memcmp(mytext,btext,i-1) == 0,
1164 "problems with _O_BINARY _write / _O_TEXT _read\n");
1165 _close(tempfd);
1166 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
1167 _S_IREAD | _S_IWRITE);
1168 ok( tempfd != -1,
1169 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
1170 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
1171 "_write _O_TEXT bad return value\n");
1172 _close(tempfd);
1173 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1174 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1175 "_read _O_BINARY got bad length\n");
1176 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1177 "problems with _O_TEXT _write / _O_BINARY _read\n");
1178 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1179 _close(tempfd);
1180 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1181 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1182 "_read _O_TEXT got bad length\n");
1183 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1184 "problems with _O_TEXT _write / _read\n");
1185 _close(tempfd);
1187 memset(btext, 0, LLEN);
1188 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
1189 ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
1190 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
1191 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
1192 _close(tempfd);
1194 /* Test reading only \n or \r */
1195 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1196 _lseek(tempfd, -1, FILE_END);
1197 ret = _read(tempfd,btext,LLEN);
1198 ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
1199 _lseek(tempfd, -2, FILE_END);
1200 ret = _read(tempfd,btext,LLEN);
1201 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
1202 _lseek(tempfd, -2, FILE_END);
1203 ret = _read(tempfd,btext,1);
1204 ok(ret == 1 && *btext == '\n', "_read returned %d, buf: %d\n", ret, *btext);
1205 ret = read(tempfd,btext,1);
1206 ok(ret == 0, "_read returned %d, expected 0\n", ret);
1207 _lseek(tempfd, -3, FILE_END);
1208 ret = _read(tempfd,btext,1);
1209 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1210 ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
1211 _lseek(tempfd, -3, FILE_END);
1212 ret = _read(tempfd,btext,2);
1213 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1214 ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
1215 _lseek(tempfd, -3, FILE_END);
1216 ret = _read(tempfd,btext,3);
1217 ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1218 ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
1219 _close(tempfd);
1221 ret = unlink(tempf);
1222 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1223 free(tempf);
1225 tempf=_tempnam(".","wne");
1226 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, _S_IWRITE);
1227 ok( tempfd != -1,
1228 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1229 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1230 "_write _O_BINARY bad return value\n");
1231 _close(tempfd);
1232 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1233 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1234 "_read _O_BINARY got bad length\n");
1235 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1236 "problems with _O_BINARY _write / _read\n");
1237 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1238 _close(tempfd);
1239 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1240 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1241 "_read _O_TEXT got bad length\n");
1242 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1243 "problems with _O_BINARY _write / _O_TEXT _read\n");
1244 _close(tempfd);
1246 /* test _read with single bytes. CR should be skipped and LF pulled in */
1247 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1248 for (i=0; i<strlen(mytext); i++) /* */
1250 _read(tempfd,btext, 1);
1251 ok(btext[0] == mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
1253 while (_read(tempfd,btext, 1));
1254 _close(tempfd);
1256 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
1257 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1258 i = _read(tempfd,btext, strlen(mytext));
1259 ok(i == strlen(mytext)-1, "_read_i %d\n", i);
1260 _close(tempfd);
1262 /* test read/write in unicode mode */
1263 if(p_fopen_s)
1265 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE);
1266 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1267 ret = _write(tempfd, "a", 1);
1268 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1269 ret = _write(tempfd, "a\x00\n\x00\xff\xff", 6);
1270 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1271 _close(tempfd);
1273 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1274 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1275 ret = _read(tempfd, btext, sizeof(btext));
1276 ok(ret == 10, "_read returned %d, expected 10\n", ret);
1277 ok(!memcmp(btext, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1278 _close(tempfd);
1280 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1281 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1282 errno = 0xdeadbeef;
1283 ret = _read(tempfd, btext, 3);
1284 ok(ret == -1, "_read returned %d, expected -1\n", ret);
1285 ok(errno == 22, "errno = %d\n", errno);
1286 ret = _read(tempfd, btext, sizeof(btext));
1287 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1288 ok(!memcmp(btext, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1289 _close(tempfd);
1291 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_U8TEXT, _S_IWRITE);
1292 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1293 errno = 0xdeadbeef;
1294 ret = _write(tempfd, "a", 1);
1295 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1296 ok(errno == 22, "errno = %d\n", errno);
1297 ret = _write(tempfd, "a\x00\n\x00\x62\x00", 6);
1298 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1299 _close(tempfd);
1301 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1302 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1303 ret = _read(tempfd, btext, sizeof(btext));
1304 ok(ret == 7, "_read returned %d, expected 7\n", ret);
1305 ok(!memcmp(btext, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1306 _close(tempfd);
1308 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1309 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1310 ret = _read(tempfd, btext, sizeof(btext));
1311 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1312 ok(!memcmp(btext, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1314 /* when buffer is small read sometimes fails in native implementation */
1315 lseek(tempfd, 3 /* skip bom */, SEEK_SET);
1316 ret = _read(tempfd, btext, 4);
1317 todo_wine ok(ret == -1, "_read returned %d, expected -1\n", ret);
1319 lseek(tempfd, 6, SEEK_SET);
1320 ret = _read(tempfd, btext, 2);
1321 ok(ret == 2, "_read returned %d, expected 2\n", ret);
1322 ok(!memcmp(btext, "\x62\x00", 2), "btext is incorrect\n");
1323 _close(tempfd);
1325 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IWRITE);
1326 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1327 ret = _write(tempfd, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1328 ok(ret == 12, "_write returned %d, expected 9\n", ret);
1329 _close(tempfd);
1331 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1332 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1333 ret = _read(tempfd, btext, sizeof(btext));
1334 ok(ret == 12, "_read returned %d, expected 12\n", ret);
1335 ok(!memcmp(btext, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1337 /* test invalid utf8 sequence */
1338 lseek(tempfd, 5, SEEK_SET);
1339 ret = _read(tempfd, btext, sizeof(btext));
1340 todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret);
1341 /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1342 todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1343 ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1344 _close(tempfd);
1346 else
1348 win_skip("unicode mode tests on file\n");
1351 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
1352 ok( ret == 0,
1353 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
1354 ret = unlink(tempf);
1355 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1356 free(tempf);
1359 static void test_file_inherit_child(const char* fd_s)
1361 int fd = atoi(fd_s);
1362 char buffer[32];
1363 int ret;
1365 ret =write(fd, "Success", 8);
1366 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
1367 lseek(fd, 0, SEEK_SET);
1368 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
1369 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1372 static void test_file_inherit_child_no(const char* fd_s)
1374 int fd = atoi(fd_s);
1375 int ret;
1377 ret = write(fd, "Success", 8);
1378 ok( ret == -1 && errno == EBADF,
1379 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
1382 static void create_io_inherit_block( STARTUPINFOA *startup, unsigned int count, const HANDLE *handles )
1384 static BYTE block[1024];
1385 BYTE *wxflag_ptr;
1386 HANDLE *handle_ptr;
1387 unsigned int i;
1389 startup->lpReserved2 = block;
1390 startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
1391 wxflag_ptr = block + sizeof(unsigned);
1392 handle_ptr = (HANDLE *)(wxflag_ptr + count);
1394 *(unsigned*)block = count;
1395 for (i = 0; i < count; i++)
1397 wxflag_ptr[i] = 0x81;
1398 handle_ptr[i] = handles[i];
1402 static const char *read_file( HANDLE file )
1404 static char buffer[128];
1405 DWORD ret;
1406 SetFilePointer( file, 0, NULL, FILE_BEGIN );
1407 if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
1408 buffer[ret] = 0;
1409 return buffer;
1412 static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
1413 const char *descr )
1415 const char *data;
1416 HANDLE hErrorFile;
1417 SECURITY_ATTRIBUTES sa;
1418 PROCESS_INFORMATION proc;
1420 /* make file handle inheritable */
1421 sa.nLength = sizeof(sa);
1422 sa.lpSecurityDescriptor = NULL;
1423 sa.bInheritHandle = TRUE;
1425 hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1426 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1427 startup->dwFlags = STARTF_USESTDHANDLES;
1428 startup->hStdInput = GetStdHandle( STD_INPUT_HANDLE );
1429 startup->hStdOutput = hErrorFile;
1430 startup->hStdError = GetStdHandle( STD_ERROR_HANDLE );
1432 CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1433 CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1434 winetest_wait_child_process( proc.hProcess );
1436 data = read_file( hErrorFile );
1437 if (expect_stdout)
1438 ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1439 else
1440 ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1442 if (hstdout)
1444 data = read_file( hstdout );
1445 if (expect_stdout)
1446 ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1447 else
1448 ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1451 CloseHandle( hErrorFile );
1452 DeleteFileA( "fdopen.err" );
1455 static void test_file_inherit( const char* selfname )
1457 int fd;
1458 const char* arg_v[5];
1459 char buffer[16];
1460 char cmdline[MAX_PATH];
1461 STARTUPINFOA startup;
1462 SECURITY_ATTRIBUTES sa;
1463 HANDLE handles[3];
1465 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1466 ok(fd != -1, "Couldn't create test file\n");
1467 arg_v[0] = get_base_name(selfname);
1468 arg_v[1] = "tests/file.c";
1469 arg_v[2] = "inherit";
1470 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1471 arg_v[4] = 0;
1472 _spawnvp(_P_WAIT, selfname, arg_v);
1473 ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1474 lseek(fd, 0, SEEK_SET);
1475 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1476 close (fd);
1477 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1479 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1480 ok(fd != -1, "Couldn't create test file\n");
1481 arg_v[1] = "tests/file.c";
1482 arg_v[2] = "inherit_no";
1483 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1484 arg_v[4] = 0;
1485 _spawnvp(_P_WAIT, selfname, arg_v);
1486 ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1487 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1488 close (fd);
1489 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1491 /* make file handle inheritable */
1492 sa.nLength = sizeof(sa);
1493 sa.lpSecurityDescriptor = NULL;
1494 sa.bInheritHandle = TRUE;
1495 sprintf(cmdline, "%s file inherit 1", selfname);
1497 /* init an empty Reserved2, which should not be recognized as inherit-block */
1498 ZeroMemory(&startup, sizeof(startup));
1499 startup.cb = sizeof(startup);
1500 create_io_inherit_block( &startup, 0, NULL );
1501 test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1503 /* test with valid inheritblock */
1504 handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1505 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1506 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1507 handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1508 create_io_inherit_block( &startup, 3, handles );
1509 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1510 CloseHandle( handles[1] );
1511 DeleteFileA("fdopen.tst");
1513 /* test inherit block starting with unsigned zero */
1514 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1515 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1516 create_io_inherit_block( &startup, 3, handles );
1517 *(unsigned int *)startup.lpReserved2 = 0;
1518 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1519 CloseHandle( handles[1] );
1520 DeleteFileA("fdopen.tst");
1522 /* test inherit block with smaller size */
1523 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1524 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1525 create_io_inherit_block( &startup, 3, handles );
1526 startup.cbReserved2 -= 3;
1527 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1528 CloseHandle( handles[1] );
1529 DeleteFileA("fdopen.tst");
1531 /* test inherit block with even smaller size */
1532 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1533 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1534 create_io_inherit_block( &startup, 3, handles );
1535 startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1536 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1537 CloseHandle( handles[1] );
1538 DeleteFileA("fdopen.tst");
1540 /* test inherit block with larger size */
1541 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1542 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1543 create_io_inherit_block( &startup, 3, handles );
1544 startup.cbReserved2 += 7;
1545 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1546 CloseHandle( handles[1] );
1547 DeleteFileA("fdopen.tst");
1550 static void test_invalid_stdin_child( void )
1552 HANDLE handle;
1553 ioinfo *info;
1554 int ret;
1555 char c;
1557 errno = 0xdeadbeef;
1558 handle = (HANDLE)_get_osfhandle(STDIN_FILENO);
1559 ok(handle == (HANDLE)-2, "handle = %p\n", handle);
1560 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1562 info = &__pioinfo[STDIN_FILENO/MSVCRT_FD_BLOCK_SIZE][STDIN_FILENO%MSVCRT_FD_BLOCK_SIZE];
1563 ok(info->handle == (HANDLE)-2, "info->handle = %p\n", info->handle);
1564 ok(info->wxflag == 0xc1, "info->wxflag = %x\n", info->wxflag);
1566 ok(stdin->_file == -2, "stdin->_file = %d\n", stdin->_file);
1568 errno = 0xdeadbeef;
1569 ret = fread(&c, 1, 1, stdin);
1570 ok(!ret, "fread(stdin) returned %d\n", ret);
1571 ok(errno == EBADF, "errno = %d\n", errno);
1573 errno = 0xdeadbeef;
1574 ret = read(-2, &c, 1);
1575 ok(ret == -1, "read(-2) returned %d\n", ret);
1576 ok(errno == EBADF, "errno = %d\n", errno);
1578 errno = 0xdeadbeef;
1579 ret = read(STDIN_FILENO, &c, 1);
1580 ok(ret == -1, "read(STDIN_FILENO) returned %d\n", ret);
1581 ok(errno == EBADF, "errno = %d\n", errno);
1583 errno = 0xdeadbeef;
1584 ret = _flsbuf('a', stdin);
1585 ok(ret == EOF, "_flsbuf(stdin) returned %d\n", ret);
1586 ok(errno == EBADF, "errno = %d\n", errno);
1588 errno = 0xdeadbeef;
1589 ret = fwrite(&c, 1, 1, stdin);
1590 ok(!ret, "fwrite(stdin) returned %d\n", ret);
1591 ok(errno == EBADF, "errno = %d\n", errno);
1593 errno = 0xdeadbeef;
1594 ret = write(-2, &c, 1);
1595 ok(ret == -1, "write(-2) returned %d\n", ret);
1596 ok(errno == EBADF, "errno = %d\n", errno);
1598 errno = 0xdeadbeef;
1599 ret = write(STDIN_FILENO, &c, 1);
1600 ok(ret == -1, "write(STDIN_FILENO) returned %d\n", ret);
1601 ok(errno == EBADF, "errno = %d\n", errno);
1603 errno = 0xdeadbeef;
1604 ret = fclose(stdin);
1605 ok(ret == -1, "fclose(stdin) returned %d\n", ret);
1606 ok(errno == EBADF, "errno = %d\n", errno);
1608 errno = 0xdeadbeef;
1609 ret = close(-2);
1610 ok(ret == -1, "close(-2) returned %d\n", ret);
1611 ok(errno == EBADF, "errno = %d\n", errno);
1613 errno = 0xdeadbeef;
1614 ret = close(STDIN_FILENO);
1615 ok(ret==-1 || !ret, "close(STDIN_FILENO) returned %d\n", ret);
1616 ok((ret==-1 && errno==EBADF) || (!ret && errno==0xdeadbeef), "errno = %d\n", errno);
1619 static void test_invalid_stdin( const char* selfname )
1621 char cmdline[MAX_PATH];
1622 PROCESS_INFORMATION proc;
1623 SECURITY_ATTRIBUTES sa;
1624 STARTUPINFOA startup;
1625 HKEY key;
1626 LONG ret;
1628 if(!p_fopen_s) {
1629 /* Behaviour of the dll has changed in newer version */
1630 win_skip("skipping invalid stdin tests\n");
1631 return;
1634 ret = RegOpenCurrentUser(KEY_READ, &key);
1635 ok(!ret, "RegOpenCurrentUser failed: %x\n", ret);
1637 sa.nLength = sizeof(sa);
1638 sa.lpSecurityDescriptor = NULL;
1639 sa.bInheritHandle = TRUE;
1641 memset(&startup, 0, sizeof(startup));
1642 startup.cb = sizeof(startup);
1643 startup.dwFlags = STARTF_USESTDHANDLES;
1644 startup.hStdInput = key;
1645 startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
1646 startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);
1648 sprintf(cmdline, "%s file stdin", selfname);
1649 CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
1650 CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc);
1651 winetest_wait_child_process(proc.hProcess);
1653 ret = RegCloseKey(key);
1654 ok(!ret, "RegCloseKey failed: %x\n", ret);
1657 static void test_tmpnam( void )
1659 char name[MAX_PATH] = "abc";
1660 char *res;
1662 res = tmpnam(NULL);
1663 ok(res != NULL, "tmpnam returned NULL\n");
1664 ok(res[0] == '\\', "first character is not a backslash\n");
1665 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1666 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1668 res = tmpnam(name);
1669 ok(res != NULL, "tmpnam returned NULL\n");
1670 ok(res == name, "supplied buffer was not used\n");
1671 ok(res[0] == '\\', "first character is not a backslash\n");
1672 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1673 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1676 static void test_chsize( void )
1678 int fd;
1679 LONG cur, pos, count;
1680 char temptext[] = "012345678";
1681 char *tempfile = _tempnam( ".", "tst" );
1683 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1685 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1686 ok( fd > 0, "Couldn't open test file\n" );
1688 count = _write( fd, temptext, sizeof(temptext) );
1689 ok( count > 0, "Couldn't write to test file\n" );
1691 /* get current file pointer */
1692 cur = _lseek( fd, 0, SEEK_CUR );
1694 /* make the file smaller */
1695 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1697 pos = _lseek( fd, 0, SEEK_CUR );
1698 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1699 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1701 /* enlarge the file */
1702 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
1704 pos = _lseek( fd, 0, SEEK_CUR );
1705 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1706 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1708 _close( fd );
1709 _unlink( tempfile );
1710 free( tempfile );
1713 static void test_fopen_fclose_fcloseall( void )
1715 char fname1[] = "empty1";
1716 char fname2[] = "empty2";
1717 char fname3[] = "empty3";
1718 FILE *stream1, *stream2, *stream3, *stream4;
1719 int ret, numclosed;
1721 /* testing fopen() */
1722 stream1 = fopen(fname1, "w+");
1723 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1724 stream2 = fopen(fname2, "w ");
1725 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1726 _unlink(fname3);
1727 stream3 = fopen(fname3, "r");
1728 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1729 stream3 = fopen(fname3, "w+");
1730 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1731 errno = 0xfaceabad;
1732 stream4 = fopen("", "w+");
1733 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1734 "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1735 errno = 0xfaceabad;
1736 stream4 = fopen(NULL, "w+");
1737 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1738 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1740 /* testing fclose() */
1741 ret = fclose(stream2);
1742 ok(ret == 0, "The file '%s' was not closed\n", fname2);
1743 ret = fclose(stream3);
1744 ok(ret == 0, "The file '%s' was not closed\n", fname3);
1745 errno = 0xdeadbeef;
1746 ret = fclose(stream2);
1747 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1748 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1749 ret = fclose(stream3);
1750 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1751 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1753 /* testing fcloseall() */
1754 numclosed = _fcloseall();
1755 /* fname1 should be closed here */
1756 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1757 numclosed = _fcloseall();
1758 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1760 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1761 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1762 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1765 static void test_fopen_s( void )
1767 const char name[] = "empty1";
1768 char buff[16];
1769 unsigned char *ubuff = (unsigned char*)buff;
1770 FILE *file, *file2;
1771 int ret;
1772 int len;
1774 if (!p_fopen_s)
1776 win_skip("Skipping fopen_s test\n");
1777 return;
1779 /* testing fopen_s */
1780 ret = p_fopen_s(&file, name, "w");
1781 ok(ret == 0, "fopen_s failed with %d\n", ret);
1782 ok(file != 0, "fopen_s failed to return value\n");
1783 fwrite(name, sizeof(name), 1, file);
1785 ret = fclose(file);
1786 ok(ret != EOF, "File failed to close\n");
1788 file = fopen(name, "r");
1789 ok(file != 0, "fopen failed\n");
1790 len = fread(buff, 1, sizeof(name), file);
1791 ok(len == sizeof(name), "File length is %d\n", len);
1792 buff[sizeof(name)] = '\0';
1793 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1795 ret = fclose(file);
1796 ok(ret != EOF, "File failed to close\n");
1798 ret = p_fopen_s(&file, name, "w, ccs=UNIcode");
1799 ok(ret == 0, "fopen_s failed with %d\n", ret);
1800 ret = fwrite("a", 1, 2, file);
1801 ok(ret == 2, "fwrite returned %d\n", ret);
1802 fclose(file);
1804 ret = p_fopen_s(&file, name, "r");
1805 ok(ret == 0, "fopen_s failed with %d\n", ret);
1806 len = fread(buff, 1, 2, file);
1807 ok(len == 2, "len = %d\n", len);
1808 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1809 ubuff[0], ubuff[1]);
1810 fclose(file);
1812 ret = p_fopen_s(&file, name, "r,ccs=unicode");
1813 ok(ret == 0, "fopen_s failed with %d\n", ret);
1814 len = fread(buff, 1, 2, file);
1815 ok(len == 2, "len = %d\n", len);
1816 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1817 ubuff[0], ubuff[1]);
1818 fclose(file);
1820 ret = p_fopen_s(&file, name, "r,ccs=utf-16le");
1821 ok(ret == 0, "fopen_s failed with %d\n", ret);
1822 len = fread(buff, 1, 2, file);
1823 ok(len == 2, "len = %d\n", len);
1824 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1825 ubuff[0], ubuff[1]);
1826 fclose(file);
1828 ret = p_fopen_s(&file, name, "r,ccs=utf-8");
1829 ok(ret == 0, "fopen_s failed with %d\n", ret);
1830 len = fread(buff, 1, 2, file);
1831 ok(len == 2, "len = %d\n", len);
1832 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1833 ubuff[0], ubuff[1]);
1834 fclose(file);
1836 ret = p_fopen_s(&file, name, "w,ccs=utf-16le");
1837 ok(ret == 0, "fopen_s failed with %d\n", ret);
1838 fclose(file);
1840 ret = p_fopen_s(&file, name, "r");
1841 ok(ret == 0, "fopen_s failed with %d\n", ret);
1842 len = fread(buff, 1, 3, file);
1843 ok(len == 2, "len = %d\n", len);
1844 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1845 ubuff[0], ubuff[1]);
1846 fclose(file);
1848 ret = p_fopen_s(&file, name, "w,ccs=utf-8");
1849 ok(ret == 0, "fopen_s failed with %d\n", ret);
1850 fclose(file);
1852 ret = p_fopen_s(&file, name, "r");
1853 ok(ret == 0, "fopen_s failed with %d\n", ret);
1854 len = fread(buff, 1, 4, file);
1855 ok(len == 3, "len = %d\n", len);
1856 ok(ubuff[0]==0xef && ubuff[1]==0xbb && ubuff[2]==0xbf,
1857 "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1858 ubuff[0], ubuff[1], ubuff[2]);
1859 fclose(file);
1861 /* test initial FILE values */
1862 memset(file, 0xfe, sizeof(*file));
1863 file->_flag = 0;
1864 ret = p_fopen_s(&file2, name, "r");
1865 ok(!ret, "fopen_s failed with %d\n", ret);
1866 ok(file == file2, "file != file2 %p %p\n", file, file2);
1867 ok(!file->_ptr, "file->_ptr != NULL\n");
1868 ok(!file->_cnt, "file->_cnt != 0\n");
1869 ok(!file->_base, "file->_base != NULL\n");
1870 ok(file->_flag == 1, "file->_flag = %x\n", file->_flag);
1871 ok(file->_file, "file->_file == 0\n");
1872 ok(file->_charbuf == 0xfefefefe, "file->_charbuf = %x\n", file->_charbuf);
1873 ok(file->_bufsiz == 0xfefefefe, "file->_bufsiz = %x\n", file->_bufsiz);
1874 ok(!file->_tmpfname, "file->_tmpfname != NULL\n");
1875 fclose(file2);
1877 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1880 static void test__wfopen_s( void )
1882 const char name[] = "empty1";
1883 const WCHAR wname[] = {
1884 'e','m','p','t','y','1',0
1886 const WCHAR wmode[] = {
1887 'w',0
1889 char buff[16];
1890 FILE *file;
1891 int ret;
1892 int len;
1894 if (!p__wfopen_s)
1896 win_skip("Skipping _wfopen_s test\n");
1897 return;
1899 /* testing _wfopen_s */
1900 ret = p__wfopen_s(&file, wname, wmode);
1901 ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1902 ok(file != 0, "_wfopen_s failed to return value\n");
1903 fwrite(name, sizeof(name), 1, file);
1905 ret = fclose(file);
1906 ok(ret != EOF, "File failed to close\n");
1908 file = fopen(name, "r");
1909 ok(file != 0, "fopen failed\n");
1910 len = fread(buff, 1, sizeof(name), file);
1911 ok(len == sizeof(name), "File length is %d\n", len);
1912 buff[sizeof(name)] = '\0';
1913 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1915 ret = fclose(file);
1916 ok(ret != EOF, "File failed to close\n");
1918 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1921 static void test_setmode(void)
1923 const char name[] = "empty1";
1924 int fd, ret;
1926 if(!p_fopen_s) {
1927 win_skip("unicode file modes are not available, skipping setmode tests\n");
1928 return;
1931 errno = 0xdeadbeef;
1932 ret = _setmode(-2, 0);
1933 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1934 ok(errno == EINVAL, "errno = %d\n", errno);
1936 errno = 0xdeadbeef;
1937 ret = _setmode(-2, _O_TEXT);
1938 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1939 ok(errno == EBADF, "errno = %d\n", errno);
1941 fd = _open(name, _O_CREAT|_O_WRONLY, _S_IWRITE);
1942 ok(fd != -1, "failed to open file\n");
1944 errno = 0xdeadbeef;
1945 ret = _setmode(fd, 0xffffffff);
1946 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1947 ok(errno == EINVAL, "errno = %d\n", errno);
1949 errno = 0xdeadbeef;
1950 ret = _setmode(fd, 0);
1951 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1952 ok(errno == EINVAL, "errno = %d\n", errno);
1954 errno = 0xdeadbeef;
1955 ret = _setmode(fd, _O_BINARY|_O_TEXT);
1956 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1957 ok(errno == EINVAL, "errno = %d\n", errno);
1959 errno = 0xdeadbeef;
1960 ret = _setmode(fd, _O_WTEXT|_O_U16TEXT);
1961 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1962 ok(errno == EINVAL, "errno = %d\n", errno);
1964 ret = _setmode(fd, _O_BINARY);
1965 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1967 ret = _setmode(fd, _O_WTEXT);
1968 ok(ret == _O_BINARY, "_setmode returned %x, expected _O_BINARY\n", ret);
1970 ret = _setmode(fd, _O_TEXT);
1971 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1973 ret = _setmode(fd, _O_U16TEXT);
1974 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1976 ret = _setmode(fd, _O_U8TEXT);
1977 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1979 ret = _setmode(fd, _O_TEXT);
1980 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1982 _close(fd);
1983 _unlink(name);
1986 static void test_get_osfhandle(void)
1988 int fd;
1989 char fname[] = "t_get_osfhanle";
1990 DWORD bytes_written;
1991 HANDLE handle;
1993 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1994 handle = (HANDLE)_get_osfhandle(fd);
1995 WriteFile(handle, "bar", 3, &bytes_written, NULL);
1996 _close(fd);
1997 fd = _open(fname, _O_RDONLY, 0);
1998 ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
2000 _close(fd);
2001 _unlink(fname);
2003 errno = 0xdeadbeef;
2004 handle = (HANDLE)_get_osfhandle(fd);
2005 ok(handle == INVALID_HANDLE_VALUE, "_get_osfhandle returned %p\n", handle);
2006 ok(errno == EBADF, "errno = %d\n", errno);
2009 static void test_setmaxstdio(void)
2011 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
2012 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
2015 static void test_stat(void)
2017 int fd;
2018 int pipes[2];
2019 int ret;
2020 struct stat buf;
2022 /* Tests for a file */
2023 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
2024 if (fd >= 0)
2026 ret = fstat(fd, &buf);
2027 ok(!ret, "fstat failed: errno=%d\n", errno);
2028 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
2029 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
2030 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
2031 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
2032 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2033 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
2035 ret = stat("stat.tst", &buf);
2036 ok(!ret, "stat failed: errno=%d\n", errno);
2037 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
2038 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
2039 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
2040 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2041 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
2043 errno = 0xdeadbeef;
2044 ret = stat("stat.tst\\", &buf);
2045 ok(ret == -1, "stat returned %d\n", ret);
2046 ok(errno == ENOENT, "errno = %d\n", errno);
2048 close(fd);
2049 remove("stat.tst");
2051 else
2052 skip("open failed with errno %d\n", errno);
2054 /* Tests for a char device */
2055 if (_dup2(0, 10) == 0)
2057 ret = fstat(10, &buf);
2058 ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
2059 if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
2061 ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
2062 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
2063 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
2064 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2066 else
2067 skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
2068 close(10);
2070 else
2071 skip("_dup2 failed with errno %d\n", errno);
2073 /* Tests for pipes */
2074 if (_pipe(pipes, 1024, O_BINARY) == 0)
2076 ret = fstat(pipes[0], &buf);
2077 ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
2078 ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
2079 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
2080 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
2081 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2082 close(pipes[0]);
2083 close(pipes[1]);
2085 else
2086 skip("pipe failed with errno %d\n", errno);
2088 /* Tests for directory */
2089 if(mkdir("stat.tst") == 0)
2091 ret = stat("stat.tst ", &buf);
2092 ok(!ret, "stat(directory) failed: errno=%d\n", errno);
2093 ok((buf.st_mode & _S_IFMT) == _S_IFDIR, "bad format = %06o\n", buf.st_mode);
2094 ok((buf.st_mode & 0777) == 0777, "bad st_mode = %06o\n", buf.st_mode);
2095 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
2096 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2098 errno = 0xdeadbeef;
2099 ret = stat("stat.tst\\ ", &buf);
2100 ok(ret == -1, "stat returned %d\n", ret);
2101 ok(errno == ENOENT, "errno = %d\n", errno);
2102 rmdir( "stat.tst" );
2104 else
2105 skip("mkdir failed with errno %d\n", errno);
2107 errno = 0xdeadbeef;
2108 ret = stat("c:", &buf);
2109 ok(ret == -1, "stat returned %d\n", ret);
2110 ok(errno == ENOENT, "errno = %d\n", errno);
2112 ret = stat("c:/", &buf);
2113 ok(!ret, "stat returned %d\n", ret);
2114 ok(buf.st_dev == 2, "st_dev = %d\n", buf.st_dev);
2115 ok(buf.st_rdev == 2, "st_rdev = %d\n", buf.st_rdev);
2118 static const char* pipe_string="Hello world";
2120 /* How many messages to transfer over the pipe */
2121 #define N_TEST_MESSAGES 3
2123 static void test_pipes_child(int argc, char** args)
2125 int fd;
2126 int nwritten;
2127 int i;
2129 if (argc < 5)
2131 ok(0, "not enough parameters: %d\n", argc);
2132 return;
2135 fd=atoi(args[3]);
2136 i=close(fd);
2137 ok(!i, "unable to close %d: %d\n", fd, errno);
2139 fd=atoi(args[4]);
2141 for (i=0; i<N_TEST_MESSAGES; i++) {
2142 nwritten=write(fd, pipe_string, strlen(pipe_string));
2143 ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
2144 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
2145 if (i < N_TEST_MESSAGES-1)
2146 Sleep(100);
2149 i=close(fd);
2150 ok(!i, "unable to close %d: %d\n", fd, errno);
2153 static void test_pipes(const char* selfname)
2155 int pipes[2];
2156 char str_fdr[12], str_fdw[12];
2157 FILE* file;
2158 const char* arg_v[6];
2159 char buf[4096];
2160 char expected[4096];
2161 int r;
2162 int i;
2164 /* Test reading from a pipe with read() */
2165 if (_pipe(pipes, 1024, O_BINARY) < 0)
2167 ok(0, "pipe failed with errno %d\n", errno);
2168 return;
2171 arg_v[0] = get_base_name(selfname);
2172 arg_v[1] = "tests/file.c";
2173 arg_v[2] = "pipes";
2174 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
2175 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
2176 arg_v[5] = NULL;
2177 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
2178 i=close(pipes[1]);
2179 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
2181 for (i=0; i<N_TEST_MESSAGES; i++) {
2182 r=read(pipes[0], buf, sizeof(buf)-1);
2183 ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
2184 if (r > 0)
2185 buf[r]='\0';
2186 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
2189 r=read(pipes[0], buf, sizeof(buf)-1);
2190 ok(r == 0, "expected to read 0 bytes, got %d\n", r);
2191 i=close(pipes[0]);
2192 ok(!i, "unable to close %d: %d\n", pipes[0], errno);
2194 /* Test reading from a pipe with fread() */
2195 if (_pipe(pipes, 1024, O_BINARY) < 0)
2197 ok(0, "pipe failed with errno %d\n", errno);
2198 return;
2201 arg_v[1] = "tests/file.c";
2202 arg_v[2] = "pipes";
2203 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
2204 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
2205 arg_v[5] = NULL;
2206 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
2207 i=close(pipes[1]);
2208 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
2209 file=fdopen(pipes[0], "r");
2211 /* In blocking mode, fread will keep calling read() until it gets
2212 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
2213 * in cooked mode instead of a pipe, it would also stop on EOL.)
2215 expected[0] = 0;
2216 for (i=0; i<N_TEST_MESSAGES; i++)
2217 strcat(expected, pipe_string);
2218 r=fread(buf, 1, sizeof(buf)-1, file);
2219 ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
2220 if (r > 0)
2221 buf[r]='\0';
2222 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
2224 /* Let child close the file before we read, so we can sense EOF reliably */
2225 Sleep(100);
2226 r=fread(buf, 1, sizeof(buf)-1, file);
2227 ok(r == 0, "fread() returned %d instead of 0\n", r);
2228 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
2229 ok(feof(file), "feof() is false!\n");
2231 i=fclose(file);
2232 ok(!i, "unable to close the pipe: %d\n", errno);
2234 /* test \r handling when it's the last character read */
2235 if (_pipe(pipes, 1024, O_BINARY) < 0)
2237 ok(0, "pipe failed with errno %d\n", errno);
2238 return;
2240 r = write(pipes[1], "\r\n\rab\r\n", 7);
2241 ok(r == 7, "write returned %d, errno = %d\n", r, errno);
2242 setmode(pipes[0], O_TEXT);
2243 r = read(pipes[0], buf, 1);
2244 ok(r == 1, "read returned %d, expected 1\n", r);
2245 ok(buf[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf[0]);
2246 r = read(pipes[0], buf, 1);
2247 ok(r == 1, "read returned %d, expected 1\n", r);
2248 ok(buf[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf[0]);
2249 r = read(pipes[0], buf, 1);
2250 ok(r == 1, "read returned %d, expected 1\n", r);
2251 ok(buf[0] == 'a', "buf[0] = %x, expected 'a'\n", buf[0]);
2252 r = read(pipes[0], buf, 2);
2253 ok(r == 2, "read returned %d, expected 1\n", r);
2254 ok(buf[0] == 'b', "buf[0] = %x, expected 'b'\n", buf[0]);
2255 ok(buf[1] == '\n', "buf[1] = %x, expected '\\n'\n", buf[1]);
2257 if (p_fopen_s)
2259 /* test utf16 read with insufficient data */
2260 r = write(pipes[1], "a\0b", 3);
2261 ok(r == 3, "write returned %d, errno = %d\n", r, errno);
2262 buf[2] = 'z';
2263 buf[3] = 'z';
2264 setmode(pipes[0], _O_WTEXT);
2265 r = read(pipes[0], buf, 4);
2266 ok(r == 2, "read returned %d, expected 2\n", r);
2267 ok(!memcmp(buf, "a\0bz", 4), "read returned incorrect data\n");
2268 r = write(pipes[1], "\0", 1);
2269 ok(r == 1, "write returned %d, errno = %d\n", r, errno);
2270 buf[0] = 'z';
2271 buf[1] = 'z';
2272 r = read(pipes[0], buf, 2);
2273 ok(r == 0, "read returned %d, expected 0\n", r);
2274 ok(!memcmp(buf, "\0z", 2), "read returned incorrect data\n");
2276 else
2278 win_skip("unicode mode tests on pipe\n");
2281 close(pipes[1]);
2282 close(pipes[0]);
2285 static void test_unlink(void)
2287 FILE* file;
2288 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
2289 file = fopen("test_unlink\\empty", "w");
2290 ok(file != NULL, "unable to create test file\n");
2291 if(file)
2292 fclose(file);
2293 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
2294 unlink("test_unlink\\empty");
2295 rmdir("test_unlink");
2298 static void test_dup2(void)
2300 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
2303 static void test_stdin(void)
2305 HANDLE stdinh = GetStdHandle(STD_INPUT_HANDLE);
2306 int stdin_dup, fd;
2307 HANDLE h;
2308 DWORD r;
2310 stdin_dup = _dup(STDIN_FILENO);
2311 ok(stdin_dup != -1, "_dup(STDIN_FILENO) failed\n");
2313 ok(stdinh == (HANDLE)_get_osfhandle(STDIN_FILENO),
2314 "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n");
2316 r = SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE);
2317 ok(r == TRUE, "SetStdHandle returned %x, expected TRUE\n", r);
2318 h = GetStdHandle(STD_INPUT_HANDLE);
2319 ok(h == INVALID_HANDLE_VALUE, "h = %p\n", h);
2321 close(STDIN_FILENO);
2322 h = GetStdHandle(STD_INPUT_HANDLE);
2323 ok(h == NULL, "h != NULL\n");
2325 fd = open("stdin.tst", O_WRONLY | O_CREAT, _S_IREAD |_S_IWRITE);
2326 ok(fd != -1, "open failed\n");
2327 ok(fd == STDIN_FILENO, "fd = %d, expected STDIN_FILENO\n", fd);
2328 h = GetStdHandle(STD_INPUT_HANDLE);
2329 ok(h != NULL, "h == NULL\n");
2330 close(fd);
2331 unlink("stdin.tst");
2333 r = _dup2(stdin_dup, STDIN_FILENO);
2334 ok(r != -1, "_dup2 failed\n");
2335 h = GetStdHandle(STD_INPUT_HANDLE);
2336 ok(h != NULL, "h == NULL\n");
2339 static void test_mktemp(void)
2341 char buf[16];
2343 strcpy(buf, "a");
2344 ok(!_mktemp(buf), "_mktemp(\"a\") != NULL\n");
2346 strcpy(buf, "testXXXXX");
2347 ok(!_mktemp(buf), "_mktemp(\"testXXXXX\") != NULL\n");
2349 strcpy(buf, "testXXXXXX");
2350 ok(_mktemp(buf) != NULL, "_mktemp(\"testXXXXXX\") == NULL\n");
2352 strcpy(buf, "testXXXXXXa");
2353 ok(!_mktemp(buf), "_mktemp(\"testXXXXXXa\") != NULL\n");
2355 strcpy(buf, "**XXXXXX");
2356 ok(_mktemp(buf) != NULL, "_mktemp(\"**XXXXXX\") == NULL\n");
2359 static void test__open_osfhandle(void)
2361 ioinfo *info;
2362 HANDLE h, tmp;
2363 int fd;
2365 errno = 0xdeadbeef;
2366 fd = _open_osfhandle((intptr_t)INVALID_HANDLE_VALUE, 0);
2367 ok(fd == -1, "_open_osfhandle returned %d\n", fd);
2368 ok(errno == EBADF, "errno = %d\n", errno);
2370 h = CreateFileA("open_osfhandle.tst", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2371 fd = _open_osfhandle((intptr_t)h, 0);
2372 ok(fd > 0, "_open_osfhandle returned %d (%d)\n", fd, errno);
2373 info = &__pioinfo[fd/MSVCRT_FD_BLOCK_SIZE][fd%MSVCRT_FD_BLOCK_SIZE];
2374 ok(info->handle == h, "info->handle = %p, expected %p\n", info->handle, h);
2375 ok(info->wxflag == 1, "info->wxflag = %x, expected 1\n", info->wxflag);
2376 close(fd);
2377 ok(info->handle == INVALID_HANDLE_VALUE, "info->handle = %p, expected INVALID_HANDLE_VALUE\n", info->handle);
2378 ok(info->wxflag == 0, "info->wxflag = %x, expected 0\n", info->wxflag);
2379 DeleteFileA("open_osfhandle.tst");
2381 errno = 0xdeadbeef;
2382 fd = _open_osfhandle((intptr_t)h, 0);
2383 ok(fd == -1, "_open_osfhandle returned %d\n", fd);
2384 ok(errno == EBADF, "errno = %d\n", errno);
2386 ok(CreatePipe(&h, &tmp, NULL, 0), "CreatePipe failed\n");
2387 fd = _open_osfhandle((intptr_t)h, 0);
2388 ok(fd > 0, "_open_osfhandle returned %d (%d)\n", fd, errno);
2389 info = &__pioinfo[fd/MSVCRT_FD_BLOCK_SIZE][fd%MSVCRT_FD_BLOCK_SIZE];
2390 ok(info->handle == h, "info->handle = %p, expected %p\n", info->handle, h);
2391 ok(info->wxflag == 9, "info->wxflag = %x, expected 9\n", info->wxflag);
2392 close(fd);
2393 CloseHandle(tmp);
2396 static void test_write_flush_size(FILE *file, int bufsize)
2398 char *inbuffer;
2399 char *outbuffer;
2400 int size, fd;
2401 fpos_t pos, pos2;
2403 fd = fileno(file);
2404 inbuffer = calloc(1, bufsize + 1);
2405 outbuffer = calloc(1, bufsize + 1);
2406 _snprintf(outbuffer, bufsize + 1, "0,1,2,3,4,5,6,7,8,9");
2408 for (size = bufsize + 1; size >= bufsize - 1; size--) {
2409 rewind(file);
2410 ok(file->_cnt == 0, "_cnt should be 0 after rewind, but is %d\n", file->_cnt);
2411 fwrite(outbuffer, 1, size, file);
2412 /* lseek() below intentionally redirects the write in fflush() to detect
2413 * if fwrite() has already flushed the whole buffer or not.
2415 lseek(fd, 1, SEEK_SET);
2416 fflush(file);
2417 ok(file->_cnt == 0, "_cnt should be 0 after fflush, but is %d\n", file->_cnt);
2418 fseek(file, 0, SEEK_SET);
2419 ok(fread(inbuffer, 1, bufsize, file) == bufsize, "read failed\n");
2420 if (size == bufsize)
2421 ok(memcmp(outbuffer, inbuffer, bufsize) == 0, "missing flush by %d byte write\n", size);
2422 else
2423 ok(memcmp(outbuffer, inbuffer, bufsize) != 0, "unexpected flush by %d byte write\n", size);
2425 rewind(file);
2426 fwrite(outbuffer, 1, bufsize / 2, file);
2427 fwrite(outbuffer + bufsize / 2, 1, bufsize / 2, file);
2428 lseek(fd, 1, SEEK_SET);
2429 fflush(file);
2430 fseek(file, 0, SEEK_SET);
2431 ok(fread(inbuffer, 1, bufsize, file) == bufsize, "read failed\n");
2432 ok(memcmp(outbuffer, inbuffer, bufsize) != 0, "unexpected flush by %d/2 byte double write\n", bufsize);
2434 ok(!fseek(file, -1, SEEK_END), "fseek failed\n");
2435 ok(!fgetpos(file, &pos), "fgetpos failed\n");
2436 ok(fread(inbuffer, 1, 1, file) == 1, "fread failed\n");
2437 ok(file->_flag & _IOREAD, "file->_flag = %x\n", file->_flag);
2438 ok(!file->_cnt, "file->_cnt = %d\n", file->_cnt);
2439 ok(file->_ptr != file->_base, "file->_ptr == file->_base\n");
2440 ok(fwrite(outbuffer, 1, bufsize, file), "fwrite failed\n");
2441 ok(file->_flag & _IOREAD, "file->_flag = %x\n", file->_flag);
2442 ok(!file->_cnt, "file->_cnt = %d\n", file->_cnt);
2443 ok(file->_ptr == file->_base, "file->_ptr == file->_base\n");
2444 ok(!fgetpos(file, &pos2), "fgetpos failed\n");
2445 ok(pos+bufsize+1 == pos2, "pos = %d (%d)\n", (int)pos, (int)pos2);
2446 free(inbuffer);
2447 free(outbuffer);
2450 static void test_write_flush(void)
2452 char iobuf[1024];
2453 char *tempf;
2454 FILE *file;
2456 tempf = _tempnam(".","wne");
2457 file = fopen(tempf, "wb+");
2458 ok(file != NULL, "unable to create test file\n");
2459 iobuf[0] = 0;
2460 ok(file->_bufsiz == 4096, "incorrect default buffer size: %d\n", file->_bufsiz);
2461 test_write_flush_size(file, file->_bufsiz);
2462 setvbuf(file, iobuf, _IOFBF, sizeof(iobuf));
2463 test_write_flush_size(file, sizeof(iobuf));
2464 fclose(file);
2465 unlink(tempf);
2466 free(tempf);
2469 static void test_close(void)
2471 ioinfo *stdout_info, stdout_copy, *stderr_info, stderr_copy;
2472 int fd1, fd2, ret1, ret2, ret3, ret4;
2473 DWORD flags;
2474 HANDLE h;
2476 /* test close on fds that use the same handle */
2477 h = CreateFileA("fdopen.tst", GENERIC_READ|GENERIC_WRITE,
2478 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
2479 ok(h != INVALID_HANDLE_VALUE, "error opening fdopen.tst file\n");
2481 fd1 = _open_osfhandle((intptr_t)h, 0);
2482 ok(fd1 != -1, "_open_osfhandle failed (%d)\n", errno);
2483 fd2 = _open_osfhandle((intptr_t)h, 0);
2484 ok(fd2 != -1, "_open_osfhandle failed (%d)\n", errno);
2485 ok(fd1 != fd2, "fd1 == fd2\n");
2487 ok((HANDLE)_get_osfhandle(fd1) == h, "handles mismatch (%p != %p)\n",
2488 (HANDLE)_get_osfhandle(fd1), h);
2489 ok((HANDLE)_get_osfhandle(fd2) == h, "handles mismatch (%p != %p)\n",
2490 (HANDLE)_get_osfhandle(fd2), h);
2491 ret1 = close(fd1);
2492 ok(!ret1, "close(fd1) failed (%d)\n", errno);
2493 ok(!GetHandleInformation(h, &flags), "GetHandleInformation succeeded\n");
2494 ok(close(fd2), "close(fd2) succeeded\n");
2496 /* test close on already closed fd */
2497 errno = 0xdeadbeef;
2498 ret1 = close(fd1);
2499 ok(ret1 == -1, "close(fd1) succeeded\n");
2500 ok(errno == 9, "errno = %d\n", errno);
2502 /* test close on stdout and stderr that use the same handle */
2503 h = CreateFileA("fdopen.tst", GENERIC_READ|GENERIC_WRITE,
2504 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
2505 ok(h != INVALID_HANDLE_VALUE, "error opening fdopen.tst file\n");
2507 /* tests output will not be visible from now on */
2508 stdout_info = &__pioinfo[STDOUT_FILENO/MSVCRT_FD_BLOCK_SIZE][STDOUT_FILENO%MSVCRT_FD_BLOCK_SIZE];
2509 stderr_info = &__pioinfo[STDERR_FILENO/MSVCRT_FD_BLOCK_SIZE][STDERR_FILENO%MSVCRT_FD_BLOCK_SIZE];
2510 stdout_copy = *stdout_info;
2511 stderr_copy = *stderr_info;
2512 stdout_info->handle = h;
2513 stderr_info->handle = h;
2515 ret1 = close(STDOUT_FILENO);
2516 ret2 = GetHandleInformation(h, &flags);
2517 ret3 = close(STDERR_FILENO);
2518 ret4 = GetHandleInformation(h, &flags);
2520 *stdout_info = stdout_copy;
2521 *stderr_info = stderr_copy;
2522 SetStdHandle(STD_OUTPUT_HANDLE, stdout_info->handle);
2523 SetStdHandle(STD_ERROR_HANDLE, stderr_info->handle);
2524 /* stdout and stderr restored */
2526 ok(!ret1, "close(STDOUT_FILENO) failed\n");
2527 ok(ret2, "GetHandleInformation failed\n");
2528 ok(!ret3, "close(STDERR_FILENO) failed\n");
2529 ok(!ret4, "GetHandleInformation succeeded\n");
2531 DeleteFileA( "fdopen.tst" );
2534 static void test__creat(void)
2536 int fd, pos, count, readonly, old_fmode = 0, have_fmode;
2537 char buf[6], testdata[4] = {'a', '\n', 'b', '\n'};
2539 have_fmode = p__get_fmode && p__set_fmode && !p__get_fmode(&old_fmode);
2540 if (!have_fmode)
2541 win_skip("_fmode can't be set, skipping mode tests\n");
2543 if (have_fmode)
2544 p__set_fmode(_O_TEXT);
2545 fd = _creat("_creat.tst", 0);
2546 ok(fd > 0, "_creat failed\n");
2547 _write(fd, testdata, 4);
2548 if (have_fmode) {
2549 pos = _tell(fd);
2550 ok(pos == 6, "expected pos 6 (text mode), got %d\n", pos);
2552 ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n");
2553 count = _read(fd, buf, 6);
2554 ok(count == 4, "_read returned %d, expected 4\n", count);
2555 count = count > 0 ? count > 4 ? 4 : count : 0;
2556 ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n");
2557 _close(fd);
2558 readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY;
2559 ok(readonly, "expected read-only file\n");
2560 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL);
2561 DeleteFileA("_creat.tst");
2563 if (have_fmode)
2564 p__set_fmode(_O_BINARY);
2565 fd = _creat("_creat.tst", _S_IREAD | _S_IWRITE);
2566 ok(fd > 0, "_creat failed\n");
2567 _write(fd, testdata, 4);
2568 if (have_fmode) {
2569 pos = _tell(fd);
2570 ok(pos == 4, "expected pos 4 (binary mode), got %d\n", pos);
2572 ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n");
2573 count = _read(fd, buf, 6);
2574 ok(count == 4, "_read returned %d, expected 4\n", count);
2575 count = count > 0 ? count > 4 ? 4 : count : 0;
2576 ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n");
2577 _close(fd);
2578 readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY;
2579 ok(!readonly, "expected rw file\n");
2580 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL);
2581 DeleteFileA("_creat.tst");
2583 if (have_fmode)
2584 p__set_fmode(old_fmode);
2587 START_TEST(file)
2589 int arg_c;
2590 char** arg_v;
2592 init();
2594 arg_c = winetest_get_mainargs( &arg_v );
2596 /* testing low-level I/O */
2597 if (arg_c >= 3)
2599 if (strcmp(arg_v[2], "inherit") == 0)
2600 test_file_inherit_child(arg_v[3]);
2601 else if (strcmp(arg_v[2], "inherit_no") == 0)
2602 test_file_inherit_child_no(arg_v[3]);
2603 else if (strcmp(arg_v[2], "pipes") == 0)
2604 test_pipes_child(arg_c, arg_v);
2605 else if (strcmp(arg_v[2], "stdin") == 0)
2606 test_invalid_stdin_child();
2607 else
2608 ok(0, "invalid argument '%s'\n", arg_v[2]);
2609 return;
2611 test_dup2();
2612 test_file_inherit(arg_v[0]);
2613 test_invalid_stdin(arg_v[0]);
2614 test_file_write_read();
2615 test_chsize();
2616 test_stat();
2617 test_unlink();
2619 /* testing stream I/O */
2620 test_filbuf();
2621 test_fdopen();
2622 test_fopen_fclose_fcloseall();
2623 test_fopen_s();
2624 test__wfopen_s();
2625 test_setmode();
2626 test_fileops();
2627 test_asciimode();
2628 test_asciimode2();
2629 test_filemodeT();
2630 test_readmode(FALSE); /* binary mode */
2631 test_readmode(TRUE); /* ascii mode */
2632 test_readboundary();
2633 test_fgetc();
2634 test_fputc();
2635 test_flsbuf();
2636 test_fflush();
2637 test_fgetwc();
2638 /* \x83\xa9 is double byte character, \xe0\x7f is not (undefined). */
2639 test_fgetwc_locale("AB\x83\xa9\xe0\x7f", "Japanese_Japan.932", 932);
2640 /* \x83 is U+0192 */
2641 test_fgetwc_locale("AB\x83\xa9", "English", 1252);
2642 /* \x83 is U+0083 */
2643 test_fgetwc_locale("AB\x83\xa9", "C", 0);
2644 test_fgetwc_unicode();
2645 test_fputwc();
2646 test_ctrlz();
2647 test_file_put_get();
2648 test_tmpnam();
2649 test_get_osfhandle();
2650 test_setmaxstdio();
2651 test_pipes(arg_v[0]);
2652 test_stdin();
2653 test_mktemp();
2654 test__open_osfhandle();
2655 test_write_flush();
2656 test_close();
2657 test__creat();
2659 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
2660 * file contains lines in the correct order
2662 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);