Imported Upstream version 1.0.25
[platform/upstream/libsndfile.git] / tests / win32_test.c
1 /*
2 ** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 of the License, or
7 ** (at your option) any later version.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 ** GNU General Public License for more details.
13 **
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "sfconfig.h"
20 #include "sndfile.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <assert.h>
25
26 #if HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29
30 #if (HAVE_DECL_S_IRGRP == 0)
31 #include <sf_unistd.h>
32 #endif
33
34 #include <string.h>
35 #include <fcntl.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39
40 #define SIGNED_SIZEOF(x)        ((int) sizeof (x))
41
42 /* EMX is OS/2. */
43 #if defined (__CYGWIN__) || defined (__EMX__)
44
45         #define         LSEEK   lseek
46         #define         FSTAT   fstat
47
48         typedef         struct stat                     STATBUF ;
49         typedef         off_t                           INT64 ;
50
51         static char dir_cmd [] = "ls -l" ;
52
53 #elif (defined (WIN32) || defined (_WIN32))
54
55         #define         LSEEK   _lseeki64
56         #define         FSTAT   _fstati64
57
58         typedef         struct _stati64         STATBUF ;
59         typedef         __int64                         INT64 ;
60
61         static char dir_cmd [] = "dir" ;
62
63 #else
64
65         #define         LSEEK   lseek
66         #define         FSTAT   fstat
67
68         typedef         struct stat             STATBUF ;
69         typedef         sf_count_t              INT64 ;
70
71         #define         O_BINARY        0
72         static char dir_cmd [] = "ls -l" ;
73
74 #endif
75
76 static void show_fstat_error (void) ;
77 static void show_lseek_error (void) ;
78 static void show_stat_fstat_error (void) ;
79 static void write_to_closed_file (void) ;
80
81 int
82 main (void)
83 {
84         puts ("\n\n\n\n"
85                 "This program shows up errors in the Win32 implementation of\n"
86                 "a couple of POSIX API functions on some versions of windoze.\n"
87                 "It can also be compiled on Linux (which works correctly) and\n"
88                 "other OSes just to provide a sanity check.\n"
89                 ) ;
90
91         show_fstat_error () ;
92         show_lseek_error () ;
93         show_stat_fstat_error () ;
94         write_to_closed_file () ;
95
96         puts ("\n\n") ;
97
98         return 0 ;
99 } /* main */
100
101 static void
102 show_fstat_error (void)
103 {       static const char *filename = "fstat.dat" ;
104         static char data [256] ;
105
106         STATBUF         statbuf ;
107         int fd, mode, flags ;
108
109         if (sizeof (statbuf.st_size) != sizeof (INT64))
110         {       printf ("\n\nLine %d: Error, sizeof (statbuf.st_size) != 8.\n\n", __LINE__) ;
111                 return ;
112                 } ;
113
114         puts ("\n64 bit fstat() test.\n--------------------") ;
115
116         printf ("0) Create a file, write %d bytes and close it.\n", SIGNED_SIZEOF (data)) ;
117         mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
118         flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
119         if ((fd = open (filename, mode, flags)) < 0)
120         {       printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
121                 return ;
122                 } ;
123         assert (write (fd, data, sizeof (data)) > 0) ;
124         close (fd) ;
125
126         printf ("1) Re-open file in read/write mode and write another %d bytes at the end.\n", SIGNED_SIZEOF (data)) ;
127         mode = O_RDWR | O_BINARY ;
128         flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
129         if ((fd = open (filename, mode, flags)) < 0)
130         {       printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
131                 return ;
132                 } ;
133         LSEEK (fd, 0, SEEK_END) ;
134         assert (write (fd, data, sizeof (data)) > 0) ;
135
136         printf ("2) Now use system (\"%s %s\") to show the file length.\n\n", dir_cmd, filename) ;
137
138         /* Would use snprintf, but thats not really available on windows. */
139         memset (data, 0, sizeof (data)) ;
140         strncpy (data, dir_cmd, sizeof (data) - 1) ;
141         strncat (data, " ", sizeof (data) - 1 - strlen (data)) ;
142         strncat (data, filename, sizeof (data) - 1 - strlen (data)) ;
143
144         assert (system (data) >= 0) ;
145         puts ("") ;
146
147         printf ("3) Now use fstat() to get the file length.\n") ;
148         if (FSTAT (fd, &statbuf) != 0)
149         {       printf ("\n\nLine %d: fstat() returned error : %s\n", __LINE__, strerror (errno)) ;
150                 return ;
151                 } ;
152
153         printf ("4) According to fstat(), the file length is %ld, ", (long) statbuf.st_size) ;
154
155         close (fd) ;
156
157         if (statbuf.st_size != 2 * sizeof (data))
158                 printf ("but thats just plain ***WRONG***.\n\n") ;
159         else
160         {       printf ("which is correct.\n\n") ;
161                 unlink (filename) ;
162                 } ;
163
164 } /* show_fstat_error */
165
166 static void
167 show_lseek_error (void)
168 {       static const char *filename = "fstat.dat" ;
169         static char data [256] ;
170
171         INT64   retval ;
172         int fd, mode, flags ;
173
174         puts ("\n64 bit lseek() test.\n--------------------") ;
175
176         printf ("0) Create a file, write %d bytes and close it.\n", SIGNED_SIZEOF (data)) ;
177         mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
178         flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
179         if ((fd = open (filename, mode, flags)) < 0)
180         {       printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
181                 return ;
182                 } ;
183         assert (write (fd, data, sizeof (data)) > 0) ;
184         close (fd) ;
185
186         printf ("1) Re-open file in read/write mode and write another %d bytes at the end.\n", SIGNED_SIZEOF (data)) ;
187         mode = O_RDWR | O_BINARY ;
188         flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
189         if ((fd = open (filename, mode, flags)) < 0)
190         {       printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
191                 return ;
192                 } ;
193
194         LSEEK (fd, 0, SEEK_END) ;
195         assert (write (fd, data, sizeof (data)) > 0) ;
196
197         printf ("2) Now use system (\"%s %s\") to show the file length.\n\n", dir_cmd, filename) ;
198
199         /* Would use snprintf, but thats not really available on windows. */
200         memset (data, 0, sizeof (data)) ;
201         strncpy (data, dir_cmd, sizeof (data) - 1) ;
202         strncat (data, " ", sizeof (data) - 1 - strlen (data)) ;
203         strncat (data, filename, sizeof (data) - 1 - strlen (data)) ;
204
205         assert (system (data) >= 0) ;
206         puts ("") ;
207
208         printf ("3) Now use lseek() to go to the end of the file.\n") ;
209         retval = LSEEK (fd, 0, SEEK_END) ;
210
211         printf ("4) We are now at position %ld, ", (long) retval) ;
212
213         close (fd) ;
214
215         if (retval != 2 * sizeof (data))
216                 printf ("but thats just plain ***WRONG***.\n\n") ;
217         else
218         {       printf ("which is correct.\n\n") ;
219                 unlink (filename) ;
220                 } ;
221
222 } /* show_lseek_error */
223
224 static void
225 show_stat_fstat_error (void)
226 {       static const char *filename = "stat_fstat.dat" ;
227         static char data [256] ;
228
229         int fd, mode, flags ;
230         int stat_size, fstat_size ;
231         struct stat buf ;
232
233         /* Known to fail on WinXP. */
234         puts ("\nstat/fstat test.\n----------------") ;
235
236         printf ("0) Create a file and write %d bytes.\n", SIGNED_SIZEOF (data)) ;
237
238         mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
239         flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
240         if ((fd = open (filename, mode, flags)) < 0)
241         {       printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
242                 return ;
243                 } ;
244
245         assert (write (fd, data, sizeof (data)) > 0) ;
246
247         printf ("1) Now call stat and fstat on the file and retreive the file lengths.\n") ;
248
249         if (stat (filename, &buf) != 0)
250         {       printf ("\n\nLine %d: stat() failed : %s\n\n", __LINE__, strerror (errno)) ;
251                 goto error_exit ;
252                 } ;
253         stat_size = buf.st_size ;
254
255         if (fstat (fd, &buf) != 0)
256         {       printf ("\n\nLine %d: fstat() failed : %s\n\n", __LINE__, strerror (errno)) ;
257                 goto error_exit ;
258                 } ;
259         fstat_size = buf.st_size ;
260
261         printf ("2) Size returned by stat and fstat is %d and %d, ", stat_size, fstat_size) ;
262
263
264         if (stat_size == 0 || stat_size != fstat_size)
265                 printf ("but thats just plain ***WRONG***.\n\n") ;
266         else
267                 printf ("which is correct.\n\n") ;
268
269 error_exit :
270
271         close (fd) ;
272         unlink (filename) ;
273
274         return ;
275 } /* show_stat_fstat_error */
276
277
278 static void
279 write_to_closed_file (void)
280 {       const char * filename = "closed_write_test.txt" ;
281         struct stat buf ;
282         FILE * file ;
283         int             fd ;
284
285         puts ("\nWrite to closed file test.\n--------------------------") ;
286
287         printf ("0) First we open file for write using fopen().\n") ;
288         if ((file = fopen (filename, "w")) == NULL)
289         {       printf ("\n\nLine %d: fopen() failed : %s\n\n", __LINE__, strerror (errno)) ;
290                 return ;
291                 } ;
292
293         printf ("1) Now we grab the file descriptor fileno().\n") ;
294         fd = fileno (file) ;
295
296         printf ("2) Write some text via the file descriptor.\n") ;
297         assert (write (fd, "a\n", 2) > 0) ;
298
299         printf ("3) Now we close the file using fclose().\n") ;
300         fclose (file) ;
301
302         stat (filename, &buf) ;
303         printf ("   File size is %d bytes.\n", (int) buf.st_size) ;
304
305         printf ("4) Now write more data to the file descriptor which should fail.\n") ;
306         if (write (fd, "b\n", 2) < 0)
307                 printf ("5) Good, write returned an error code as it should have.\n") ;
308         else
309         {       printf ("5) Attempting to write to a closed file should have failed but didn't! *** WRONG ***\n") ;
310
311                 stat (filename, &buf) ;
312                 printf ("   File size is %d bytes.\n", (int) buf.st_size) ;
313                 } ;
314
315         unlink (filename) ;
316
317         return ;
318 } /* write_to_closed_file */