blob: 1fde0805dc10a4fa62a9aca041b7196919552937 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 * proc01.c - Tests Linux /proc file reading.
3 *
4 * Copyright (C) 2001 Stephane Fillod <f4cfe@free.fr>
subrata_modakcf473b72009-02-05 11:15:57 +00005 * Copyright (c) 2008, 2009 Red Hat, Inc.
subrata_modak4bb656a2009-02-26 12:02:09 +00006 *
plars865695b2001-08-27 22:15:12 +00007 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
subrata_modak4bb656a2009-02-26 12:02:09 +000010 *
plars865695b2001-08-27 22:15:12 +000011 * This program is distributed in the hope that it would be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
subrata_modak4bb656a2009-02-26 12:02:09 +000014 *
plars865695b2001-08-27 22:15:12 +000015 * Further, this software is distributed without any warranty that it is
16 * free of the rightful claim of any third person regarding infringement
17 * or the like. Any license provided herein, whether implied or
18 * otherwise, applies only to this software file. Patent licenses, if
19 * any, provided herein do not apply to combinations of this program with
20 * other software, or any other product whatsoever.
subrata_modak4bb656a2009-02-26 12:02:09 +000021 *
plars865695b2001-08-27 22:15:12 +000022 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080023 * with this program; if not, write the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
subrata_modak4bb656a2009-02-26 12:02:09 +000025 *
plars865695b2001-08-27 22:15:12 +000026 */
27
subrata_modakafe343d2009-02-05 11:20:49 +000028#include "config.h"
29
subrata_modakda124b92009-10-13 14:00:45 +000030#include <errno.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <limits.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <dirent.h>
plars865695b2001-08-27 22:15:12 +000038#include <unistd.h>
39#include <fcntl.h>
subrata_modakca317e62007-11-13 09:25:05 +000040#include <fnmatch.h>
plars865695b2001-08-27 22:15:12 +000041
subrata_modak190c7ad2009-03-16 08:27:20 +000042#ifdef HAVE_LIBSELINUX_DEVEL
subrata_modakafe343d2009-02-05 11:20:49 +000043#include <selinux/selinux.h>
44#endif
45
plars865695b2001-08-27 22:15:12 +000046#include "test.h"
plars865695b2001-08-27 22:15:12 +000047
plars865695b2001-08-27 22:15:12 +000048#define MAX_BUFF_SIZE 65536
subrata_modak8a9ecb72008-05-26 06:09:19 +000049#define MAX_FUNC_NAME 256
plars865695b2001-08-27 22:15:12 +000050
vapier10fe5d82006-08-21 07:16:54 +000051char *TCID = "proc01";
52int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000053
Wanlong Gao14259b02012-11-12 14:02:46 +080054static int opt_verbose;
55static int opt_procpath;
56static char *opt_procpathstr;
57static int opt_buffsize;
58static int opt_readirq;
59static char *opt_buffsizestr;
60static int opt_maxmbytes;
61static char *opt_maxmbytesstr;
plars865695b2001-08-27 22:15:12 +000062
Wanlong Gao14259b02012-11-12 14:02:46 +080063static char *procpath = "/proc";
64static const char selfpath[] = "/proc/self";
65size_t buffsize = 1024;
Jan Stancek37bfeec2012-07-31 10:33:13 +020066static long long maxbytes;
plars865695b2001-08-27 22:15:12 +000067
Wanlong Gao14259b02012-11-12 14:02:46 +080068unsigned long long total_read;
69unsigned int total_obj;
plars865695b2001-08-27 22:15:12 +000070
subrata_modakda124b92009-10-13 14:00:45 +000071struct mapping {
72 char func[MAX_FUNC_NAME];
73 char file[PATH_MAX];
74 int err;
subrata_modak8a9ecb72008-05-26 06:09:19 +000075};
subrata_modakda124b92009-10-13 14:00:45 +000076
subrata_modak8a9ecb72008-05-26 06:09:19 +000077/* Those are known failures for 2.6.18 baremetal kernel and Xen dom0
78 kernel on i686, x86_64, ia64, ppc64 and s390x. In addition, It looks
79 like if SELinux is disabled, the test may still fail on some other
80 entries. */
Wanlong Gao14259b02012-11-12 14:02:46 +080081static const struct mapping known_issues[] = {
82 {"open", "/proc/acpi/event", EBUSY},
83 {"open", "/proc/sal/cpe/data", EBUSY},
84 {"open", "/proc/sal/cmc/data", EBUSY},
85 {"open", "/proc/sal/init/data", EBUSY},
86 {"open", "/proc/sal/mca/data", EBUSY},
Jan Stancekcbf52ab2013-09-05 09:22:31 +020087 {"open", "/proc/fs/nfsd/pool_stats", ENODEV},
Wanlong Gao14259b02012-11-12 14:02:46 +080088 {"read", "/proc/acpi/event", EAGAIN},
89 {"read", "/proc/kmsg", EAGAIN},
90 {"read", "/proc/sal/cpe/event", EAGAIN},
91 {"read", "/proc/sal/cmc/event", EAGAIN},
92 {"read", "/proc/sal/init/event", EAGAIN},
93 {"read", "/proc/sal/mca/event", EAGAIN},
Cyril Hrubisdb7f4352013-04-24 16:54:22 +020094 {"read", "/proc/xen/privcmd", EIO},
Wanlong Gao14259b02012-11-12 14:02:46 +080095 {"read", "/proc/xen/privcmd", EINVAL},
96 {"read", "/proc/self/mem", EIO},
97 {"read", "/proc/self/task/[0-9]*/mem", EIO},
98 {"read", "/proc/self/attr/*", EINVAL},
99 {"read", "/proc/self/task/[0-9]*/attr/*", EINVAL},
100 {"read", "/proc/self/ns/*", EINVAL},
101 {"read", "/proc/self/task/[0-9]*/ns/*", EINVAL},
102 {"read", "/proc/ppc64/rtas/error_log", EINVAL},
103 {"read", "/proc/powerpc/rtas/error_log", EINVAL},
104 {"read", "/proc/fs/nfsd/unlock_filesystem", EINVAL},
105 {"read", "/proc/fs/nfsd/unlock_ip", EINVAL},
106 {"read", "/proc/fs/nfsd/filehandle", EINVAL},
107 {"read", "/proc/fs/nfsd/.getfs", EINVAL},
108 {"read", "/proc/fs/nfsd/.getfd", EINVAL},
Jan Stancek80ab8bc2013-08-27 11:05:32 +0200109 {"read", "/proc/self/net/rpc/use-gss-proxy", EAGAIN},
Wanlong Gao14259b02012-11-12 14:02:46 +0800110 {"", "", 0}
yaberauneyada963562009-11-15 08:21:45 +0000111};
subrata_modak8a9ecb72008-05-26 06:09:19 +0000112
subrata_modak190c7ad2009-03-16 08:27:20 +0000113/*
114 * If a particular LSM is enabled, it is expected that some entries can
115 * be read successfully. Otherwise, those entries will retrun some
116 * failures listed above. Here to add any LSM specific entries.
117 */
118
119/*
120 * Test macro to indicate that SELinux libraries and headers are
121 * installed.
122 */
123#ifdef HAVE_LIBSELINUX_DEVEL
Wanlong Gao14259b02012-11-12 14:02:46 +0800124static const char lsm_should_work[][PATH_MAX] = {
125 "/proc/self/attr/*",
126 "/proc/self/task/[0-9]*/attr/*",
127 ""
yaberauneyada963562009-11-15 08:21:45 +0000128};
Wanlong Gao14259b02012-11-12 14:02:46 +0800129
subrata_modak190c7ad2009-03-16 08:27:20 +0000130/* Place holder for none of LSM is detected. */
subrata_modak13a21422009-02-16 05:44:04 +0000131#else
Wanlong Gao14259b02012-11-12 14:02:46 +0800132static const char lsm_should_work[][PATH_MAX] = {
133 ""
yaberauneyada963562009-11-15 08:21:45 +0000134};
subrata_modak13a21422009-02-16 05:44:04 +0000135#endif
subrata_modakafe343d2009-02-05 11:20:49 +0000136
subrata_modak8a9ecb72008-05-26 06:09:19 +0000137/* Known files that does not honor O_NONBLOCK, so they will hang
subrata_modakafe343d2009-02-05 11:20:49 +0000138 the test while being read. */
Wanlong Gao14259b02012-11-12 14:02:46 +0800139static const char error_nonblock[][PATH_MAX] = {
140 "/proc/xen/xenbus",
141 ""
yaberauneyada963562009-11-15 08:21:45 +0000142};
subrata_modak8a9ecb72008-05-26 06:09:19 +0000143
Garrett Cooper2c282152010-12-16 00:55:50 -0800144/*
yaberauneyada963562009-11-15 08:21:45 +0000145 * Verify expected failures, and then let the test to continue.
146 *
147 * Return 0 when a problem errno is found.
148 * Return 1 when a known issue is found.
149 *
subrata_modak190c7ad2009-03-16 08:27:20 +0000150 */
Wanlong Gao14259b02012-11-12 14:02:46 +0800151static int found_errno(const char *syscall, const char *obj, int tmperr)
subrata_modak8a9ecb72008-05-26 06:09:19 +0000152{
yaberauneyada963562009-11-15 08:21:45 +0000153 int i;
subrata_modak8a9ecb72008-05-26 06:09:19 +0000154
yaberauneyada963562009-11-15 08:21:45 +0000155 /* Should not see any error for certain entries if a LSM is enabled. */
156#ifdef HAVE_LIBSELINUX_DEVEL
157 if (is_selinux_enabled()) {
158 for (i = 0; lsm_should_work[i][0] != '\0'; i++) {
159 if (!strcmp(obj, lsm_should_work[i]) ||
160 !fnmatch(lsm_should_work[i], obj, FNM_PATHNAME)) {
161 return 0;
162 }
163 }
164 }
165#endif
166 for (i = 0; known_issues[i].err != 0; i++) {
167 if (tmperr == known_issues[i].err &&
168 (!strcmp(obj, known_issues[i].file) ||
169 !fnmatch(known_issues[i].file, obj, FNM_PATHNAME)) &&
170 !strcmp(syscall, known_issues[i].func)) {
171 /* Using strcmp / fnmatch could have messed up the
172 * errno value. */
173 errno = tmperr;
174 tst_resm(TINFO | TERRNO, "%s: known issue", obj);
175 return 1;
176 }
177 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800178 return 0;
subrata_modak8a9ecb72008-05-26 06:09:19 +0000179}
180
Wanlong Gao14259b02012-11-12 14:02:46 +0800181static void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000182{
vapier10fe5d82006-08-21 07:16:54 +0000183 tst_rmdir();
plars865695b2001-08-27 22:15:12 +0000184}
185
Wanlong Gao14259b02012-11-12 14:02:46 +0800186static void setup(void)
plars865695b2001-08-27 22:15:12 +0000187{
vapier10fe5d82006-08-21 07:16:54 +0000188 tst_sig(FORK, DEF_HANDLER, cleanup);
vapier10fe5d82006-08-21 07:16:54 +0000189 TEST_PAUSE;
vapier10fe5d82006-08-21 07:16:54 +0000190 tst_tmpdir();
plars865695b2001-08-27 22:15:12 +0000191}
192
Wanlong Gao14259b02012-11-12 14:02:46 +0800193void help(void)
plars865695b2001-08-27 22:15:12 +0000194{
vapier10fe5d82006-08-21 07:16:54 +0000195 printf(" -b x read byte count\n");
Jan Stancek37bfeec2012-07-31 10:33:13 +0200196 printf(" -m x max megabytes to read from single file\n");
yaberauneyada963562009-11-15 08:21:45 +0000197 printf(" -q read .../irq/... entries\n");
vapier10fe5d82006-08-21 07:16:54 +0000198 printf(" -r x proc pathname\n");
199 printf(" -v verbose mode\n");
plars865695b2001-08-27 22:15:12 +0000200}
201
202/*
203 * add the -m option whose parameter is the
204 * pages that should be mapped.
205 */
Wanlong Gao14259b02012-11-12 14:02:46 +0800206static option_t options[] = {
207 {"b:", &opt_buffsize, &opt_buffsizestr},
208 {"m:", &opt_maxmbytes, &opt_maxmbytesstr},
209 {"q", &opt_readirq, NULL},
210 {"r:", &opt_procpath, &opt_procpathstr},
211 {"v", &opt_verbose, NULL},
212 {NULL, NULL, NULL}
plars865695b2001-08-27 22:15:12 +0000213};
214
plars865695b2001-08-27 22:15:12 +0000215/*
subrata_modak4bb656a2009-02-26 12:02:09 +0000216 * NB: this function is recursive
plars865695b2001-08-27 22:15:12 +0000217 * returns 0 if no error encountered, otherwise number of errors (objs)
218 *
yaberauneyada963562009-11-15 08:21:45 +0000219 * REM: Funny enough, while developing this function (actually replacing
plars865695b2001-08-27 22:15:12 +0000220 * streamed fopen by standard open), I hit a real /proc bug.
221 * On a 2.2.13-SuSE kernel, "cat /proc/tty/driver/serial" would fail
222 * with EFAULT, while "cat /proc/tty/driver/serial > somefile" wouldn't.
223 * Okay, this might be due to a slight serial misconfiguration, but still.
224 * Analysis with strace showed up the difference was on the count size
225 * of read (1024 bytes vs 4096 bytes). So I tested further..
subrata_modak4bb656a2009-02-26 12:02:09 +0000226 * read count of 512 bytes adds /proc/tty/drivers to the list
227 * of broken proc files, while 64 bytes reads removes
yaberauneyada963562009-11-15 08:21:45 +0000228 * /proc/tty/driver/serial from the list. Interesting, isn't it?
plars865695b2001-08-27 22:15:12 +0000229 * Now, there's a -b option to this test, so you can try your luck. --SF
230 *
231 * It's more fun to run this test it as root, as all the files will be accessible!
232 * (however, be careful, there might be some bufferoverflow holes..)
233 * reading proc files might be also a good kernel latency killer.
234 */
Wanlong Gao14259b02012-11-12 14:02:46 +0800235static long readproc(const char *obj)
plars865695b2001-08-27 22:15:12 +0000236{
yaberauneyada963562009-11-15 08:21:45 +0000237 DIR *dir = NULL; /* pointer to a directory */
vapier10fe5d82006-08-21 07:16:54 +0000238 struct dirent *dir_ent; /* pointer to directory entries */
239 char dirobj[PATH_MAX]; /* object inside directory to modify */
240 struct stat statbuf; /* used to hold stat information */
subrata_modak8a9ecb72008-05-26 06:09:19 +0000241 int fd, tmperr, i;
vapier10fe5d82006-08-21 07:16:54 +0000242 ssize_t nread;
243 static char buf[MAX_BUFF_SIZE]; /* static kills reentrancy, but we don't care about the contents */
Jan Stancek37bfeec2012-07-31 10:33:13 +0200244 unsigned long long file_total_read = 0;
plars865695b2001-08-27 22:15:12 +0000245
vapier10fe5d82006-08-21 07:16:54 +0000246 /* Determine the file type */
247 if (lstat(obj, &statbuf) < 0) {
yaberauneyada963562009-11-15 08:21:45 +0000248
vapier10fe5d82006-08-21 07:16:54 +0000249 /* permission denied is not considered as error */
250 if (errno != EACCES) {
yaberauneyada963562009-11-15 08:21:45 +0000251 tst_resm(TFAIL | TERRNO, "%s: lstat", obj);
vapier10fe5d82006-08-21 07:16:54 +0000252 return 1;
plars865695b2001-08-27 22:15:12 +0000253 }
254 return 0;
yaberauneyada963562009-11-15 08:21:45 +0000255
plars865695b2001-08-27 22:15:12 +0000256 }
257
yaberauneyada963562009-11-15 08:21:45 +0000258 /* Prevent loops, but read /proc/self. */
subrata_modakca317e62007-11-13 09:25:05 +0000259 if (S_ISLNK(statbuf.st_mode) && strcmp(obj, selfpath))
vapier10fe5d82006-08-21 07:16:54 +0000260 return 0;
261
262 total_obj++;
263
264 /* Take appropriate action, depending on the file type */
subrata_modakca317e62007-11-13 09:25:05 +0000265 if (S_ISDIR(statbuf.st_mode) || !strcmp(obj, selfpath)) {
yaberauneyada963562009-11-15 08:21:45 +0000266
vapier10fe5d82006-08-21 07:16:54 +0000267 /* object is a directory */
268
yaberauneyada963562009-11-15 08:21:45 +0000269 /*
270 * Skip over the /proc/irq directory, unless the user
271 * requested that we read the directory because it could
272 * map to a broken driver which effectively `hangs' the
273 * test.
274 */
yaberauneyaf0ff0022009-11-24 06:37:15 +0000275 if (!opt_readirq && !strcmp("/proc/irq", obj)) {
yaberauneyada963562009-11-15 08:21:45 +0000276 return 0;
Wanlong Gao14259b02012-11-12 14:02:46 +0800277 /* Open the directory to get access to what is in it */
yaberauneyada963562009-11-15 08:21:45 +0000278 } else if ((dir = opendir(obj)) == NULL) {
vapier10fe5d82006-08-21 07:16:54 +0000279 if (errno != EACCES) {
Wanlong Gao14259b02012-11-12 14:02:46 +0800280 tst_resm(TFAIL | TERRNO, "%s: opendir", obj);
vapier10fe5d82006-08-21 07:16:54 +0000281 return 1;
plars865695b2001-08-27 22:15:12 +0000282 }
plars865695b2001-08-27 22:15:12 +0000283 return 0;
yaberauneyada963562009-11-15 08:21:45 +0000284 } else {
285
286 long ret_val = 0;
287
288 /* Loop through the entries in the directory */
289 for (dir_ent = (struct dirent *)readdir(dir);
290 dir_ent != NULL;
291 dir_ent = (struct dirent *)readdir(dir)) {
292
293 /* Ignore ".", "..", "kcore", and
294 * "/proc/<pid>" (unless this is our
295 * starting point as directed by the
296 * user).
297 */
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800298 if (strcmp(dir_ent->d_name, ".") &&
Wanlong Gao14259b02012-11-12 14:02:46 +0800299 strcmp(dir_ent->d_name, "..") &&
300 strcmp(dir_ent->d_name, "kcore") &&
301 (fnmatch("[0-9]*", dir_ent->d_name,
302 FNM_PATHNAME) ||
303 strcmp(obj, procpath))) {
yaberauneyada963562009-11-15 08:21:45 +0000304
305 if (opt_verbose) {
306 fprintf(stderr, "%s\n",
307 dir_ent->d_name);
308 }
309
310 /* Recursively call this routine to test the
311 * current entry */
312 snprintf(dirobj, PATH_MAX,
Wanlong Gao14259b02012-11-12 14:02:46 +0800313 "%s/%s", obj, dir_ent->d_name);
yaberauneyada963562009-11-15 08:21:45 +0000314 ret_val += readproc(dirobj);
315
316 }
317
318 }
319
320 /* Close the directory */
321 if (dir)
Wanlong Gao14259b02012-11-12 14:02:46 +0800322 (void)closedir(dir);
yaberauneyada963562009-11-15 08:21:45 +0000323
324 return ret_val;
325
plars865695b2001-08-27 22:15:12 +0000326 }
vapier10fe5d82006-08-21 07:16:54 +0000327
vapier10fe5d82006-08-21 07:16:54 +0000328 } else { /* if it's not a dir, read it! */
329
330 if (!S_ISREG(statbuf.st_mode))
331 return 0;
332
yaberauneyada963562009-11-15 08:21:45 +0000333#ifdef DEBUG
334 fprintf(stderr, "%s", obj);
335#endif
subrata_modak8a9ecb72008-05-26 06:09:19 +0000336
yaberauneyada963562009-11-15 08:21:45 +0000337 /* is O_NONBLOCK enough to escape from FIFO's ? */
Wanlong Gao14259b02012-11-12 14:02:46 +0800338 fd = open(obj, O_RDONLY | O_NONBLOCK);
339 if (fd < 0) {
yaberauneyada963562009-11-15 08:21:45 +0000340 tmperr = errno;
341
342 if (!found_errno("open", obj, tmperr)) {
343
344 errno = tmperr;
345
346 if (errno != EACCES) {
347 tst_resm(TFAIL | TERRNO,
Wanlong Gao14259b02012-11-12 14:02:46 +0800348 "%s: open failed", obj);
yaberauneyada963562009-11-15 08:21:45 +0000349 return 1;
350 }
351
vapier10fe5d82006-08-21 07:16:54 +0000352 }
353 return 0;
yaberauneyada963562009-11-15 08:21:45 +0000354
355 }
356
Wanlong Gao14259b02012-11-12 14:02:46 +0800357 /* Skip write-only files. */
358 if ((statbuf.st_mode & S_IRUSR) == 0 &&
yaberauneyada963562009-11-15 08:21:45 +0000359 (statbuf.st_mode & S_IWUSR) != 0) {
360 tst_resm(TINFO, "%s: is write-only.", obj);
361 return 0;
vapier10fe5d82006-08-21 07:16:54 +0000362 }
363
yaberauneyada963562009-11-15 08:21:45 +0000364 /* Skip files does not honor O_NONBLOCK. */
365 for (i = 0; error_nonblock[i][0] != '\0'; i++) {
366 if (!strcmp(obj, error_nonblock[i])) {
Wanlong Gao14259b02012-11-12 14:02:46 +0800367 tst_resm(TWARN, "%s: does not honor "
368 "O_NONBLOCK", obj);
vapier10fe5d82006-08-21 07:16:54 +0000369 return 0;
370 }
yaberauneyada963562009-11-15 08:21:45 +0000371 }
372
Jan Stancek37bfeec2012-07-31 10:33:13 +0200373 file_total_read = 0;
yaberauneyada963562009-11-15 08:21:45 +0000374 do {
375
376 nread = read(fd, buf, buffsize);
377
378 if (nread < 0) {
379
Wanlong Gao14259b02012-11-12 14:02:46 +0800380 tmperr = errno;
381 (void)close(fd);
yaberauneyada963562009-11-15 08:21:45 +0000382
383 /* ignore no perm (not root) and no
384 * process (terminated) errors */
Wanlong Gao14259b02012-11-12 14:02:46 +0800385 if (!found_errno("read", obj, tmperr)) {
yaberauneyada963562009-11-15 08:21:45 +0000386
387 errno = tmperr;
388
Wanlong Gao14259b02012-11-12 14:02:46 +0800389 if (errno != EACCES && errno != ESRCH) {
yaberauneyada963562009-11-15 08:21:45 +0000390 tst_resm(TFAIL | TERRNO,
Wanlong Gao14259b02012-11-12 14:02:46 +0800391 "read failed: "
392 "%s", obj);
yaberauneyada963562009-11-15 08:21:45 +0000393 return 1;
394 }
395 return 0;
396
Wanlong Gao14259b02012-11-12 14:02:46 +0800397 }
yaberauneyada963562009-11-15 08:21:45 +0000398
Jan Stancek37bfeec2012-07-31 10:33:13 +0200399 } else
400 file_total_read += nread;
yaberauneyada963562009-11-15 08:21:45 +0000401
vapier10fe5d82006-08-21 07:16:54 +0000402 if (opt_verbose) {
403#ifdef DEBUG
yaberauneyada963562009-11-15 08:21:45 +0000404 fprintf(stderr, "%ld", nread);
vapier10fe5d82006-08-21 07:16:54 +0000405#endif
subrata_modak2f4de1d2008-05-26 06:10:16 +0000406 fprintf(stderr, ".");
vapier10fe5d82006-08-21 07:16:54 +0000407 }
408
Jan Stancek37bfeec2012-07-31 10:33:13 +0200409 if ((maxbytes > 0) && (file_total_read > maxbytes)) {
410 tst_resm(TINFO, "%s: reached maxmbytes (-m)",
Wanlong Gao14259b02012-11-12 14:02:46 +0800411 obj);
Jan Stancek37bfeec2012-07-31 10:33:13 +0200412 break;
413 }
yaberauneyada963562009-11-15 08:21:45 +0000414 } while (0 < nread);
Jan Stancek37bfeec2012-07-31 10:33:13 +0200415 total_read += file_total_read;
yaberauneyada963562009-11-15 08:21:45 +0000416
vapier10fe5d82006-08-21 07:16:54 +0000417 if (opt_verbose)
yaberauneyada963562009-11-15 08:21:45 +0000418 fprintf(stderr, "\n");
419
420 if (0 <= fd)
Wanlong Gao14259b02012-11-12 14:02:46 +0800421 (void)close(fd);
yaberauneyada963562009-11-15 08:21:45 +0000422
plars865695b2001-08-27 22:15:12 +0000423 }
plars865695b2001-08-27 22:15:12 +0000424
yaberauneyada963562009-11-15 08:21:45 +0000425 /* It's better to assume success by default rather than failure. */
plars865695b2001-08-27 22:15:12 +0000426 return 0;
yaberauneyada963562009-11-15 08:21:45 +0000427
plars865695b2001-08-27 22:15:12 +0000428}
429
vapier10fe5d82006-08-21 07:16:54 +0000430int main(int argc, char *argv[])
431{
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200432 const char *msg;
vapier10fe5d82006-08-21 07:16:54 +0000433 int lc;
434
Wanlong Gao14259b02012-11-12 14:02:46 +0800435 msg = parse_opts(argc, argv, options, help);
436 if (msg != NULL)
vapier10fe5d82006-08-21 07:16:54 +0000437 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
438
439 if (opt_buffsize) {
440 size_t bs;
441 bs = atoi(opt_buffsizestr);
442 if (bs <= MAX_BUFF_SIZE)
443 buffsize = bs;
444 else
445 tst_brkm(TBROK, cleanup,
446 "Invalid arg for -b (max: %u): %s",
447 MAX_BUFF_SIZE, opt_buffsizestr);
448 }
Jan Stancek37bfeec2012-07-31 10:33:13 +0200449 if (opt_maxmbytes)
450 maxbytes = atoi(opt_maxmbytesstr) * 1024 * 1024;
vapier10fe5d82006-08-21 07:16:54 +0000451
yaberauneyada963562009-11-15 08:21:45 +0000452 if (opt_procpath)
vapier10fe5d82006-08-21 07:16:54 +0000453 procpath = opt_procpathstr;
vapier10fe5d82006-08-21 07:16:54 +0000454
455 setup();
456
457 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800458 tst_count = 0;
vapier10fe5d82006-08-21 07:16:54 +0000459
460 TEST(readproc(procpath));
461
462 if (TEST_RETURN != 0) {
subrata_modakda124b92009-10-13 14:00:45 +0000463 tst_resm(TFAIL, "readproc() failed with %ld errors.",
vapier10fe5d82006-08-21 07:16:54 +0000464 TEST_RETURN);
465 } else {
466 tst_resm(TPASS, "readproc() completed successfully, "
yaberauneyada963562009-11-15 08:21:45 +0000467 "total read: %llu bytes, %u objs", total_read,
vapier10fe5d82006-08-21 07:16:54 +0000468 total_obj);
469 }
470 }
471
472 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800473 tst_exit();
Jan Stancek37bfeec2012-07-31 10:33:13 +0200474}