blob: 811af8d53039e441a7b4fff8bc8bfaf0f095fc1e [file] [log] [blame]
subrata_modak498546d2007-12-05 08:44:26 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 * Copyright (c) Red Hat Inc., 2007
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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 * the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
subrata_modak498546d2007-12-05 08:44:26 +000019 */
20
21/*
22 * NAME
23 * sendfile07.c
24 *
25 * DESCRIPTION
26 * Testcase to test that sendfile(2) system call returns EAGAIN
27 * when passing blocked out_fd. Here out_fd is opend with O_NONBLOCK.
28 *
29 * ALGORITHM
30 * 1. Make sockets with socketpair(&p). Use p[1] as out_fd.
31 * 2. Set O_NONBLOCK flag of out_fd on.
32 * 3. Write much datum to out_fd till write() returns EAGAIN.
33 * 4. Call sendfile with out_fd, and expect EAGAIN.
34 *
35 * USAGE: <for command-line>
36 * sendfile07 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
37 * where, -c n : Run n copies concurrently.
38 * -e : Turn on errno logging.
39 * -i n : Execute test n times.
40 * -I x : Execute test for x seconds.
41 * -P x : Pause for x seconds between iterations.
42 * -t : Turn on syscall timing.
43 *
44 * HISTORY
45 * 12/2007 Copyed from sendfile03.c by Masatake YAMATO
46 *
47 * RESTRICTIONS
48 * NONE
49 */
50
51#include <stdio.h>
52#include <errno.h>
53#include <fcntl.h>
54#include <sys/sendfile.h>
55#include <sys/socket.h>
subrata_modak498546d2007-12-05 08:44:26 +000056#include "test.h"
57
58#ifndef OFF_T
59#define OFF_T off_t
60#endif /* Not def: OFF_T */
61
subrata_modak585950c2008-08-20 10:55:19 +000062TCID_DEFINE(sendfile07);
subrata_modak498546d2007-12-05 08:44:26 +000063int TST_TOTAL = 1;
subrata_modak498546d2007-12-05 08:44:26 +000064
65int in_fd, out_fd = 0, ignored_fd = 0;
66char in_file[100];
67
68/* To make out_fd overflow, write much chars
69 to out_fd. MAX_FILL_DATA_LENGTH defines the `much'. */
70#define MAX_FILL_DATA_LENGTH 0xFFFFFFF
71
72void cleanup(void);
73void setup(void);
74
75int main(int ac, char **av)
76{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020077 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020078 const char *msg; /* parse_opts() return message */
subrata_modak498546d2007-12-05 08:44:26 +000079
Garrett Cooper45e285d2010-11-22 12:19:25 -080080 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -080081 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Wanlong Gao354ebb42012-12-07 10:10:04 +080082 }
subrata_modak498546d2007-12-05 08:44:26 +000083
84 setup();
85
86 /*
87 * The following loop checks looping state if -c option given
88 */
89 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +080090 tst_count = 0;
subrata_modak498546d2007-12-05 08:44:26 +000091
92 TEST(sendfile(out_fd, in_fd, NULL, 1));
93
94 if (TEST_RETURN != -1) {
95 tst_resm(TFAIL, "call succeeded unexpectedly");
96 continue;
97 }
98
subrata_modak498546d2007-12-05 08:44:26 +000099 if (TEST_ERRNO != EAGAIN) {
100 tst_resm(TFAIL, "sendfile returned unexpected "
101 "errno, expected: %d, got: %d",
102 EAGAIN, TEST_ERRNO);
103 } else {
104 tst_resm(TPASS, "sendfile() returned %d : %s",
105 TEST_ERRNO, strerror(TEST_ERRNO));
106 }
107 }
108
109 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800110 tst_exit();
subrata_modak498546d2007-12-05 08:44:26 +0000111
subrata_modak498546d2007-12-05 08:44:26 +0000112}
113
114/*
115 * setup() - performs all ONE TIME setup for this test.
116 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400117void setup(void)
subrata_modak498546d2007-12-05 08:44:26 +0000118{
119 char buf[100];
subrata_modak56207ce2009-03-23 13:35:39 +0000120 int p[2];
121 int i, r;
subrata_modakbdbaec52009-02-26 12:14:51 +0000122
subrata_modak498546d2007-12-05 08:44:26 +0000123 tst_sig(NOFORK, DEF_HANDLER, cleanup);
124
subrata_modak498546d2007-12-05 08:44:26 +0000125 TEST_PAUSE;
126
127 /* make a temporary directory and cd to it */
128 tst_tmpdir();
129
130 sprintf(in_file, "in.%d", getpid());
131 if ((in_fd = creat(in_file, 00700)) < 0) {
132 tst_brkm(TBROK, cleanup, "creat failed in setup, errno: %d",
133 errno);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800134 }
subrata_modak498546d2007-12-05 08:44:26 +0000135 sprintf(buf, "abcdefghijklmnopqrstuvwxyz");
136 if (write(in_fd, buf, strlen(buf)) < 0) {
137 tst_brkm(TBROK, cleanup, "write failed, errno: %d", errno);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800138 }
subrata_modak498546d2007-12-05 08:44:26 +0000139 close(in_fd);
140 if ((in_fd = open(in_file, O_RDONLY)) < 0) {
141 tst_brkm(TBROK, cleanup, "open failed, errno: %d", errno);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800142 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000143
subrata_modak498546d2007-12-05 08:44:26 +0000144 /* Make fulfilled out_fd. */
145 if (socketpair(PF_UNIX, SOCK_DGRAM, 0, p) < 0) {
146 tst_brkm(TBROK, cleanup, "socketpair failed, errno: %d", errno);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800147 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000148
subrata_modak498546d2007-12-05 08:44:26 +0000149 /* Don't close.
subrata_modak56207ce2009-03-23 13:35:39 +0000150 You cannot write nothing on out_fd if ignored_fd is closed. */
subrata_modak498546d2007-12-05 08:44:26 +0000151 ignored_fd = p[0];
152 out_fd = p[1];
subrata_modak56207ce2009-03-23 13:35:39 +0000153 if (fcntl(out_fd, F_SETFL, O_WRONLY | O_NONBLOCK) < 0) {
subrata_modak498546d2007-12-05 08:44:26 +0000154 tst_brkm(TBROK, cleanup, "fcntl failed, errno: %d", errno);
155 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000156
subrata_modak498546d2007-12-05 08:44:26 +0000157 i = MAX_FILL_DATA_LENGTH;
158 while (i > 0) {
159 r = write(out_fd, buf, 1);
160 if (r < 0) {
161 if (errno == EAGAIN) {
162 break;
163 } else {
subrata_modak4bb656a2009-02-26 12:02:09 +0000164 tst_brkm(TBROK, cleanup,
165 "write failed to fill out_fd, errno: %d",
subrata_modak498546d2007-12-05 08:44:26 +0000166 errno);
167 }
168 }
169 i--;
170 }
171 if (i == 0) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000172 tst_brkm(TBROK, cleanup,
173 "fail to fill out_fd, write %d bytes but EAGAIN it not returned.",
subrata_modak498546d2007-12-05 08:44:26 +0000174 MAX_FILL_DATA_LENGTH);
175 }
176}
177
178/*
179 * cleanup() - performs all ONE TIME cleanup for this test at
180 * completion or premature exit.
181 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400182void cleanup(void)
subrata_modak498546d2007-12-05 08:44:26 +0000183{
184 /*
185 * print timing stats if that option was specified.
186 * print errno log if that option was specified.
187 */
188 if (out_fd)
subrata_modak56207ce2009-03-23 13:35:39 +0000189 close(out_fd);
subrata_modak498546d2007-12-05 08:44:26 +0000190 if (ignored_fd)
subrata_modak56207ce2009-03-23 13:35:39 +0000191 close(ignored_fd);
subrata_modak498546d2007-12-05 08:44:26 +0000192 close(in_fd);
193
subrata_modak498546d2007-12-05 08:44:26 +0000194 /* delete the test directory created in setup() */
195 tst_rmdir();
196
Chris Dearmanec6edca2012-10-17 19:54:01 -0700197}