blob: 95ba7a6486d2ba6a2687b0cd9835becd9f5b7e65 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * NAME
22 * write04.c
23 *
24 * DESCRIPTION
25 * Testcase to check that write() sets errno to EAGAIN
26 *
27 * ALGORITHM
28 * Create a named pipe (fifo), open it in O_NONBLOCK mode, and
29 * attempt to write to it when it is full, write(2) should fail
30 * with EAGAIN.
31 *
32 * USAGE: <for command-line>
33 * write04 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
34 * where, -c n : Run n copies concurrently.
35 * -e : Turn on errno logging.
36 * -i n : Execute test n times.
37 * -I x : Execute test for x seconds.
38 * -P x : Pause for x seconds between iterations.
39 * -t : Turn on syscall timing.
40 *
robbiew4644c7e2002-04-26 14:33:32 +000041 * HISTORY
42 * ??/???? someone made this testcase but didn't add HISTORY
43 *
plars865695b2001-08-27 22:15:12 +000044 * RESTRICTIONS
45 * NONE
46 */
47
48#include <sys/stat.h>
49#include <fcntl.h>
50#include <signal.h>
51#include <setjmp.h>
52#include <errno.h>
robbiew4644c7e2002-04-26 14:33:32 +000053#include <string.h>
plars865695b2001-08-27 22:15:12 +000054#include "test.h"
plars865695b2001-08-27 22:15:12 +000055
robbiew4590c0d2005-10-04 16:16:23 +000056#define PIPE_SIZE_TEST getpagesize()
57
plars865695b2001-08-27 22:15:12 +000058void alarm_handler();
59void setup();
60void cleanup();
61
62char *TCID = "write04";
63int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000064
plars865695b2001-08-27 22:15:12 +000065char fifo[100] = "fifo";
66static sigjmp_buf jmp;
67int rfd, wfd;
68
robbiew6ee509b2003-04-01 20:28:41 +000069int main(int argc, char **argv)
plars865695b2001-08-27 22:15:12 +000070{
71 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020072 const char *msg;
plars865695b2001-08-27 22:15:12 +000073
74 struct stat buf;
75 int fail;
robbiew6ee509b2003-04-01 20:28:41 +000076 int cnt;
robbiew4590c0d2005-10-04 16:16:23 +000077 char wbuf[17 * PIPE_SIZE_TEST];
subrata_modak56207ce2009-03-23 13:35:39 +000078 struct sigaction sigptr; /* set up signal handler */
plars865695b2001-08-27 22:15:12 +000079
Wanlong Gao354ebb42012-12-07 10:10:04 +080080 if ((msg = parse_opts(argc, argv, 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 }
plars865695b2001-08-27 22:15:12 +000083
84 /* global setup */
85 setup();
86
87 /*
88 * The following loop checks looping state if -i option given
89 */
90 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +080091 /* reset tst_count in case we are looping */
92 tst_count = 0;
plars865695b2001-08-27 22:15:12 +000093
94 if (mknod(fifo, S_IFIFO | 0777, 0) < 0) {
95 tst_resm(TBROK, "mknod() failed, errno: %d", errno);
96 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +080097 }
plars865695b2001-08-27 22:15:12 +000098 if (stat(fifo, &buf) != 0) {
99 tst_resm(TBROK, "stat() failed, errno: %d", errno);
100 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800101 }
plars865695b2001-08-27 22:15:12 +0000102 if ((buf.st_mode & S_IFIFO) == 0) {
103 tst_resm(TBROK, "Mode does not indicate fifo file");
104 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800105 }
iyermanoje0104b32002-11-08 17:21:47 +0000106#if 0
plars865695b2001-08-27 22:15:12 +0000107 sigset(SIGALRM, alarm_handler);
iyermanoje0104b32002-11-08 17:21:47 +0000108#endif
109 sigptr.sa_handler = (void (*)(int signal))alarm_handler;
110 sigfillset(&sigptr.sa_mask);
111 sigptr.sa_flags = 0;
112 sigaddset(&sigptr.sa_mask, SIGALRM);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800113 if (sigaction(SIGALRM, &sigptr, NULL) == -1) {
vapiercff4af02006-02-11 04:46:30 +0000114 tst_resm(TBROK, "sigaction(): Failed");
iyermanoje0104b32002-11-08 17:21:47 +0000115 cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +0000116 }
robbiew6ee509b2003-04-01 20:28:41 +0000117//block1:
plars865695b2001-08-27 22:15:12 +0000118 tst_resm(TINFO, "Enter block 1: test for EAGAIN in write()");
119 fail = 0;
120
subrata_modak56207ce2009-03-23 13:35:39 +0000121 (void)memset((void *)wbuf, 'A', 17 * PIPE_SIZE_TEST);
plars865695b2001-08-27 22:15:12 +0000122
123 /*
124 * open the read end of the pipe
125 */
126 if (sigsetjmp(jmp, 1)) {
127 tst_resm(TBROK, "Error reading fifo, read blocked");
128 fail = 1;
129 }
subrata_modak56207ce2009-03-23 13:35:39 +0000130 (void)alarm(10); /* set alarm for 10 seconds */
plars865695b2001-08-27 22:15:12 +0000131 rfd = open(fifo, O_RDONLY | O_NONBLOCK);
132 (void)alarm(0);
133 if (rfd < 0) {
134 tst_resm(TBROK, "open() for reading the pipe failed");
135 fail = 1;
136 }
137
138 /*
139 * open the write end of the pipe
140 */
141 if (sigsetjmp(jmp, 1)) {
142 tst_resm(TBROK, "setjmp() failed");
143 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800144 }
subrata_modak56207ce2009-03-23 13:35:39 +0000145 (void)alarm(10); /* set alarm for 10 seconds */
plars865695b2001-08-27 22:15:12 +0000146 wfd = open(fifo, O_WRONLY | O_NONBLOCK);
147 (void)alarm(0);
148 if (wfd < 0) {
149 tst_resm(TBROK, "open() for writing the pipe failed");
150 fail = 1;
151 }
152
153 /*
154 * attempt to fill the pipe with some data
155 */
156 if (sigsetjmp(jmp, 1)) {
157 tst_resm(TBROK, "sigsetjmp() failed");
158 fail = 1;
159 }
160 (void)alarm(10);
subrata_modak56207ce2009-03-23 13:35:39 +0000161 cnt = write(wfd, wbuf, 17 * PIPE_SIZE_TEST);
plars865695b2001-08-27 22:15:12 +0000162 (void)alarm(0);
robbiew4590c0d2005-10-04 16:16:23 +0000163 if (cnt == 17 * PIPE_SIZE_TEST) {
plars865695b2001-08-27 22:15:12 +0000164 tst_resm(TBROK, "Error reading fifo, nozero read");
165 fail = 1;
166 }
167
168 /*
169 * Now that the fifo is full try and send some more
170 */
171 if (sigsetjmp(jmp, 1)) {
172 tst_resm(TBROK, "sigsetjmp() failed");
173 fail = 1;
174 }
175 (void)alarm(10);
subrata_modak56207ce2009-03-23 13:35:39 +0000176 cnt = write(wfd, wbuf, 8 * PIPE_SIZE_TEST);
plars865695b2001-08-27 22:15:12 +0000177 (void)alarm(0);
178 if (cnt != -1) {
179 tst_resm(TBROK, "write() failed to fail when pipe "
180 "is full");
181 fail = 1;
182 } else {
plars865695b2001-08-27 22:15:12 +0000183 if (errno != EAGAIN) {
184 tst_resm(TBROK, "write set bad errno, expected "
185 "EAGAIN, got %d", errno);
186 fail = 1;
187 }
188 tst_resm(TINFO, "read() succeded in setting errno to "
189 "EAGAIN");
190 }
191 if (fail) {
192 tst_resm(TFAIL, "Block 1 FAILED");
193 } else {
194 tst_resm(TPASS, "Block 1 PASSED");
195 }
196 tst_resm(TINFO, "Exit block 1");
197
198 /* unlink fifo in case we are looping. */
199 unlink(fifo);
200 }
201 cleanup();
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800202 tst_exit();
plars865695b2001-08-27 22:15:12 +0000203}
204
Mike Frysingerc57fba52014-04-09 18:56:30 -0400205void alarm_handler(void)
plars865695b2001-08-27 22:15:12 +0000206{
207 siglongjmp(jmp, 1);
208}
209
210/*
211 * setup()
212 * performs all ONE TIME setup for this test
213 */
subrata_modak56207ce2009-03-23 13:35:39 +0000214void setup(void)
plars865695b2001-08-27 22:15:12 +0000215{
Garrett Cooper2c282152010-12-16 00:55:50 -0800216
plars865695b2001-08-27 22:15:12 +0000217 tst_sig(FORK, DEF_HANDLER, cleanup);
218
plars865695b2001-08-27 22:15:12 +0000219 /* Pause if that option was specified
220 * TEST_PAUSE contains the code to fork the test with the -i option.
221 * You want to make sure you do this before you create your temporary
222 * directory.
223 */
224 TEST_PAUSE;
225
226 /* Create a unique temporary directory and chdir() to it. */
227 tst_tmpdir();
228
229 /* create a temporary filename */
230 sprintf(fifo, "%s.%d", fifo, getpid());
231
232}
233
Mike Frysingerc57fba52014-04-09 18:56:30 -0400234void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000235{
plars865695b2001-08-27 22:15:12 +0000236
237 close(rfd);
238 close(wfd);
239 unlink(fifo);
240 tst_rmdir();
241
Wanlong Gao354ebb42012-12-07 10:10:04 +0800242}