Whamcloud - gitweb
LU-10657 utils: fd leak in mirror_split()
[fs/lustre-release.git] / lustre / tests / openunlink.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  */
26 /*
27  * This file is part of Lustre, http://www.lustre.org/
28  * Lustre is a trademark of Sun Microsystems, Inc.
29  */
30
31 #include <stdio.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <errno.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39
40 #define T1 "write data before unlink\n"
41 #define T2 "write data after unlink\n"
42 char buf[128];
43
44 int main(int argc, char **argv)
45 {
46         char *fname, *fname2;
47         struct stat st;
48         int fd, rc;
49
50         if (argc < 2 || argc > 3) {
51                 fprintf(stderr, "usage: %s filename [filename2]\n", argv[0]);
52                 exit(1);
53         }
54
55         fname = argv[1];
56         if (argc == 3)
57                 fname2 = argv[2];
58         else
59                 fname2 = argv[1];
60
61         fprintf(stderr, "opening\n");
62         fd = open(fname, O_RDWR | O_TRUNC | O_CREAT, 0644);
63         if (fd == -1) {
64                 fprintf(stderr, "open (normal) %s\n", strerror(errno));
65                 exit(1);
66         }
67
68         fprintf(stderr, "writing\n");
69         rc = write(fd, T1, strlen(T1) + 1);
70         if (rc != strlen(T1) + 1) {
71                 fprintf(stderr, "write (normal) %s (rc %d)\n",
72                         strerror(errno), rc);
73                 exit(1);
74         }
75
76         if (argc == 3) {
77                 fprintf (stderr, "unlinking %s\n", fname2);
78                 rc = unlink(fname2);
79                 if (rc) {
80                         fprintf(stderr, "unlink %s\n", strerror(errno));
81                         exit(1);
82                 }
83         } else {
84                 printf("unlink %s and press enter\n", fname);
85                 getc(stdin);
86         }
87
88         fprintf(stderr, "accessing (1)\n");
89         if (access(fname, F_OK) == 0) {
90                 fprintf(stderr, "%s still exists\n", fname);
91                 exit(1);
92         }
93
94         fprintf(stderr, "seeking (1)\n");
95         rc = lseek(fd, 0, SEEK_SET);
96         if (rc) {
97                 fprintf(stderr, "seek %s\n", strerror(errno));
98                 exit(1);
99         }
100
101         fprintf(stderr, "accessing (2)\n");
102         if (access(fname, F_OK) == 0) {
103                 fprintf(stderr, "%s still exists\n", fname);
104                 exit(1);
105         }
106
107         fprintf(stderr, "fstat...\n");
108         rc = fstat(fd, &st);
109         if (rc) {
110                 fprintf(stderr, "fstat (unlink) %s\n", strerror(errno));
111                 exit(1);
112         }
113         if (st.st_nlink != 0)
114                 fprintf(stderr, "st_nlink = %d\n", (int)st.st_nlink);
115
116         fprintf(stderr, "reading\n");
117         rc = read(fd, buf, strlen(T1) + 1);
118         if (rc != strlen(T1) + 1) {
119                 fprintf(stderr, "read (unlink) %s (rc %d)\n",
120                         strerror(errno), rc);
121                 exit(1);
122         }
123
124         fprintf(stderr, "comparing data\n");
125         if (memcmp(buf, T1, strlen(T1) + 1) ) {
126                 fprintf(stderr, "FAILURE: read wrong data after unlink\n");
127                 exit(1);
128         }
129
130         fprintf(stderr, "truncating\n");
131         rc = ftruncate(fd, 0);
132         if (rc) {
133                 fprintf(stderr, "truncate (unlink) %s\n", strerror(errno));
134                 exit(1);
135         }
136
137         fprintf(stderr, "seeking (2)\n");
138         rc = lseek(fd, 0, SEEK_SET);
139         if (rc) {
140                 fprintf(stderr, "seek (after unlink trunc) %s\n",
141                         strerror(errno));
142                 exit(1);
143         }
144
145         fprintf(stderr, "writing again\n");
146         rc = write(fd, T2, strlen(T2) + 1);
147         if (rc != strlen(T2) + 1) {
148                 fprintf(stderr, "write (after unlink trunc) %s (rc %d)\n",
149                         strerror(errno), rc);
150                 exit(1);
151         }
152
153         fprintf(stderr, "seeking (3)\n");
154         rc = lseek(fd, 0, SEEK_SET);
155         if (rc) {
156                 fprintf(stderr, "seek (before unlink read) %s\n",
157                         strerror(errno));
158                 exit(1);
159         }
160
161         fprintf(stderr, "reading again\n");
162         rc = read(fd, buf, strlen(T2) + 1);
163         if (rc != strlen(T2) + 1) {
164                 fprintf(stderr, "read (after unlink rewrite) %s (rc %d)\n",
165                         strerror(errno), rc);
166                 exit(1);
167         }
168
169         fprintf(stderr, "comparing data again\n");
170         if (memcmp(buf, T2, strlen(T2) + 1)) {
171                 fprintf(stderr, "FAILURE: read wrong data after rewrite\n");
172                 exit(1);
173         }
174
175         fprintf(stderr, "closing\n");
176         rc = close(fd);
177         if (rc) {
178                 fprintf(stderr, "close (unlink) %s\n", strerror(errno));
179                 exit(1);
180         }
181
182         fprintf(stderr, "SUCCESS - goto beer\n");
183         return 0;
184 }