OSDN Git Service

4ba802949abfadd6746075dd6d97d47b31a4f98b
[pf3gnuchains/pf3gnuchains3x.git] / winsup / testsuite / winsup.api / ltp / truncate02.c
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2001
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19
20 /* 
21  * Test Name: truncate02
22  *
23  * Test Description:
24  *  Verify that, truncate(2) succeeds to truncate a file to a certain length,
25  *  but the attempt to read past the truncated length will fail.  
26  *
27  * Expected Result:
28  *  truncate(2) should return a value 0 and the attempt to read past the 
29  *  truncated length will fail. In case where the file before truncation was 
30  *  shorter, the bytes between the old and new should  be all zeroes.
31  *      
32  * Algorithm:
33  *  Setup:
34  *   Setup signal handling.
35  *   Create temporary directory.
36  *   Pause for SIGUSR1 if option specified.
37  *
38  *  Test:
39  *   Loop if the proper options are given.
40  *   Execute system call
41  *   Check return code, if system call failed (return=-1)
42  *      Log the errno and Issue a FAIL message.
43  *   Otherwise,
44  *      Verify the Functionality of system call 
45  *      if successful,
46  *              Issue Functionality-Pass message.
47  *      Otherwise,
48  *              Issue Functionality-Fail message.
49  *  Cleanup:
50  *   Print errno log and/or timing stats if options given
51  *   Delete the temporary directory created.
52  *
53  * Usage:  <for command-line>
54  *  truncate02 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
55  *      where,  -c n : Run n copies concurrently.
56  *              -e   : Turn on errno logging.
57  *              -f   : Turn off functionality Testing.
58  *              -i n : Execute test n times.
59  *              -I x : Execute test for x seconds.
60  *              -P x : Pause for x seconds between iterations.
61  *              -t   : Turn on syscall timing.
62  *
63  * History
64  *      07/2001 John George
65  *              -Ported
66  *
67  * Restrictions:
68  *  This test should be run by 'non-super-user' only.
69  *
70  */
71
72 #include <sys/types.h>
73 #include <sys/stat.h>
74 #include <sys/fcntl.h>
75 #include <errno.h>
76 #include <string.h>
77 #include <signal.h>
78
79 #include "test.h"
80 #include "usctest.h"
81
82 #define TESTFILE        "testfile"              /* file under test */
83 #define FILE_MODE       S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
84 #define BUF_SIZE        256                     /* buffer size */
85 #define FILE_SIZE       1024                    /* test file size */
86 #define TRUNC_LEN1      256                     /* truncation length */
87 #define TRUNC_LEN2      512                     /* truncation length */
88
89 const char *TCID="truncate02";  /* Test program identifier.    */
90 int TST_TOTAL=1;                /* Total number of test conditions */
91 extern int Tst_count;           /* Test Case counter for tst_* routines */
92 int fd;                         /* file descriptor of testfile */
93 char tst_buff[BUF_SIZE];        /* buffer to hold testfile contents */
94 int exp_enos[]={0};
95
96 void setup();                   /* setup function for the test */
97 void cleanup(void) __attribute__((noreturn));                   /* cleanup function for the test */
98
99 int
100 main(int ac, char **av)
101 {
102         struct stat stat_buf;   /* stat(2) struct contents */
103         int lc, i;              /* loop counter */
104         const char *msg;        /* message returned from parse_opts */
105         off_t file_length2;     /* test file length */
106         off_t file_length1;     /* test file length */
107         int rbytes;             /* bytes read from testfile */
108         int read_len = 0;       /* total no. of bytes read from testfile */
109         int err_flag = 0;       /* error indicator flag */
110     
111         /* Parse standard options given to run the test. */
112         msg = parse_opts(ac, av, (option_t *) NULL, NULL);
113         if (msg != (char *) NULL) {
114                 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
115                 tst_exit();
116         }
117
118         /* Perform global setup for test */
119         setup();
120
121         /* set the expected errnos... */
122         TEST_EXP_ENOS(exp_enos);
123
124         /* Check looping state if -i option given */
125         for (lc = 0; TEST_LOOPING(lc); lc++) {
126                 /* Reset Tst_count in case we are looping. */
127                 Tst_count = 0;
128
129                 /* 
130                  * Call truncate(2) to truncate a test file to a 
131                  * specified length (TRUNC_LEN1).
132                  */
133                 TEST(truncate(TESTFILE, TRUNC_LEN1));
134
135                 /* check return code of truncate(2) */
136                 if (TEST_RETURN == -1) {
137                         TEST_ERROR_LOG(TEST_ERRNO);
138                         tst_resm(TFAIL, \
139                                  "truncate(%s, %d) Failed, errno=%d : %s",
140                                  TESTFILE, TRUNC_LEN1, TEST_ERRNO,
141                                  strerror(TEST_ERRNO));
142                 } else {
143                         /*
144                          * Perform functional verification if test
145                          * executed without (-f) option.
146                          */
147                         if (STD_FUNCTIONAL_TEST) {
148                                 /*
149                                  * Get the testfile information using
150                                  * stat(2).
151                                  */
152                                 if (stat(TESTFILE, &stat_buf) < 0) {
153                                         tst_brkm(TFAIL, cleanup, "stat(2) of "
154                                                 "%s failed after 1st truncate, "
155                                                 "error:%d", TESTFILE, errno);
156                                         /*NOTREACHED*/
157                                 }
158                                 file_length1 = stat_buf.st_size;
159
160                                 /*
161                                  * Set the file pointer of testfile to the 
162                                  * beginning of the file.
163                                  */
164                                 if (lseek(fd, 0, SEEK_SET) < 0) {
165                                         tst_brkm(TFAIL, cleanup, "lseek(2) on "
166                                                 "%s failed after 1st truncate, "
167                                                 "error:%d", TESTFILE, errno);
168                                         /*NOTREACHED*/
169                                 }
170
171                                 /* Read the testfile from the beginning. */
172                                 while ((rbytes = read(fd, tst_buff, \
173                                                       sizeof(tst_buff))) > 0) {
174                                         read_len += rbytes;
175                                 }
176
177                                 /*
178                                  * Execute truncate(2) again to truncate
179                                  * testfile to a size TRUNC_LEN2.
180                                  */
181                                 TEST(truncate(TESTFILE, TRUNC_LEN2));
182
183                                 /* check return code of truncate(2) */
184                                 if (TEST_RETURN == -1) {
185                                         TEST_ERROR_LOG(TEST_ERRNO);
186                                         tst_resm(TFAIL, "truncate of %s to "
187                                                 "size %d Failed, errno=%d : %s",
188                                                 TESTFILE, TRUNC_LEN2,
189                                                 TEST_ERRNO,
190                                                 strerror(TEST_ERRNO));
191                                 }
192
193                                 /*
194                                  * Get the testfile information using
195                                  * stat(2)
196                                  */
197                                 if (stat(TESTFILE, &stat_buf) < 0) {
198                                         tst_brkm(TFAIL, cleanup, "stat(2) of "
199                                                 "%s failed after 2nd truncate, "
200                                                 "error:%d", TESTFILE, errno);
201                                         /*NOTREACHED*/
202                                 }
203                                 file_length2 = stat_buf.st_size;
204
205                                 /*
206                                  * Set the file pointer of testfile to the 
207                                  * offset TRUNC_LEN1 of testfile.
208                                  */
209                                 if (lseek(fd, TRUNC_LEN1, SEEK_SET) < 0) {
210                                         tst_brkm(TFAIL, cleanup, "lseek(2) on "
211                                                 "%s failed after 2nd truncate, "
212                                                 "error:%d", TESTFILE, errno);
213                                         /*NOTREACHED*/
214                                 }
215
216                                 /* Read the testfile contents till EOF */
217                                 while((rbytes = read(fd, tst_buff, \
218                                         sizeof(tst_buff))) > 0) {
219                                         for (i = 0; i < rbytes; i++) {
220                                                 if (tst_buff[i] != 0) {
221                                                         err_flag++;
222                                                 }
223                                         }
224                                 }
225
226                                 /*
227                                  * Check for expected size of testfile after
228                                  * issuing truncate(2) on it.
229                                  */
230                                 if ((file_length1 != TRUNC_LEN1) || \
231                                         (file_length2 != TRUNC_LEN2) || \
232                                         (read_len != TRUNC_LEN1) || \
233                                         (err_flag != 0)) {
234                                         tst_resm(TFAIL, "Functionality of "
235                                                 "truncate(2) on %s Failed",
236                                                  TESTFILE);
237                                 } else {
238                                         tst_resm(TPASS, \
239                                                 "Functionality of truncate(2) "
240                                                 "on %s successful", TESTFILE);
241                                 }
242                         } else {
243                                 tst_resm(TPASS, "%s call succeeded", TCID);
244                         }
245                 }
246                 Tst_count++;                    /* incr. TEST_LOOP counter */
247         }       /* End for TEST_LOOPING */
248
249         /* Call cleanup() to undo setup done for the test. */
250         cleanup();
251         /*NOTREACHED*/
252
253 }       /* End main */
254
255 /*
256  * void
257  * setup() - performs all ONE TIME setup for this test.
258  *  Create a temporary directory and change directory to it.
259  *  Create a test file under temporary directory and write some
260  *  data into it.
261  */
262 void 
263 setup()
264 {
265         int i;                  /* counter variable */
266         int wbytes;             /* bytes written to testfile */
267         int write_len = 0;      /* total no. of bytes written to testfile */
268
269         /* capture signals */
270         tst_sig(FORK, DEF_HANDLER, cleanup);
271
272         /* Pause if that option was specified
273          * TEST_PAUSE contains the code to fork the test with the -i option.
274          * You want to make sure you do this before you create your temporary
275          * directory.
276          */
277         TEST_PAUSE;
278
279         /* make a temp directory and cd to it */
280         tst_tmpdir();
281
282
283         /* Fill the test buffer with the known data */
284         for (i = 0; i < BUF_SIZE; i++) {
285                 tst_buff[i] = 'a';
286         }
287
288         /* Creat a testfile  and write some data into it */
289         if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
290                 tst_brkm(TBROK, cleanup,
291                          "open(%s, O_RDWR|O_CREAT, %o) Failed, errno=%d : %s",
292                          TESTFILE, FILE_MODE, errno, strerror(errno));
293                 /*NOTREACHED*/
294         }
295
296         /* Write to the file 1k data from the buffer */
297         while (write_len < FILE_SIZE) {
298                 if ((wbytes = write(fd, tst_buff, sizeof(tst_buff))) <= 0) {
299                         tst_brkm(TBROK, cleanup,
300                                  "write(2) on %s Failed, errno=%d : %s",
301                                  TESTFILE, errno, strerror(errno));
302                 } else {
303                         write_len += wbytes;
304                 }
305         }
306 }       /* End setup() */
307
308 /*
309  * void
310  * cleanup() - performs all ONE TIME cleanup for this test at
311  *             completion or premature exit.
312  *  Close the temporary file opened for reading/writing.
313  *  Remove the test directory and testfile created in the setup.
314  */
315 void 
316 cleanup()
317 {
318         /*
319          * print timing stats if that option was specified.
320          */
321         TEST_CLEANUP;
322
323         /* Close the testfile after writing data into it */
324         if (close(fd) == -1) {
325                 tst_brkm(TFAIL, NULL,
326                          "close(%s) Failed, errno=%d : %s",
327                          TESTFILE, errno, strerror(errno));
328         }
329
330         /* Remove tmp dir and all files in it */
331         tst_rmdir();
332
333         /* exit with return code appropriate for results */
334         tst_exit();
335 }       /* End cleanup() */