1 /*
2  * Unit test suite for file functions
3  *
4  * Copyright 2002 Bill Currie
5  * Copyright 2005 Paul Rupe
6  *
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.
11  *
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.
16  *
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
20  */
21 
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>
38 
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;
48 
49 static HANDLE proc_handles[2];
50 
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);
55 
get_base_name(const char * path)56 static const char* get_base_name(const char *path)
57 {
58     const char *ret = path+strlen(path)-1;
59 
60     while(ret >= path) {
61         if(*ret=='\\' || *ret=='/')
62             break;
63         ret--;
64     }
65     return ret+1;
66 }
67 
init(void)68 static void init(void)
69 {
70     HMODULE hmod = GetModuleHandleA("msvcrt.dll");
71 
72     setlocale(LC_CTYPE, "C");
73 
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");
79 }
80 
test_filbuf(void)81 static void test_filbuf( void )
82 {
83     FILE *fp;
84     int c;
85     fpos_t pos;
86 
87     fp = fopen("filbuf.tst", "wb");
88     fwrite("\n\n\n\n", 1, 4, fp);
89     fclose(fp);
90 
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.
104      */
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");
110 }
111 
test_fdopen(void)112 static void test_fdopen( void )
113 {
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;
118 
119     fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
120     write (fd, buffer, sizeof (buffer));
121     close (fd);
122 
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");
130 }
131 
test_fileops(void)132 static void test_fileops( void )
133 {
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};
142 
143     fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
144     write (fd, outbuffer, sizeof (outbuffer));
145     close (fd);
146 
147     for (bufmode=0; bufmode < ARRAY_SIZE(bufmodes); bufmode++)
148     {
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]);
165 
166         rewind(file);
167         for (i = 0; i < sizeof(outbuffer); i++)
168         {
169             ok(fgetc(file) == outbuffer[i], "fgetc returned wrong data for bufmode=%x\n", bufmodes[bufmode]);
170         }
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]);
185 
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]);
193 
194         fclose (file);
195     }
196     fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
197     file = fdopen (fd, "rt"); /* open in TEXT mode */
198     ok(fgetws(wbuffer,ARRAY_SIZE(wbuffer),file) !=0,"fgetws failed unexpected\n");
199     ok(fgetws(wbuffer,ARRAY_SIZE(wbuffer),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,ARRAY_SIZE(outbuffer),file) !=0,"fgets failed unexpected\n");
205     ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
206     fclose (file);
207 
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);
215 
216     unlink ("fdopen.tst");
217 }
218 
219 #define IOMODE (ao?"ascii mode":"binary mode")
test_readmode(BOOL ascii_mode)220 static void test_readmode( BOOL ascii_mode )
221 {
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;
233 
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
237      */
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);
247 
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 */
253     }
254     else {
255         fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
256         file = fdopen (fd, "rb");
257         ao = 0;
258     }
259 
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);
292 
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++;
311     }
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);
330 
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];
346     }
347     i = _getw(file);
348     ip = (int *)buffer;
349     ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
350 
351     fclose (file);
352     unlink ("fdopen.tst");
353 
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");
361 
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");
366 
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]);
374 
375     fclose(file);
376     unlink("fdopen.tst");
377 }
378 
test_asciimode(void)379 static void test_asciimode(void)
380 {
381     FILE *fp;
382     char buf[64];
383     int c, i, j;
384 
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");
396 
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);
411 
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);
416 
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);
429     }
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);
438     }
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);
446     }
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);
453 
454     unlink("ascii.tst");
455 }
456 
test_asciimode2(void)457 static void test_asciimode2(void)
458 {
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.
465      */
466 
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";
480 
481     fp = fopen("ascii2.tst", "wt");
482     fwrite(obuf, 1, sizeof(obuf), fp);
483     fclose(fp);
484 
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");
493 }
494 
test_filemodeT(void)495 static void test_filemodeT(void)
496 {
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;
506 
507     GetTempPathA(MAX_PATH, temppath);
508     GetTempFileNameA(temppath, "", 0, tempfile);
509 
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);
515 
516     ok (bytesRead == bytesWritten && bytesRead == sizeof(DATA),
517         "fopen file mode 'T' wrongly interpreted as 't'\n" );
518 
519     h = FindFirstFileA(tempfile, &findData);
520 
521     ok (h == INVALID_HANDLE_VALUE, "file wasn't deleted when closed.\n" );
522 
523     if (h != INVALID_HANDLE_VALUE) FindClose(h);
524 }
525 
AtoW(const char * p)526 static WCHAR* AtoW( const char* p )
527 {
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;
533 }
534 
535 /* Test reading in text mode when the 512'th character read is \r*/
test_readboundary(void)536 static void test_readboundary(void)
537 {
538   FILE *fp;
539   char buf[513], rbuf[513];
540   int i, j;
541   for (i = 0; i < 511; i++)
542     {
543       j = (i%('~' - ' ')+ ' ');
544       buf[i] = j;
545     }
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++)
553     {
554       fseek(fp,0 , SEEK_CUR);
555       rbuf[i] = fgetc(fp);
556     }
557   rbuf[512] =0;
558   fclose(fp);
559   unlink("boundary.tst");
560 
561   ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n");
562   }
563 
test_fgetc(void)564 static void test_fgetc( void )
565 {
566   char* tempf;
567   FILE *tempfh;
568   int  ich=0xe0, ret;
569 
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);
590 }
591 
test_fputc(void)592 static void test_fputc( void )
593 {
594   char* tempf;
595   FILE *tempfh;
596   int  ret;
597 
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);
607 
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);
612 
613   unlink(tempf);
614   free(tempf);
615 }
616 
test_flsbuf(void)617 static void test_flsbuf( void )
618 {
619   char* tempf;
620   FILE *tempfh;
621   int  c;
622   int  ret;
623   int  bufmode;
624   static const int bufmodes[] = {_IOFBF,_IONBF};
625 
626   tempf=_tempnam(".","wne");
627   for (bufmode=0; bufmode < ARRAY_SIZE(bufmodes); bufmode++)
628   {
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]);
649     }
650 
651     fclose(tempfh);
652   }
653 
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);
658 
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);
679 
680   unlink(tempf);
681   free(tempf);
682 }
683 
test_fflush(void)684 static void test_fflush( void )
685 {
686   static const char obuf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
687   char buf1[16], buf2[24];
688   char *tempf;
689   FILE *tempfh;
690   int ret;
691 
692   tempf=_tempnam(".","wne");
693 
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);
699 
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);
704 
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]);
713 
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]);
721 
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]);
729 
730   fclose(tempfh);
731 
732   unlink(tempf);
733   free(tempf);
734 }
735 
test_fgetwc(void)736 static void test_fgetwc( void )
737 {
738 #define LLEN 512
739 
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;
749 
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++)
775     {
776       diff_found |= (*aptr != *wptr);
777     }
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);
782 
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++)
826     {
827       ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
828       diff_found |= (*aptr != *wptr);
829     }
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++)
841     {
842       ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
843       diff_found |= (*aptr != *wptr);
844     }
845   ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
846   ok(*wptr == '\n', "Should get newline\n");
847 
848   free(mytextW);
849   fclose(tempfh);
850   unlink(tempf);
851   free(tempf);
852 }
853 
test_fgetwc_locale(const char * text,const char * locale,int codepage)854 static void test_fgetwc_locale(const char* text, const char* locale, int codepage)
855 {
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;
862 
863     if (!setlocale(LC_CTYPE, locale))
864     {
865         win_skip("%s locale not available\n", locale);
866         return;
867     }
868 
869     GetTempPathA(MAX_PATH, temppath);
870     GetTempFileNameA(temppath, "", 0, tempfile);
871 
872     tempfh = fopen(tempfile, "wb");
873     ok(tempfh != NULL, "can't open tempfile\n");
874     fwrite(text, 1, strlen(text), tempfh);
875     fclose(tempfh);
876 
877     if (codepage != 0)
878     {
879         /* mbstowcs rejects invalid multibyte sequence,
880            so we use MultiByteToWideChar here. */
881         ret = MultiByteToWideChar(codepage, 0, text, -1, wtextW, ARRAY_SIZE(wtextW));
882         ok(ret > 0, "MultiByteToWideChar failed\n");
883     }
884     else
885     {
886         /* C locale */
887         const char *p;
888         for (p = text; *p != '\0'; p++)
889             wtextW[ret++] = (unsigned char)*p;
890         wtextW[ret++] = 0;
891     }
892 
893     tempfh = fopen(tempfile, "rt");
894     ok(tempfh != NULL, "can't open tempfile\n");
895 
896     for (i = 0; i < ret-1; i++)
897     {
898         ch = fgetwc(tempfh);
899         ok(ch == wtextW[i], "got %04hx, expected %04hx (cp%d[%d])\n", ch, wtextW[i], codepage, i);
900     }
901     ch = fgetwc(tempfh);
902     ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage);
903     fclose(tempfh);
904 
905     tempfh = fopen(tempfile, "wb");
906     ok(tempfh != NULL, "can't open tempfile\n");
907     fwrite(wchar_text, 1, sizeof(wchar_text), tempfh);
908     fclose(tempfh);
909 
910     tempfh = fopen(tempfile, "rb");
911     ok(tempfh != NULL, "can't open tempfile\n");
912     for (i = 0; i < ARRAY_SIZE(wchar_text); i++)
913     {
914         ch = fgetwc(tempfh);
915         ok(ch == wchar_text[i], "got %04hx, expected %04x (cp%d[%d])\n", ch, wchar_text[i], codepage, i);
916     }
917     ch = fgetwc(tempfh);
918     ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage);
919     fclose(tempfh);
920     unlink(tempfile);
921 }
922 
test_fgetwc_unicode(void)923 static void test_fgetwc_unicode(void)
924 {
925     char temppath[MAX_PATH], tempfile[MAX_PATH];
926     FILE *tempfh;
927     static const WCHAR wchar_text[] = { 0xfeff, 0xff1f, '!' };
928     char utf8_text[BUFSIZ];
929     int ret, i;
930     wint_t ch;
931 
932     GetTempPathA(MAX_PATH, temppath);
933     GetTempFileNameA(temppath, "", 0, tempfile);
934 
935     if (!p_fopen_s)
936     {
937         win_skip("fopen_s not available\n");
938         return;
939     }
940 
941     tempfh = fopen(tempfile, "wb");
942     ok(tempfh != NULL, "can't open tempfile\n");
943     fwrite(wchar_text, 1, sizeof(wchar_text), tempfh);
944     fclose(tempfh);
945 
946     tempfh = fopen(tempfile, "rt,ccs=unicode");
947     ok(tempfh != NULL, "can't open tempfile\n");
948     for (i = 1; i < ARRAY_SIZE(wchar_text); i++)
949     {
950         ch = fgetwc(tempfh);
951         ok(ch == wchar_text[i],
952            "got %04hx, expected %04x (unicode[%d])\n", ch, wchar_text[i], i-1);
953     }
954     ch = fgetwc(tempfh);
955     ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch);
956     fclose(tempfh);
957 
958     tempfh = fopen(tempfile, "wb");
959     ok(tempfh != NULL, "can't open tempfile\n");
960     ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, ARRAY_SIZE(wchar_text),
961                               utf8_text, sizeof(utf8_text), NULL, NULL);
962     ok(ret > 0, "utf-8 conversion failed\n");
963     fwrite(utf8_text, sizeof(char), ret, tempfh);
964     fclose(tempfh);
965 
966     tempfh = fopen(tempfile, "rt, ccs=UTF-8");
967     ok(tempfh != NULL, "can't open tempfile\n");
968     for (i = 1; i < ARRAY_SIZE(wchar_text); i++)
969     {
970         ch = fgetwc(tempfh);
971         ok(ch == wchar_text[i],
972            "got %04hx, expected %04x (utf8[%d])\n", ch, wchar_text[i], i-1);
973     }
974     ch = fgetwc(tempfh);
975     ok(ch == WEOF, "got %04hx, expected WEOF (utf8)\n", ch);
976     fclose(tempfh);
977     unlink(temppath);
978 }
979 
test_fputwc(void)980 static void test_fputwc(void)
981 {
982     char temppath[MAX_PATH];
983     char tempfile[MAX_PATH];
984     FILE *f;
985     char buf[1024];
986     int ret;
987 
988     GetTempPathA(MAX_PATH, temppath);
989     GetTempFileNameA(temppath, "", 0, tempfile);
990 
991     f = fopen(tempfile, "w");
992     ret = fputwc('a', f);
993     ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
994     ret = fputwc('\n', f);
995     ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
996     fclose(f);
997 
998     f = fopen(tempfile, "rb");
999     ret = fread(buf, 1, sizeof(buf), f);
1000     ok(ret == 3, "fread returned %d, expected 3\n", ret);
1001     ok(!memcmp(buf, "a\r\n", 3), "incorrect file data\n");
1002     fclose(f);
1003 
1004     if(p_fopen_s) {
1005         f = fopen(tempfile, "w,ccs=unicode");
1006         ret = fputwc('a', f);
1007         ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
1008         ret = fputwc('\n', f);
1009         ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
1010         fclose(f);
1011 
1012         f = fopen(tempfile, "rb");
1013         ret = fread(buf, 1, sizeof(buf), f);
1014         ok(ret == 8, "fread returned %d, expected 8\n", ret);
1015         ok(!memcmp(buf, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n");
1016         fclose(f);
1017 
1018         f = fopen(tempfile, "w,ccs=utf-8");
1019         ret = fputwc('a', f);
1020         ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
1021         ret = fputwc('\n', f);
1022         ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
1023         fclose(f);
1024 
1025         f = fopen(tempfile, "rb");
1026         ret = fread(buf, 1, sizeof(buf), f);
1027         ok(ret == 6, "fread returned %d, expected 6\n", ret);
1028         ok(!memcmp(buf, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n");
1029         fclose(f);
1030     }else {
1031         win_skip("fputwc tests on unicode files\n");
1032     }
1033 
1034     _unlink(tempfile);
1035 }
1036 
test_ctrlz(void)1037 static void test_ctrlz( void )
1038 {
1039   char* tempf;
1040   FILE *tempfh;
1041   static const char mytext[]= "This is test_ctrlz";
1042   char buffer[256];
1043   int i, j;
1044   LONG l;
1045 
1046   tempf=_tempnam(".","wne");
1047   tempfh = fopen(tempf,"wb");
1048   fputs(mytext,tempfh);
1049   j = 0x1a; /* a ctrl-z character signals EOF in text mode */
1050   fputc(j,tempfh);
1051   j = '\r';
1052   fputc(j,tempfh);
1053   j = '\n';
1054   fputc(j,tempfh);
1055   j = 'a';
1056   fputc(j,tempfh);
1057   fclose(tempfh);
1058   tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1059   ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1060   i=strlen(buffer);
1061   j=strlen(mytext);
1062   ok(i==j, "returned string length expected %d got %d\n", j, i);
1063   j+=4; /* ftell should indicate the true end of file */
1064   l=ftell(tempfh);
1065   ok(l==j, "ftell expected %d got %d\n", j, l);
1066   ok(feof(tempfh), "did not get EOF\n");
1067   fclose(tempfh);
1068 
1069   tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
1070   ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1071   i=strlen(buffer);
1072   j=strlen(mytext)+3; /* should get through newline */
1073   ok(i==j, "returned string length expected %d got %d\n", j, i);
1074   l=ftell(tempfh);
1075   ok(l==j, "ftell expected %d got %d\n", j, l);
1076   ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1077   i=strlen(buffer);
1078   ok(i==1, "returned string length expected %d got %d\n", 1, i);
1079   ok(feof(tempfh), "did not get EOF\n");
1080   fclose(tempfh);
1081   unlink(tempf);
1082   free(tempf);
1083 }
1084 
test_file_put_get(void)1085 static void test_file_put_get( void )
1086 {
1087   char* tempf;
1088   FILE *tempfh;
1089   static const char mytext[]=  "This is a test_file_put_get\n";
1090   static const char dostext[]= "This is a test_file_put_get\r\n";
1091   char btext[LLEN];
1092   WCHAR wtextW[LLEN+1];
1093   WCHAR *mytextW = NULL, *aptr, *wptr;
1094   BOOL diff_found = FALSE;
1095   unsigned int i;
1096 
1097   tempf=_tempnam(".","wne");
1098   tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
1099   fputs(mytext,tempfh);
1100   fclose(tempfh);
1101   tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
1102   fgets(btext,LLEN,tempfh);
1103   ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
1104   ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
1105   fclose(tempfh);
1106   tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
1107   fputs(dostext,tempfh);
1108   fclose(tempfh);
1109   tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1110   fgets(btext,LLEN,tempfh);
1111   ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
1112   fclose(tempfh);
1113   tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
1114   fgets(btext,LLEN,tempfh);
1115   ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
1116 
1117   fclose(tempfh);
1118   tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1119   fgetws(wtextW,LLEN,tempfh);
1120   mytextW = AtoW (mytext);
1121   aptr = mytextW;
1122   wptr = wtextW;
1123 
1124   for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
1125     {
1126       diff_found |= (*aptr != *wptr);
1127     }
1128   ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
1129   free(mytextW);
1130   fclose(tempfh);
1131   unlink(tempf);
1132   free(tempf);
1133 }
1134 
test_file_write_read(void)1135 static void test_file_write_read( void )
1136 {
1137   char* tempf;
1138   int tempfd;
1139   static const char mytext[]=  "This is test_file_write_read\nsecond line\n";
1140   static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
1141   char btext[LLEN];
1142   int ret, i;
1143 
1144   tempf=_tempnam(".","wne");
1145   tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
1146                      _S_IREAD | _S_IWRITE);
1147   ok( tempfd != -1,
1148      "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1149   ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1150      "_write _O_BINARY bad return value\n");
1151   _close(tempfd);
1152   i = lstrlenA(mytext);
1153   tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1154   ok(_read(tempfd,btext,i) == i,
1155      "_read _O_BINARY got bad length\n");
1156   ok( memcmp(dostext,btext,i) == 0,
1157       "problems with _O_BINARY  _write / _read\n");
1158   _close(tempfd);
1159   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1160   ok(_read(tempfd,btext,i) == i-1,
1161      "_read _O_TEXT got bad length\n");
1162   ok( memcmp(mytext,btext,i-1) == 0,
1163       "problems with _O_BINARY _write / _O_TEXT _read\n");
1164   _close(tempfd);
1165   tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
1166                      _S_IREAD | _S_IWRITE);
1167   ok( tempfd != -1,
1168      "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
1169   ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
1170      "_write _O_TEXT bad return value\n");
1171   _close(tempfd);
1172   tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1173   ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1174      "_read _O_BINARY got bad length\n");
1175   ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1176       "problems with _O_TEXT _write / _O_BINARY _read\n");
1177   ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1178   _close(tempfd);
1179   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1180   ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1181      "_read _O_TEXT got bad length\n");
1182   ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1183       "problems with _O_TEXT _write / _read\n");
1184   _close(tempfd);
1185 
1186   memset(btext, 0, LLEN);
1187   tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
1188   ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
1189   ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
1190   ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
1191   _close(tempfd);
1192 
1193   /* Test reading only \n or \r */
1194   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1195   _lseek(tempfd, -1, FILE_END);
1196   ret = _read(tempfd,btext,LLEN);
1197   ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
1198   _lseek(tempfd, -2, FILE_END);
1199   ret = _read(tempfd,btext,LLEN);
1200   ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
1201   _lseek(tempfd, -2, FILE_END);
1202   ret = _read(tempfd,btext,1);
1203   ok(ret == 1 && *btext == '\n', "_read returned %d, buf: %d\n", ret, *btext);
1204   ret = read(tempfd,btext,1);
1205   ok(ret == 0, "_read returned %d, expected 0\n", ret);
1206   _lseek(tempfd, -3, FILE_END);
1207   ret = _read(tempfd,btext,1);
1208   ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1209   ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
1210   _lseek(tempfd, -3, FILE_END);
1211   ret = _read(tempfd,btext,2);
1212   ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1213   ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
1214   _lseek(tempfd, -3, FILE_END);
1215   ret = _read(tempfd,btext,3);
1216   ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1217   ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
1218    _close(tempfd);
1219 
1220   ret = unlink(tempf);
1221   ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1222   free(tempf);
1223 
1224   tempf=_tempnam(".","wne");
1225   tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, _S_IWRITE);
1226   ok( tempfd != -1,
1227      "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1228   ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1229      "_write _O_BINARY bad return value\n");
1230   _close(tempfd);
1231   tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1232   ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1233      "_read _O_BINARY got bad length\n");
1234   ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1235       "problems with _O_BINARY _write / _read\n");
1236   ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1237   _close(tempfd);
1238   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1239   ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1240      "_read _O_TEXT got bad length\n");
1241   ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1242       "problems with _O_BINARY _write / _O_TEXT _read\n");
1243   _close(tempfd);
1244 
1245   /* test _read with single bytes. CR should be skipped and LF pulled in */
1246   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1247   for (i=0; i<strlen(mytext); i++)  /* */
1248     {
1249       _read(tempfd,btext, 1);
1250       ok(btext[0] ==  mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
1251     }
1252   while (_read(tempfd,btext, 1));
1253   _close(tempfd);
1254 
1255   /* test _read in buffered mode. Last CR should be skipped but  LF not pulled in */
1256   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1257   i = _read(tempfd,btext, strlen(mytext));
1258   ok(i == strlen(mytext)-1, "_read_i %d\n", i);
1259   _close(tempfd);
1260 
1261   /* test read/write in unicode mode */
1262   if(p_fopen_s)
1263   {
1264       tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE);
1265       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1266       ret = _write(tempfd, "a", 1);
1267       ok(ret == -1, "_write returned %d, expected -1\n", ret);
1268       ret = _write(tempfd, "a\x00\n\x00\xff\xff", 6);
1269       ok(ret == 6, "_write returned %d, expected 6\n", ret);
1270       _close(tempfd);
1271 
1272       tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1273       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1274       ret = _read(tempfd, btext, sizeof(btext));
1275       ok(ret == 10, "_read returned %d, expected 10\n", ret);
1276       ok(!memcmp(btext, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1277       _close(tempfd);
1278 
1279       tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1280       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1281       errno = 0xdeadbeef;
1282       ret = _read(tempfd, btext, 3);
1283       ok(ret == -1, "_read returned %d, expected -1\n", ret);
1284       ok(errno == 22, "errno = %d\n", errno);
1285       ret = _read(tempfd, btext, sizeof(btext));
1286       ok(ret == 6, "_read returned %d, expected 6\n", ret);
1287       ok(!memcmp(btext, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1288       _close(tempfd);
1289 
1290       tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_U8TEXT, _S_IWRITE);
1291       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1292       errno = 0xdeadbeef;
1293       ret = _write(tempfd, "a", 1);
1294       ok(ret == -1, "_write returned %d, expected -1\n", ret);
1295       ok(errno == 22, "errno = %d\n", errno);
1296       ret = _write(tempfd, "a\x00\n\x00\x62\x00", 6);
1297       ok(ret == 6, "_write returned %d, expected 6\n", ret);
1298       _close(tempfd);
1299 
1300       tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1301       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1302       ret = _read(tempfd, btext, sizeof(btext));
1303       ok(ret == 7, "_read returned %d, expected 7\n", ret);
1304       ok(!memcmp(btext, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1305       _close(tempfd);
1306 
1307       tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1308       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1309       ret = _read(tempfd, btext, sizeof(btext));
1310       ok(ret == 6, "_read returned %d, expected 6\n", ret);
1311       ok(!memcmp(btext, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1312 
1313       /* when buffer is small read sometimes fails in native implementation */
1314       lseek(tempfd, 3 /* skip bom */, SEEK_SET);
1315       ret = _read(tempfd, btext, 4);
1316       todo_wine ok(ret == -1, "_read returned %d, expected -1\n", ret);
1317 
1318       lseek(tempfd, 6, SEEK_SET);
1319       ret = _read(tempfd, btext, 2);
1320       ok(ret == 2, "_read returned %d, expected 2\n", ret);
1321       ok(!memcmp(btext, "\x62\x00", 2), "btext is incorrect\n");
1322       _close(tempfd);
1323 
1324       tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IWRITE);
1325       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1326       ret = _write(tempfd, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1327       ok(ret == 12, "_write returned %d, expected 9\n", ret);
1328       _close(tempfd);
1329 
1330       tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1331       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1332       ret = _read(tempfd, btext, sizeof(btext));
1333       ok(ret == 12, "_read returned %d, expected 12\n", ret);
1334       ok(!memcmp(btext, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1335 
1336       /* test invalid utf8 sequence */
1337       lseek(tempfd, 5, SEEK_SET);
1338       ret = _read(tempfd, btext, sizeof(btext));
1339       todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret);
1340       /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1341       todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1342       ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1343       _close(tempfd);
1344   }
1345   else
1346   {
1347       win_skip("unicode mode tests on file\n");
1348   }
1349 
1350   ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
1351   ok( ret == 0,
1352      "Can't chmod '%s' to read-write: %d\n", tempf, errno);
1353   ret = unlink(tempf);
1354   ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1355   free(tempf);
1356 }
1357 
test_file_inherit_child(const char * fd_s)1358 static void test_file_inherit_child(const char* fd_s)
1359 {
1360     int fd = atoi(fd_s);
1361     char buffer[32];
1362     int ret;
1363 
1364     ret =write(fd, "Success", 8);
1365     ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
1366     lseek(fd, 0, SEEK_SET);
1367     ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
1368     ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1369 }
1370 
test_file_inherit_child_no(const char * fd_s)1371 static void test_file_inherit_child_no(const char* fd_s)
1372 {
1373     int fd = atoi(fd_s);
1374     int ret;
1375 
1376     ret = write(fd, "Success", 8);
1377     ok( ret == -1 && errno == EBADF,
1378        "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
1379 }
1380 
create_io_inherit_block(STARTUPINFOA * startup,unsigned int count,const HANDLE * handles)1381 static void create_io_inherit_block( STARTUPINFOA *startup, unsigned int count, const HANDLE *handles )
1382 {
1383     static BYTE block[1024];
1384     BYTE *wxflag_ptr;
1385     HANDLE *handle_ptr;
1386     unsigned int i;
1387 
1388     startup->lpReserved2 = block;
1389     startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
1390     wxflag_ptr = block + sizeof(unsigned);
1391     handle_ptr = (HANDLE *)(wxflag_ptr + count);
1392 
1393     *(unsigned*)block = count;
1394     for (i = 0; i < count; i++)
1395     {
1396         wxflag_ptr[i] = 0x81;
1397         handle_ptr[i] = handles[i];
1398     }
1399 }
1400 
read_file(HANDLE file)1401 static const char *read_file( HANDLE file )
1402 {
1403     static char buffer[128];
1404     DWORD ret;
1405     SetFilePointer( file, 0, NULL, FILE_BEGIN );
1406     if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
1407     buffer[ret] = 0;
1408     return buffer;
1409 }
1410 
test_stdout_handle(STARTUPINFOA * startup,char * cmdline,HANDLE hstdout,BOOL expect_stdout,const char * descr)1411 static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
1412                                 const char *descr )
1413 {
1414     const char *data;
1415     HANDLE hErrorFile;
1416     SECURITY_ATTRIBUTES sa;
1417     PROCESS_INFORMATION proc;
1418 
1419     /* make file handle inheritable */
1420     sa.nLength = sizeof(sa);
1421     sa.lpSecurityDescriptor = NULL;
1422     sa.bInheritHandle = TRUE;
1423 
1424     hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1425                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1426     startup->dwFlags    = STARTF_USESTDHANDLES;
1427     startup->hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
1428     startup->hStdOutput = hErrorFile;
1429     startup->hStdError  = GetStdHandle( STD_ERROR_HANDLE );
1430 
1431     CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1432                     CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1433     winetest_wait_child_process( proc.hProcess );
1434 
1435     data = read_file( hErrorFile );
1436     if (expect_stdout)
1437         ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1438     else
1439         ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1440 
1441     if (hstdout)
1442     {
1443         data = read_file( hstdout );
1444         if (expect_stdout)
1445             ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1446         else
1447             ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1448     }
1449 
1450     CloseHandle( hErrorFile );
1451     DeleteFileA( "fdopen.err" );
1452 }
1453 
test_file_inherit(const char * selfname)1454 static void test_file_inherit( const char* selfname )
1455 {
1456     int			fd;
1457     const char*		arg_v[5];
1458     char 		buffer[16];
1459     char cmdline[MAX_PATH];
1460     STARTUPINFOA startup;
1461     SECURITY_ATTRIBUTES sa;
1462     HANDLE handles[3];
1463 
1464     fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1465     ok(fd != -1, "Couldn't create test file\n");
1466     arg_v[0] = get_base_name(selfname);
1467     arg_v[1] = "tests/file.c";
1468     arg_v[2] = "inherit";
1469     arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1470     arg_v[4] = 0;
1471     _spawnvp(_P_WAIT, selfname, arg_v);
1472     ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1473     lseek(fd, 0, SEEK_SET);
1474     ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1475     close (fd);
1476     ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1477 
1478     fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1479     ok(fd != -1, "Couldn't create test file\n");
1480     arg_v[1] = "tests/file.c";
1481     arg_v[2] = "inherit_no";
1482     arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1483     arg_v[4] = 0;
1484     _spawnvp(_P_WAIT, selfname, arg_v);
1485     ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1486     ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1487     close (fd);
1488     ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1489 
1490     /* make file handle inheritable */
1491     sa.nLength = sizeof(sa);
1492     sa.lpSecurityDescriptor = NULL;
1493     sa.bInheritHandle = TRUE;
1494     sprintf(cmdline, "%s file inherit 1", selfname);
1495 
1496     /* init an empty Reserved2, which should not be recognized as inherit-block */
1497     ZeroMemory(&startup, sizeof(startup));
1498     startup.cb = sizeof(startup);
1499     create_io_inherit_block( &startup, 0, NULL );
1500     test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1501 
1502     /* test with valid inheritblock */
1503     handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1504     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1505                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1506     handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1507     create_io_inherit_block( &startup, 3, handles );
1508     test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1509     CloseHandle( handles[1] );
1510     DeleteFileA("fdopen.tst");
1511 
1512     /* test inherit block starting with unsigned zero */
1513     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1514                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1515     create_io_inherit_block( &startup, 3, handles );
1516     *(unsigned int *)startup.lpReserved2 = 0;
1517     test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1518     CloseHandle( handles[1] );
1519     DeleteFileA("fdopen.tst");
1520 
1521     /* test inherit block with smaller size */
1522     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1523                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1524     create_io_inherit_block( &startup, 3, handles );
1525     startup.cbReserved2 -= 3;
1526     test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1527     CloseHandle( handles[1] );
1528     DeleteFileA("fdopen.tst");
1529 
1530     /* test inherit block with even smaller size */
1531     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1532                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1533     create_io_inherit_block( &startup, 3, handles );
1534     startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1535     test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1536     CloseHandle( handles[1] );
1537     DeleteFileA("fdopen.tst");
1538 
1539     /* test inherit block with larger size */
1540     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1541                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1542     create_io_inherit_block( &startup, 3, handles );
1543     startup.cbReserved2 += 7;
1544     test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1545     CloseHandle( handles[1] );
1546     DeleteFileA("fdopen.tst");
1547 }
1548 
test_invalid_stdin_child(void)1549 static void test_invalid_stdin_child( void )
1550 {
1551     HANDLE handle;
1552     ioinfo *info;
1553     int ret;
1554     char c;
1555 
1556     errno = 0xdeadbeef;
1557     handle = (HANDLE)_get_osfhandle(STDIN_FILENO);
1558     ok(handle == (HANDLE)-2, "handle = %p\n", handle);
1559     ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1560 
1561     info = &__pioinfo[STDIN_FILENO/MSVCRT_FD_BLOCK_SIZE][STDIN_FILENO%MSVCRT_FD_BLOCK_SIZE];
1562     ok(info->handle == (HANDLE)-2, "info->handle = %p\n", info->handle);
1563     ok(info->wxflag == 0xc1, "info->wxflag = %x\n", info->wxflag);
1564 
1565     ok(stdin->_file == -2, "stdin->_file = %d\n", stdin->_file);
1566 
1567     errno = 0xdeadbeef;
1568     ret = fread(&c, 1, 1, stdin);
1569     ok(!ret, "fread(stdin) returned %d\n", ret);
1570     ok(errno == EBADF, "errno = %d\n", errno);
1571 
1572     errno = 0xdeadbeef;
1573     ret = read(-2, &c, 1);
1574     ok(ret == -1, "read(-2) returned %d\n", ret);
1575     ok(errno == EBADF, "errno = %d\n", errno);
1576 
1577     errno = 0xdeadbeef;
1578     ret = read(STDIN_FILENO, &c, 1);
1579     ok(ret == -1, "read(STDIN_FILENO) returned %d\n", ret);
1580     ok(errno == EBADF, "errno = %d\n", errno);
1581 
1582     errno = 0xdeadbeef;
1583     ret = _flsbuf('a', stdin);
1584     ok(ret == EOF, "_flsbuf(stdin) returned %d\n", ret);
1585     ok(errno == EBADF, "errno = %d\n", errno);
1586 
1587     errno = 0xdeadbeef;
1588     ret = fwrite(&c, 1, 1, stdin);
1589     ok(!ret, "fwrite(stdin) returned %d\n", ret);
1590     ok(errno == EBADF, "errno = %d\n", errno);
1591 
1592     errno = 0xdeadbeef;
1593     ret = write(-2, &c, 1);
1594     ok(ret == -1, "write(-2) returned %d\n", ret);
1595     ok(errno == EBADF, "errno = %d\n", errno);
1596 
1597     errno = 0xdeadbeef;
1598     ret = write(STDIN_FILENO, &c, 1);
1599     ok(ret == -1, "write(STDIN_FILENO) returned %d\n", ret);
1600     ok(errno == EBADF, "errno = %d\n", errno);
1601 
1602     errno = 0xdeadbeef;
1603     ret = fclose(stdin);
1604     ok(ret == -1, "fclose(stdin) returned %d\n", ret);
1605     ok(errno == EBADF, "errno = %d\n", errno);
1606 
1607     errno = 0xdeadbeef;
1608     ret = close(-2);
1609     ok(ret == -1, "close(-2) returned %d\n", ret);
1610     ok(errno == EBADF, "errno = %d\n", errno);
1611 
1612     errno = 0xdeadbeef;
1613     ret = close(STDIN_FILENO);
1614     ok(ret==-1 || !ret, "close(STDIN_FILENO) returned %d\n", ret);
1615     ok((ret==-1 && errno==EBADF) || (!ret && errno==0xdeadbeef), "errno = %d\n", errno);
1616 }
1617 
test_invalid_stdin(const char * selfname)1618 static void test_invalid_stdin( const char* selfname )
1619 {
1620     char cmdline[MAX_PATH];
1621     PROCESS_INFORMATION proc;
1622     SECURITY_ATTRIBUTES sa;
1623     STARTUPINFOA startup;
1624     HKEY key;
1625     LONG ret;
1626 
1627     if(!p_fopen_s) {
1628         /* Behaviour of the dll has changed in newer version */
1629         win_skip("skipping invalid stdin tests\n");
1630         return;
1631     }
1632 
1633     ret = RegOpenCurrentUser(KEY_READ, &key);
1634     ok(!ret, "RegOpenCurrentUser failed: %x\n", ret);
1635 
1636     sa.nLength = sizeof(sa);
1637     sa.lpSecurityDescriptor = NULL;
1638     sa.bInheritHandle = TRUE;
1639 
1640     memset(&startup, 0, sizeof(startup));
1641     startup.cb = sizeof(startup);
1642     startup.dwFlags = STARTF_USESTDHANDLES;
1643     startup.hStdInput = key;
1644     startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
1645     startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);
1646 
1647     sprintf(cmdline, "%s file stdin", selfname);
1648     CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
1649             CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc);
1650     winetest_wait_child_process(proc.hProcess);
1651 
1652     ret = RegCloseKey(key);
1653     ok(!ret, "RegCloseKey failed: %x\n", ret);
1654 }
1655 
test_tmpnam(void)1656 static void test_tmpnam( void )
1657 {
1658   char name[MAX_PATH] = "abc";
1659   char *res;
1660 
1661   res = tmpnam(NULL);
1662   ok(res != NULL, "tmpnam returned NULL\n");
1663   ok(res[0] == '\\', "first character is not a backslash\n");
1664   ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1665   ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1666 
1667   res = tmpnam(name);
1668   ok(res != NULL, "tmpnam returned NULL\n");
1669   ok(res == name, "supplied buffer was not used\n");
1670   ok(res[0] == '\\', "first character is not a backslash\n");
1671   ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1672   ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1673 }
1674 
test_chsize(void)1675 static void test_chsize( void )
1676 {
1677     int fd;
1678     LONG cur, pos, count;
1679     char temptext[] = "012345678";
1680     char *tempfile = _tempnam( ".", "tst" );
1681 
1682     ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1683 
1684     fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1685     ok( fd > 0, "Couldn't open test file\n" );
1686 
1687     count = _write( fd, temptext, sizeof(temptext) );
1688     ok( count > 0, "Couldn't write to test file\n" );
1689 
1690     /* get current file pointer */
1691     cur = _lseek( fd, 0, SEEK_CUR );
1692 
1693     /* make the file smaller */
1694     ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1695 
1696     pos = _lseek( fd, 0, SEEK_CUR );
1697     ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1698     ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1699 
1700     /* enlarge the file */
1701     ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
1702 
1703     pos = _lseek( fd, 0, SEEK_CUR );
1704     ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1705     ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1706 
1707     _close( fd );
1708     _unlink( tempfile );
1709     free( tempfile );
1710 }
1711 
test_fopen_fclose_fcloseall(void)1712 static void test_fopen_fclose_fcloseall( void )
1713 {
1714     char fname1[] = "empty1";
1715     char fname2[] = "empty2";
1716     char fname3[] = "empty3";
1717     FILE *stream1, *stream2, *stream3, *stream4;
1718     int ret, numclosed;
1719 
1720     /* testing fopen() */
1721     stream1 = fopen(fname1, "w+");
1722     ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1723     stream2 = fopen(fname2, "w ");
1724     ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1725     _unlink(fname3);
1726     stream3 = fopen(fname3, "r");
1727     ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1728     stream3 = fopen(fname3, "w+");
1729     ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1730     errno = 0xfaceabad;
1731     stream4 = fopen("", "w+");
1732     ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1733        "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1734     errno = 0xfaceabad;
1735     stream4 = fopen(NULL, "w+");
1736     ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1737        "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1738 
1739     /* testing fclose() */
1740     ret = fclose(stream2);
1741     ok(ret == 0, "The file '%s' was not closed\n", fname2);
1742     ret = fclose(stream3);
1743     ok(ret == 0, "The file '%s' was not closed\n", fname3);
1744     errno = 0xdeadbeef;
1745     ret = fclose(stream2);
1746     ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1747     ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1748     ret = fclose(stream3);
1749     ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1750     ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1751 
1752     /* testing fcloseall() */
1753     numclosed = _fcloseall();
1754     /* fname1 should be closed here */
1755     ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1756     numclosed = _fcloseall();
1757     ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1758 
1759     ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1760     ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1761     ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1762 }
1763 
test_fopen_s(void)1764 static void test_fopen_s( void )
1765 {
1766     const char name[] = "empty1";
1767     char buff[16];
1768     unsigned char *ubuff = (unsigned char*)buff;
1769     FILE *file, *file2;
1770     int ret;
1771     int len;
1772 
1773     if (!p_fopen_s)
1774     {
1775         win_skip("Skipping fopen_s test\n");
1776         return;
1777     }
1778     /* testing fopen_s */
1779     ret = p_fopen_s(&file, name, "w");
1780     ok(ret == 0, "fopen_s failed with %d\n", ret);
1781     ok(file != 0, "fopen_s failed to return value\n");
1782     fwrite(name, sizeof(name), 1, file);
1783 
1784     ret = fclose(file);
1785     ok(ret != EOF, "File failed to close\n");
1786 
1787     file = fopen(name, "r");
1788     ok(file != 0, "fopen failed\n");
1789     len = fread(buff, 1, sizeof(name), file);
1790     ok(len == sizeof(name), "File length is %d\n", len);
1791     buff[sizeof(name)] = '\0';
1792     ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1793 
1794     ret = fclose(file);
1795     ok(ret != EOF, "File failed to close\n");
1796 
1797     ret = p_fopen_s(&file, name, "w,  ccs=UNIcode");
1798     ok(ret == 0, "fopen_s failed with %d\n", ret);
1799     ret = fwrite("a", 1, 2, file);
1800     ok(ret == 2, "fwrite returned %d\n", ret);
1801     fclose(file);
1802 
1803     ret = p_fopen_s(&file, name, "r");
1804     ok(ret == 0, "fopen_s failed with %d\n", ret);
1805     len = fread(buff, 1, 2, file);
1806     ok(len == 2, "len = %d\n", len);
1807     ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1808             ubuff[0], ubuff[1]);
1809     fclose(file);
1810 
1811     ret = p_fopen_s(&file, name, "r,ccs=unicode");
1812     ok(ret == 0, "fopen_s failed with %d\n", ret);
1813     len = fread(buff, 1, 2, file);
1814     ok(len == 2, "len = %d\n", len);
1815     ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1816             ubuff[0], ubuff[1]);
1817     fclose(file);
1818 
1819     ret = p_fopen_s(&file, name, "r,ccs=utf-16le");
1820     ok(ret == 0, "fopen_s failed with %d\n", ret);
1821     len = fread(buff, 1, 2, file);
1822     ok(len == 2, "len = %d\n", len);
1823     ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1824             ubuff[0], ubuff[1]);
1825     fclose(file);
1826 
1827     ret = p_fopen_s(&file, name, "r,ccs=utf-8");
1828     ok(ret == 0, "fopen_s failed with %d\n", ret);
1829     len = fread(buff, 1, 2, file);
1830     ok(len == 2, "len = %d\n", len);
1831     ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1832             ubuff[0], ubuff[1]);
1833     fclose(file);
1834 
1835     ret = p_fopen_s(&file, name, "w,ccs=utf-16le");
1836     ok(ret == 0, "fopen_s failed with %d\n", ret);
1837     fclose(file);
1838 
1839     ret = p_fopen_s(&file, name, "r");
1840     ok(ret == 0, "fopen_s failed with %d\n", ret);
1841     len = fread(buff, 1, 3, file);
1842     ok(len == 2, "len = %d\n", len);
1843     ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1844             ubuff[0], ubuff[1]);
1845     fclose(file);
1846 
1847     ret = p_fopen_s(&file, name, "w,ccs=utf-8");
1848     ok(ret == 0, "fopen_s failed with %d\n", ret);
1849     fclose(file);
1850 
1851     ret = p_fopen_s(&file, name, "r");
1852     ok(ret == 0, "fopen_s failed with %d\n", ret);
1853     len = fread(buff, 1, 4, file);
1854     ok(len == 3, "len = %d\n", len);
1855     ok(ubuff[0]==0xef && ubuff[1]==0xbb && ubuff[2]==0xbf,
1856             "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1857             ubuff[0], ubuff[1], ubuff[2]);
1858     fclose(file);
1859 
1860     /* test initial FILE values */
1861     memset(file, 0xfe, sizeof(*file));
1862     file->_flag = 0;
1863     ret = p_fopen_s(&file2, name, "r");
1864     ok(!ret, "fopen_s failed with %d\n", ret);
1865     ok(file == file2, "file != file2 %p %p\n", file, file2);
1866     ok(!file->_ptr, "file->_ptr != NULL\n");
1867     ok(!file->_cnt, "file->_cnt != 0\n");
1868     ok(!file->_base, "file->_base != NULL\n");
1869     ok(file->_flag == 1, "file->_flag = %x\n", file->_flag);
1870     ok(file->_file, "file->_file == 0\n");
1871     ok(file->_charbuf == 0xfefefefe, "file->_charbuf = %x\n", file->_charbuf);
1872     ok(file->_bufsiz == 0xfefefefe, "file->_bufsiz = %x\n", file->_bufsiz);
1873     ok(!file->_tmpfname, "file->_tmpfname != NULL\n");
1874     fclose(file2);
1875 
1876     ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1877 }
1878 
test__wfopen_s(void)1879 static void test__wfopen_s( void )
1880 {
1881     const char name[] = "empty1";
1882     const WCHAR wname[] = {
1883        'e','m','p','t','y','1',0
1884     };
1885     const WCHAR wmode[] = {
1886        'w',0
1887     };
1888     char buff[16];
1889     FILE *file;
1890     int ret;
1891     int len;
1892 
1893     if (!p__wfopen_s)
1894     {
1895         win_skip("Skipping _wfopen_s test\n");
1896         return;
1897     }
1898     /* testing _wfopen_s */
1899     ret = p__wfopen_s(&file, wname, wmode);
1900     ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1901     ok(file != 0, "_wfopen_s failed to return value\n");
1902     fwrite(name, sizeof(name), 1, file);
1903 
1904     ret = fclose(file);
1905     ok(ret != EOF, "File failed to close\n");
1906 
1907     file = fopen(name, "r");
1908     ok(file != 0, "fopen failed\n");
1909     len = fread(buff, 1, sizeof(name), file);
1910     ok(len == sizeof(name), "File length is %d\n", len);
1911     buff[sizeof(name)] = '\0';
1912     ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1913 
1914     ret = fclose(file);
1915     ok(ret != EOF, "File failed to close\n");
1916 
1917     ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1918 }
1919 
test_setmode(void)1920 static void test_setmode(void)
1921 {
1922     const char name[] = "empty1";
1923     int fd, ret;
1924 
1925     if(!p_fopen_s) {
1926         win_skip("unicode file modes are not available, skipping setmode tests\n");
1927         return;
1928     }
1929 
1930     errno = 0xdeadbeef;
1931     ret = _setmode(-2, 0);
1932     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1933     ok(errno == EINVAL, "errno = %d\n", errno);
1934 
1935     errno = 0xdeadbeef;
1936     ret = _setmode(-2, _O_TEXT);
1937     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1938     ok(errno == EBADF, "errno = %d\n", errno);
1939 
1940     fd = _open(name, _O_CREAT|_O_WRONLY, _S_IWRITE);
1941     ok(fd != -1, "failed to open file\n");
1942 
1943     errno = 0xdeadbeef;
1944     ret = _setmode(fd, 0xffffffff);
1945     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1946     ok(errno == EINVAL, "errno = %d\n", errno);
1947 
1948     errno = 0xdeadbeef;
1949     ret = _setmode(fd, 0);
1950     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1951     ok(errno == EINVAL, "errno = %d\n", errno);
1952 
1953     errno = 0xdeadbeef;
1954     ret = _setmode(fd, _O_BINARY|_O_TEXT);
1955     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1956     ok(errno == EINVAL, "errno = %d\n", errno);
1957 
1958     errno = 0xdeadbeef;
1959     ret = _setmode(fd, _O_WTEXT|_O_U16TEXT);
1960     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1961     ok(errno == EINVAL, "errno = %d\n", errno);
1962 
1963     ret = _setmode(fd, _O_BINARY);
1964     ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1965 
1966     ret = _setmode(fd, _O_WTEXT);
1967     ok(ret == _O_BINARY, "_setmode returned %x, expected _O_BINARY\n", ret);
1968 
1969     ret = _setmode(fd, _O_TEXT);
1970     ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1971 
1972     ret = _setmode(fd, _O_U16TEXT);
1973     ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1974 
1975     ret = _setmode(fd, _O_U8TEXT);
1976     ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1977 
1978     ret = _setmode(fd, _O_TEXT);
1979     ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1980 
1981     _close(fd);
1982     _unlink(name);
1983 }
1984 
test_get_osfhandle(void)1985 static void test_get_osfhandle(void)
1986 {
1987     int fd;
1988     char fname[] = "t_get_osfhanle";
1989     DWORD bytes_written;
1990     HANDLE handle;
1991 
1992     fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1993     handle = (HANDLE)_get_osfhandle(fd);
1994     WriteFile(handle, "bar", 3, &bytes_written, NULL);
1995     _close(fd);
1996     fd = _open(fname, _O_RDONLY, 0);
1997     ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
1998 
1999     _close(fd);
2000     _unlink(fname);
2001 
2002     errno = 0xdeadbeef;
2003     handle = (HANDLE)_get_osfhandle(fd);
2004     ok(handle == INVALID_HANDLE_VALUE, "_get_osfhandle returned %p\n", handle);
2005     ok(errno == EBADF, "errno = %d\n", errno);
2006 }
2007 
test_setmaxstdio(void)2008 static void test_setmaxstdio(void)
2009 {
2010     ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
2011     ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
2012 }
2013 
test_stat(void)2014 static void test_stat(void)
2015 {
2016     int fd;
2017     int pipes[2];
2018     int ret;
2019     struct stat buf;
2020 
2021     /* Tests for a file */
2022     fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
2023     if (fd >= 0)
2024     {
2025         ret = fstat(fd, &buf);
2026         ok(!ret, "fstat failed: errno=%d\n", errno);
2027         ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
2028         ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
2029         ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
2030         ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
2031         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2032         ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
2033 
2034         ret = stat("stat.tst", &buf);
2035         ok(!ret, "stat failed: errno=%d\n", errno);
2036         ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
2037         ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
2038         ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
2039         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2040         ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
2041 
2042         errno = 0xdeadbeef;
2043         ret = stat("stat.tst\\", &buf);
2044         ok(ret == -1, "stat returned %d\n", ret);
2045         ok(errno == ENOENT, "errno = %d\n", errno);
2046 
2047         close(fd);
2048         remove("stat.tst");
2049     }
2050     else
2051         skip("open failed with errno %d\n", errno);
2052 
2053     /* Tests for a char device */
2054     if (_dup2(0, 10) == 0)
2055     {
2056         ret = fstat(10, &buf);
2057         ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
2058         if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
2059         {
2060             ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
2061             ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
2062             ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
2063             ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2064         }
2065         else
2066             skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
2067         close(10);
2068     }
2069     else
2070         skip("_dup2 failed with errno %d\n", errno);
2071 
2072     /* Tests for pipes */
2073     if (_pipe(pipes, 1024, O_BINARY) == 0)
2074     {
2075         ret = fstat(pipes[0], &buf);
2076         ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
2077         ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
2078         ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
2079         ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
2080         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2081         close(pipes[0]);
2082         close(pipes[1]);
2083     }
2084     else
2085         skip("pipe failed with errno %d\n", errno);
2086 
2087     /* Tests for directory */
2088     if(mkdir("stat.tst") == 0)
2089     {
2090         ret = stat("stat.tst                         ", &buf);
2091         ok(!ret, "stat(directory) failed: errno=%d\n", errno);
2092         ok((buf.st_mode & _S_IFMT) == _S_IFDIR, "bad format = %06o\n", buf.st_mode);
2093         ok((buf.st_mode & 0777) == 0777, "bad st_mode = %06o\n", buf.st_mode);
2094         ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
2095         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
2096 
2097         errno = 0xdeadbeef;
2098         ret = stat("stat.tst\\ ", &buf);
2099         ok(ret == -1, "stat returned %d\n", ret);
2100         ok(errno == ENOENT, "errno = %d\n", errno);
2101         rmdir( "stat.tst" );
2102     }
2103     else
2104         skip("mkdir failed with errno %d\n", errno);
2105 
2106     errno = 0xdeadbeef;
2107     ret = stat("c:", &buf);
2108     ok(ret == -1, "stat returned %d\n", ret);
2109     ok(errno == ENOENT, "errno = %d\n", errno);
2110 
2111     ret = stat("c:/", &buf);
2112     ok(!ret, "stat returned %d\n", ret);
2113     ok(buf.st_dev == 2, "st_dev = %d\n", buf.st_dev);
2114     ok(buf.st_rdev == 2, "st_rdev = %d\n", buf.st_rdev);
2115 }
2116 
2117 static const char* pipe_string="Hello world";
2118 
2119 /* How many messages to transfer over the pipe */
2120 #define N_TEST_MESSAGES 3
2121 
test_pipes_child(int argc,char ** args)2122 static void test_pipes_child(int argc, char** args)
2123 {
2124     int fd;
2125     int nwritten;
2126     int i;
2127 
2128     if (argc < 5)
2129     {
2130         ok(0, "not enough parameters: %d\n", argc);
2131         return;
2132     }
2133 
2134     fd=atoi(args[3]);
2135     i=close(fd);
2136     ok(!i, "unable to close %d: %d\n", fd, errno);
2137 
2138     fd=atoi(args[4]);
2139 
2140     for (i=0; i<N_TEST_MESSAGES; i++) {
2141        nwritten=write(fd, pipe_string, strlen(pipe_string));
2142        ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
2143        /* let other process wake up so they can show off their "keep reading until EOF" behavior */
2144        if (i < N_TEST_MESSAGES-1)
2145            Sleep(100);
2146     }
2147 
2148     i=close(fd);
2149     ok(!i, "unable to close %d: %d\n", fd, errno);
2150 }
2151 
test_pipes(const char * selfname)2152 static void test_pipes(const char* selfname)
2153 {
2154     int pipes[2];
2155     char str_fdr[12], str_fdw[12];
2156     FILE* file;
2157     const char* arg_v[6];
2158     char buf[4096];
2159     char expected[4096];
2160     int r;
2161     int i;
2162 
2163     /* Test reading from a pipe with read() */
2164     if (_pipe(pipes, 1024, O_BINARY) < 0)
2165     {
2166         ok(0, "pipe failed with errno %d\n", errno);
2167         return;
2168     }
2169 
2170     arg_v[0] = get_base_name(selfname);
2171     arg_v[1] = "tests/file.c";
2172     arg_v[2] = "pipes";
2173     arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
2174     arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
2175     arg_v[5] = NULL;
2176     proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
2177     i=close(pipes[1]);
2178     ok(!i, "unable to close %d: %d\n", pipes[1], errno);
2179 
2180     for (i=0; i<N_TEST_MESSAGES; i++) {
2181        r=read(pipes[0], buf, sizeof(buf)-1);
2182        ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
2183        if (r > 0)
2184            buf[r]='\0';
2185        ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
2186    }
2187 
2188     r=read(pipes[0], buf, sizeof(buf)-1);
2189     ok(r == 0, "expected to read 0 bytes, got %d\n", r);
2190     i=close(pipes[0]);
2191     ok(!i, "unable to close %d: %d\n", pipes[0], errno);
2192 
2193     /* Test reading from a pipe with fread() */
2194     if (_pipe(pipes, 1024, O_BINARY) < 0)
2195     {
2196         ok(0, "pipe failed with errno %d\n", errno);
2197         return;
2198     }
2199 
2200     arg_v[1] = "tests/file.c";
2201     arg_v[2] = "pipes";
2202     arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
2203     arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
2204     arg_v[5] = NULL;
2205     proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
2206     i=close(pipes[1]);
2207     ok(!i, "unable to close %d: %d\n", pipes[1], errno);
2208     file=fdopen(pipes[0], "r");
2209 
2210     /* In blocking mode, fread will keep calling read() until it gets
2211      * enough bytes, or EOF, even on Unix.  (If this were a Unix terminal
2212      * in cooked mode instead of a pipe, it would also stop on EOL.)
2213      */
2214     expected[0] = 0;
2215     for (i=0; i<N_TEST_MESSAGES; i++)
2216        strcat(expected, pipe_string);
2217     r=fread(buf, 1, sizeof(buf)-1, file);
2218     ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
2219     if (r > 0)
2220        buf[r]='\0';
2221     ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
2222 
2223     /* Let child close the file before we read, so we can sense EOF reliably */
2224     Sleep(100);
2225     r=fread(buf, 1, sizeof(buf)-1, file);
2226     ok(r == 0, "fread() returned %d instead of 0\n", r);
2227     ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
2228     ok(feof(file), "feof() is false!\n");
2229 
2230     i=fclose(file);
2231     ok(!i, "unable to close the pipe: %d\n", errno);
2232 
2233     /* test \r handling when it's the last character read */
2234     if (_pipe(pipes, 1024, O_BINARY) < 0)
2235     {
2236         ok(0, "pipe failed with errno %d\n", errno);
2237         return;
2238     }
2239     r = write(pipes[1], "\r\n\rab\r\n", 7);
2240     ok(r == 7, "write returned %d, errno = %d\n", r, errno);
2241     setmode(pipes[0], O_TEXT);
2242     r = read(pipes[0], buf, 1);
2243     ok(r == 1, "read returned %d, expected 1\n", r);
2244     ok(buf[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf[0]);
2245     r = read(pipes[0], buf, 1);
2246     ok(r == 1, "read returned %d, expected 1\n", r);
2247     ok(buf[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf[0]);
2248     r = read(pipes[0], buf, 1);
2249     ok(r == 1, "read returned %d, expected 1\n", r);
2250     ok(buf[0] == 'a', "buf[0] = %x, expected 'a'\n", buf[0]);
2251     r = read(pipes[0], buf, 2);
2252     ok(r == 2, "read returned %d, expected 1\n", r);
2253     ok(buf[0] == 'b', "buf[0] = %x, expected 'b'\n", buf[0]);
2254     ok(buf[1] == '\n', "buf[1] = %x, expected '\\n'\n", buf[1]);
2255 
2256     if (p_fopen_s)
2257     {
2258         /* test utf16 read with insufficient data */
2259         r = write(pipes[1], "a\0b", 3);
2260         ok(r == 3, "write returned %d, errno = %d\n", r, errno);
2261         buf[2] = 'z';
2262         buf[3] = 'z';
2263         setmode(pipes[0], _O_WTEXT);
2264         r = read(pipes[0], buf, 4);
2265         ok(r == 2, "read returned %d, expected 2\n", r);
2266         ok(!memcmp(buf, "a\0bz", 4), "read returned incorrect data\n");
2267         r = write(pipes[1], "\0", 1);
2268         ok(r == 1, "write returned %d, errno = %d\n", r, errno);
2269         buf[0] = 'z';
2270         buf[1] = 'z';
2271         r = read(pipes[0], buf, 2);
2272         ok(r == 0, "read returned %d, expected 0\n", r);
2273         ok(!memcmp(buf, "\0z", 2), "read returned incorrect data\n");
2274     }
2275     else
2276     {
2277         win_skip("unicode mode tests on pipe\n");
2278     }
2279 
2280     close(pipes[1]);
2281     close(pipes[0]);
2282 }
2283 
test_unlink(void)2284 static void test_unlink(void)
2285 {
2286     FILE* file;
2287     ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
2288     file = fopen("test_unlink\\empty", "w");
2289     ok(file != NULL, "unable to create test file\n");
2290     if(file)
2291       fclose(file);
2292     ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
2293     unlink("test_unlink\\empty");
2294     rmdir("test_unlink");
2295 }
2296 
test_dup2(void)2297 static void test_dup2(void)
2298 {
2299     ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
2300 }
2301 
test_stdin(void)2302 static void test_stdin(void)
2303 {
2304     HANDLE stdinh = GetStdHandle(STD_INPUT_HANDLE);
2305     int stdin_dup, fd;
2306     HANDLE h;
2307     DWORD r;
2308 
2309     stdin_dup = _dup(STDIN_FILENO);
2310     ok(stdin_dup != -1, "_dup(STDIN_FILENO) failed\n");
2311 
2312     ok(stdinh == (HANDLE)_get_osfhandle(STDIN_FILENO),
2313             "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n");
2314 
2315     r = SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE);
2316     ok(r == TRUE, "SetStdHandle returned %x, expected TRUE\n", r);
2317     h = GetStdHandle(STD_INPUT_HANDLE);
2318     ok(h == INVALID_HANDLE_VALUE, "h = %p\n", h);
2319 
2320     close(STDIN_FILENO);
2321     h = GetStdHandle(STD_INPUT_HANDLE);
2322     ok(h == NULL, "h != NULL\n");
2323 
2324     fd = open("stdin.tst", O_WRONLY | O_CREAT, _S_IREAD |_S_IWRITE);
2325     ok(fd != -1, "open failed\n");
2326     ok(fd == STDIN_FILENO, "fd = %d, expected STDIN_FILENO\n", fd);
2327     h = GetStdHandle(STD_INPUT_HANDLE);
2328     ok(h != NULL, "h == NULL\n");
2329     close(fd);
2330     unlink("stdin.tst");
2331 
2332     r = _dup2(stdin_dup, STDIN_FILENO);
2333     ok(r != -1, "_dup2 failed\n");
2334     h = GetStdHandle(STD_INPUT_HANDLE);
2335     ok(h != NULL, "h == NULL\n");
2336 }
2337 
test_mktemp(void)2338 static void test_mktemp(void)
2339 {
2340     char buf[16];
2341 
2342     strcpy(buf, "a");
2343     ok(!_mktemp(buf), "_mktemp(\"a\") != NULL\n");
2344 
2345     strcpy(buf, "testXXXXX");
2346     ok(!_mktemp(buf), "_mktemp(\"testXXXXX\") != NULL\n");
2347 
2348     strcpy(buf, "testXXXXXX");
2349     ok(_mktemp(buf) != NULL, "_mktemp(\"testXXXXXX\") == NULL\n");
2350 
2351     strcpy(buf, "testXXXXXXa");
2352     ok(!_mktemp(buf), "_mktemp(\"testXXXXXXa\") != NULL\n");
2353 
2354     strcpy(buf, "**XXXXXX");
2355     ok(_mktemp(buf) != NULL, "_mktemp(\"**XXXXXX\") == NULL\n");
2356 }
2357 
test__open_osfhandle(void)2358 static void test__open_osfhandle(void)
2359 {
2360     ioinfo *info;
2361     HANDLE h, tmp;
2362     int fd;
2363 
2364     errno = 0xdeadbeef;
2365     fd = _open_osfhandle((intptr_t)INVALID_HANDLE_VALUE, 0);
2366     ok(fd == -1, "_open_osfhandle returned %d\n", fd);
2367     ok(errno == EBADF, "errno = %d\n", errno);
2368 
2369     h = CreateFileA("open_osfhandle.tst", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2370     fd = _open_osfhandle((intptr_t)h, 0);
2371     ok(fd > 0, "_open_osfhandle returned %d (%d)\n", fd, errno);
2372     info = &__pioinfo[fd/MSVCRT_FD_BLOCK_SIZE][fd%MSVCRT_FD_BLOCK_SIZE];
2373     ok(info->handle == h, "info->handle = %p, expected %p\n", info->handle, h);
2374     ok(info->wxflag == 1, "info->wxflag = %x, expected 1\n", info->wxflag);
2375     close(fd);
2376     ok(info->handle == INVALID_HANDLE_VALUE, "info->handle = %p, expected INVALID_HANDLE_VALUE\n", info->handle);
2377     ok(info->wxflag == 0, "info->wxflag = %x, expected 0\n", info->wxflag);
2378     DeleteFileA("open_osfhandle.tst");
2379 
2380     errno = 0xdeadbeef;
2381     fd = _open_osfhandle((intptr_t)h, 0);
2382     ok(fd == -1, "_open_osfhandle returned %d\n", fd);
2383     ok(errno == EBADF, "errno = %d\n", errno);
2384 
2385     ok(CreatePipe(&h, &tmp, NULL, 0), "CreatePipe failed\n");
2386     fd = _open_osfhandle((intptr_t)h, 0);
2387     ok(fd > 0, "_open_osfhandle returned %d (%d)\n", fd, errno);
2388     info = &__pioinfo[fd/MSVCRT_FD_BLOCK_SIZE][fd%MSVCRT_FD_BLOCK_SIZE];
2389     ok(info->handle == h, "info->handle = %p, expected %p\n", info->handle, h);
2390     ok(info->wxflag == 9, "info->wxflag = %x, expected 9\n", info->wxflag);
2391     close(fd);
2392     CloseHandle(tmp);
2393 }
2394 
test_write_flush_size(FILE * file,int bufsize)2395 static void test_write_flush_size(FILE *file, int bufsize)
2396 {
2397     char *inbuffer;
2398     char *outbuffer;
2399     int size, fd;
2400     fpos_t pos, pos2;
2401 
2402     fd = fileno(file);
2403     inbuffer = calloc(1, bufsize + 1);
2404     outbuffer = calloc(1, bufsize + 1);
2405     _snprintf(outbuffer, bufsize + 1, "0,1,2,3,4,5,6,7,8,9");
2406 
2407     for (size = bufsize + 1; size >= bufsize - 1; size--) {
2408         rewind(file);
2409         ok(file->_cnt == 0, "_cnt should be 0 after rewind, but is %d\n", file->_cnt);
2410         fwrite(outbuffer, 1, size, file);
2411         /* lseek() below intentionally redirects the write in fflush() to detect
2412          * if fwrite() has already flushed the whole buffer or not.
2413          */
2414         lseek(fd, 1, SEEK_SET);
2415         fflush(file);
2416         ok(file->_cnt == 0, "_cnt should be 0 after fflush, but is %d\n", file->_cnt);
2417         fseek(file, 0, SEEK_SET);
2418         ok(fread(inbuffer, 1, bufsize, file) == bufsize, "read failed\n");
2419         if (size == bufsize)
2420             ok(memcmp(outbuffer, inbuffer, bufsize) == 0, "missing flush by %d byte write\n", size);
2421         else
2422             ok(memcmp(outbuffer, inbuffer, bufsize) != 0, "unexpected flush by %d byte write\n", size);
2423     }
2424     rewind(file);
2425     fwrite(outbuffer, 1, bufsize / 2, file);
2426     fwrite(outbuffer + bufsize / 2, 1, bufsize / 2, file);
2427     lseek(fd, 1, SEEK_SET);
2428     fflush(file);
2429     fseek(file, 0, SEEK_SET);
2430     ok(fread(inbuffer, 1, bufsize, file) == bufsize, "read failed\n");
2431     ok(memcmp(outbuffer, inbuffer, bufsize) != 0, "unexpected flush by %d/2 byte double write\n", bufsize);
2432 
2433     ok(!fseek(file, -1, SEEK_END), "fseek failed\n");
2434     ok(!fgetpos(file, &pos), "fgetpos failed\n");
2435     ok(fread(inbuffer, 1, 1, file) == 1, "fread failed\n");
2436     ok(file->_flag & _IOREAD, "file->_flag = %x\n", file->_flag);
2437     ok(!file->_cnt, "file->_cnt = %d\n", file->_cnt);
2438     ok(file->_ptr != file->_base, "file->_ptr == file->_base\n");
2439     ok(fwrite(outbuffer, 1, bufsize, file), "fwrite failed\n");
2440     ok(file->_flag & _IOREAD, "file->_flag = %x\n", file->_flag);
2441     ok(!file->_cnt, "file->_cnt = %d\n", file->_cnt);
2442     ok(file->_ptr == file->_base, "file->_ptr == file->_base\n");
2443     ok(!fgetpos(file, &pos2), "fgetpos failed\n");
2444     ok(pos+bufsize+1 == pos2, "pos = %d (%d)\n", (int)pos, (int)pos2);
2445     free(inbuffer);
2446     free(outbuffer);
2447 }
2448 
test_write_flush(void)2449 static void test_write_flush(void)
2450 {
2451     char iobuf[1024];
2452     char *tempf;
2453     FILE *file;
2454 
2455     tempf = _tempnam(".","wne");
2456     file = fopen(tempf, "wb+");
2457     ok(file != NULL, "unable to create test file\n");
2458     iobuf[0] = 0;
2459     ok(file->_bufsiz == 4096, "incorrect default buffer size: %d\n", file->_bufsiz);
2460     test_write_flush_size(file, file->_bufsiz);
2461     setvbuf(file, iobuf, _IOFBF, sizeof(iobuf));
2462     test_write_flush_size(file, sizeof(iobuf));
2463     fclose(file);
2464     unlink(tempf);
2465     free(tempf);
2466 }
2467 
test_close(void)2468 static void test_close(void)
2469 {
2470     ioinfo *stdout_info, stdout_copy, *stderr_info, stderr_copy;
2471     int fd1, fd2, ret1, ret2, ret3, ret4;
2472     DWORD flags;
2473     HANDLE h;
2474 
2475     /* test close on fds that use the same handle */
2476     h = CreateFileA("fdopen.tst", GENERIC_READ|GENERIC_WRITE,
2477             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
2478     ok(h != INVALID_HANDLE_VALUE, "error opening fdopen.tst file\n");
2479 
2480     fd1 = _open_osfhandle((intptr_t)h, 0);
2481     ok(fd1 != -1, "_open_osfhandle failed (%d)\n", errno);
2482     fd2 = _open_osfhandle((intptr_t)h, 0);
2483     ok(fd2 != -1, "_open_osfhandle failed (%d)\n", errno);
2484     ok(fd1 != fd2, "fd1 == fd2\n");
2485 
2486     ok((HANDLE)_get_osfhandle(fd1) == h, "handles mismatch (%p != %p)\n",
2487             (HANDLE)_get_osfhandle(fd1), h);
2488     ok((HANDLE)_get_osfhandle(fd2) == h, "handles mismatch (%p != %p)\n",
2489             (HANDLE)_get_osfhandle(fd2), h);
2490     ret1 = close(fd1);
2491     ok(!ret1, "close(fd1) failed (%d)\n", errno);
2492     ok(!GetHandleInformation(h, &flags), "GetHandleInformation succeeded\n");
2493     ok(close(fd2), "close(fd2) succeeded\n");
2494 
2495     /* test close on already closed fd */
2496     errno = 0xdeadbeef;
2497     ret1 = close(fd1);
2498     ok(ret1 == -1, "close(fd1) succeeded\n");
2499     ok(errno == 9, "errno = %d\n", errno);
2500 
2501     /* test close on stdout and stderr that use the same handle */
2502     h = CreateFileA("fdopen.tst", GENERIC_READ|GENERIC_WRITE,
2503             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
2504     ok(h != INVALID_HANDLE_VALUE, "error opening fdopen.tst file\n");
2505 
2506     /* tests output will not be visible from now on */
2507     stdout_info = &__pioinfo[STDOUT_FILENO/MSVCRT_FD_BLOCK_SIZE][STDOUT_FILENO%MSVCRT_FD_BLOCK_SIZE];
2508     stderr_info = &__pioinfo[STDERR_FILENO/MSVCRT_FD_BLOCK_SIZE][STDERR_FILENO%MSVCRT_FD_BLOCK_SIZE];
2509     stdout_copy = *stdout_info;
2510     stderr_copy = *stderr_info;
2511     stdout_info->handle = h;
2512     stderr_info->handle = h;
2513 
2514     ret1 = close(STDOUT_FILENO);
2515     ret2 = GetHandleInformation(h, &flags);
2516     ret3 = close(STDERR_FILENO);
2517     ret4 = GetHandleInformation(h, &flags);
2518 
2519     *stdout_info = stdout_copy;
2520     *stderr_info = stderr_copy;
2521     SetStdHandle(STD_OUTPUT_HANDLE, stdout_info->handle);
2522     SetStdHandle(STD_ERROR_HANDLE, stderr_info->handle);
2523     /* stdout and stderr restored */
2524 
2525     ok(!ret1, "close(STDOUT_FILENO) failed\n");
2526     ok(ret2, "GetHandleInformation failed\n");
2527     ok(!ret3, "close(STDERR_FILENO) failed\n");
2528     ok(!ret4, "GetHandleInformation succeeded\n");
2529 
2530     DeleteFileA( "fdopen.tst" );
2531 }
2532 
test__creat(void)2533 static void test__creat(void)
2534 {
2535     int fd, pos, count, readonly, old_fmode = 0, have_fmode;
2536     char buf[6], testdata[4] = {'a', '\n', 'b', '\n'};
2537 
2538     have_fmode = p__get_fmode && p__set_fmode && !p__get_fmode(&old_fmode);
2539     if (!have_fmode)
2540         win_skip("_fmode can't be set, skipping mode tests\n");
2541 
2542     if (have_fmode)
2543         p__set_fmode(_O_TEXT);
2544     fd = _creat("_creat.tst", 0);
2545     ok(fd > 0, "_creat failed\n");
2546     _write(fd, testdata, 4);
2547     if (have_fmode) {
2548         pos = _tell(fd);
2549         ok(pos == 6, "expected pos 6 (text mode), got %d\n", pos);
2550     }
2551     ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n");
2552     count = _read(fd, buf, 6);
2553     ok(count == 4, "_read returned %d, expected 4\n", count);
2554     count = count > 0 ? count > 4 ? 4 : count : 0;
2555     ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n");
2556     _close(fd);
2557     readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY;
2558     ok(readonly, "expected read-only file\n");
2559     SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL);
2560     DeleteFileA("_creat.tst");
2561 
2562     if (have_fmode)
2563         p__set_fmode(_O_BINARY);
2564     fd = _creat("_creat.tst", _S_IREAD | _S_IWRITE);
2565     ok(fd > 0, "_creat failed\n");
2566     _write(fd, testdata, 4);
2567     if (have_fmode) {
2568         pos = _tell(fd);
2569         ok(pos == 4, "expected pos 4 (binary mode), got %d\n", pos);
2570     }
2571     ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n");
2572     count = _read(fd, buf, 6);
2573     ok(count == 4, "_read returned %d, expected 4\n", count);
2574     count = count > 0 ? count > 4 ? 4 : count : 0;
2575     ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n");
2576     _close(fd);
2577     readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY;
2578     ok(!readonly, "expected rw file\n");
2579     SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL);
2580     DeleteFileA("_creat.tst");
2581 
2582     if (have_fmode)
2583         p__set_fmode(old_fmode);
2584 }
2585 
START_TEST(file)2586 START_TEST(file)
2587 {
2588     int arg_c;
2589     char** arg_v;
2590 
2591     init();
2592 
2593     arg_c = winetest_get_mainargs( &arg_v );
2594 
2595     /* testing low-level I/O */
2596     if (arg_c >= 3)
2597     {
2598         if (strcmp(arg_v[2], "inherit") == 0)
2599             test_file_inherit_child(arg_v[3]);
2600         else if (strcmp(arg_v[2], "inherit_no") == 0)
2601             test_file_inherit_child_no(arg_v[3]);
2602         else if (strcmp(arg_v[2], "pipes") == 0)
2603             test_pipes_child(arg_c, arg_v);
2604         else if (strcmp(arg_v[2], "stdin") == 0)
2605             test_invalid_stdin_child();
2606         else
2607             ok(0, "invalid argument '%s'\n", arg_v[2]);
2608         return;
2609     }
2610     test_dup2();
2611     test_file_inherit(arg_v[0]);
2612     test_invalid_stdin(arg_v[0]);
2613     test_file_write_read();
2614     test_chsize();
2615     test_stat();
2616     test_unlink();
2617 
2618     /* testing stream I/O */
2619     test_filbuf();
2620     test_fdopen();
2621     test_fopen_fclose_fcloseall();
2622     test_fopen_s();
2623     test__wfopen_s();
2624     test_setmode();
2625     test_fileops();
2626     test_asciimode();
2627     test_asciimode2();
2628     test_filemodeT();
2629     test_readmode(FALSE); /* binary mode */
2630     test_readmode(TRUE);  /* ascii mode */
2631     test_readboundary();
2632     test_fgetc();
2633     test_fputc();
2634     test_flsbuf();
2635     test_fflush();
2636     test_fgetwc();
2637     /* \x83\xa9 is double byte character, \xe0\x7f is not (undefined). */
2638     test_fgetwc_locale("AB\x83\xa9\xe0\x7f", "Japanese_Japan.932", 932);
2639     /* \x83 is U+0192 */
2640     test_fgetwc_locale("AB\x83\xa9", "English", 1252);
2641     /* \x83 is U+0083 */
2642     test_fgetwc_locale("AB\x83\xa9", "C", 0);
2643     test_fgetwc_unicode();
2644     test_fputwc();
2645     test_ctrlz();
2646     test_file_put_get();
2647     test_tmpnam();
2648     test_get_osfhandle();
2649     test_setmaxstdio();
2650     test_pipes(arg_v[0]);
2651     test_stdin();
2652     test_mktemp();
2653     test__open_osfhandle();
2654     test_write_flush();
2655     test_close();
2656     test__creat();
2657 
2658     /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
2659      * file contains lines in the correct order
2660      */
2661     WaitForMultipleObjects(ARRAY_SIZE(proc_handles), proc_handles, TRUE, 5000);
2662 }
2663