~ubuntu-branches/ubuntu/natty/eglibc/natty-security

« back to all changes in this revision

Viewing changes to rt/tst-aio7.c

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno
  • Date: 2009-05-05 09:54:14 UTC
  • Revision ID: james.westby@ubuntu.com-20090505095414-c45qsg9ixjheohru
ImportĀ upstreamĀ versionĀ 2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Test for AIO POSIX compliance.
 
2
   Copyright (C) 2001,02, 03 Free Software Foundation, Inc.
 
3
   This file is part of the GNU C Library.
 
4
 
 
5
   The GNU C Library is free software; you can redistribute it and/or
 
6
   modify it under the terms of the GNU Lesser General Public
 
7
   License as published by the Free Software Foundation; either
 
8
   version 2.1 of the License, or (at your option) any later version.
 
9
 
 
10
   The GNU C Library 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 the GNU
 
13
   Lesser General Public License for more details.
 
14
 
 
15
   You should have received a copy of the GNU Lesser General Public
 
16
   License along with the GNU C Library; if not, write to the Free
 
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
18
   02111-1307 USA.  */
 
19
 
 
20
#include <aio.h>
 
21
#include <error.h>
 
22
#include <errno.h>
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <unistd.h>
 
26
 
 
27
 
 
28
/* We might wait for 3 seconds, so increase timeout to 10 seconds.  */
 
29
#define TIMEOUT 10
 
30
 
 
31
 
 
32
#define TEST_FUNCTION do_test ()
 
33
static int
 
34
do_test (void)
 
35
{
 
36
  int result = 0;
 
37
  int piped[2];
 
38
 
 
39
  /* Make a pipe that we will never write to, so we can block reading it.  */
 
40
  if (pipe (piped) < 0)
 
41
    {
 
42
      perror ("pipe");
 
43
      return 1;
 
44
    }
 
45
 
 
46
  /* Test for aio_cancel() detecting invalid file descriptor.  */
 
47
  {
 
48
    struct aiocb cb;
 
49
    int fd = -1;
 
50
 
 
51
    cb.aio_fildes = fd;
 
52
    cb.aio_offset = 0;
 
53
    cb.aio_buf = NULL;
 
54
    cb.aio_nbytes = 0;
 
55
    cb.aio_reqprio = 0;
 
56
    cb.aio_sigevent.sigev_notify = SIGEV_NONE;
 
57
 
 
58
    errno = 0;
 
59
 
 
60
    /* Case one: invalid fds that match.  */
 
61
    if (aio_cancel (fd, &cb) != -1 || errno != EBADF)
 
62
      {
 
63
        if (errno == ENOSYS)
 
64
          {
 
65
            puts ("no aio support in this configuration");
 
66
            return 0;
 
67
          }
 
68
 
 
69
        puts ("aio_cancel( -1, {-1..} ) did not return -1 or errno != EBADF");
 
70
        ++result;
 
71
      }
 
72
 
 
73
    cb.aio_fildes = -2;
 
74
    errno = 0;
 
75
 
 
76
    /* Case two: invalid fds that do not match; just print warning.  */
 
77
    if (aio_cancel (fd, &cb) != -1 || errno != EBADF)
 
78
      puts ("aio_cancel( -1, {-2..} ) did not return -1 or errno != EBADF");
 
79
  }
 
80
 
 
81
  /* Test for aio_fsync() detecting bad fd, and fd not open for writing.  */
 
82
  {
 
83
    struct aiocb cb;
 
84
    int fd = -1;
 
85
 
 
86
    cb.aio_fildes = fd;
 
87
    cb.aio_offset = 0;
 
88
    cb.aio_buf = NULL;
 
89
    cb.aio_nbytes = 0;
 
90
    cb.aio_reqprio = 0;
 
91
    cb.aio_sigevent.sigev_notify = SIGEV_NONE;
 
92
 
 
93
    errno = 0;
 
94
 
 
95
    /* Case one: invalid fd.  */
 
96
    if (aio_fsync (O_SYNC, &cb) != -1 || errno != EBADF)
 
97
      {
 
98
        puts ("aio_fsync( op, {-1..} ) did not return -1 or errno != EBADF");
 
99
        ++result;
 
100
      }
 
101
 
 
102
    if ((fd = open ("/dev/null", O_RDONLY)) < 0)
 
103
      error (1, errno, "opening /dev/null");
 
104
 
 
105
    cb.aio_fildes = fd;
 
106
    errno = 0;
 
107
 
 
108
    /* Case two: valid fd but open for read only.  */
 
109
    if (aio_fsync (O_SYNC, &cb) != -1 || errno != EBADF)
 
110
      {
 
111
        puts ("aio_fsync( op, {RO..} ) did not return -1 or errno != EBADF");
 
112
        ++result;
 
113
      }
 
114
 
 
115
    close (fd);
 
116
  }
 
117
 
 
118
  /* Test for aio_suspend() suspending even if completed elements in list.  */
 
119
  {
 
120
#define BYTES 8
 
121
    const int ELEMS = 2;
 
122
    int i, r, fd;
 
123
    static char buff[BYTES];
 
124
    char name[] = "/tmp/aio7.XXXXXX";
 
125
    struct timespec timeout;
 
126
    static struct aiocb cb0, cb1;
 
127
    struct aiocb *list[ELEMS];
 
128
 
 
129
    fd = mkstemp (name);
 
130
    if (fd < 0)
 
131
      error (1, errno, "creating temp file");
 
132
 
 
133
    if (unlink (name))
 
134
      error (1, errno, "unlinking temp file");
 
135
 
 
136
    if (write (fd, "01234567", BYTES) != BYTES)
 
137
      error (1, errno, "writing to temp file");
 
138
 
 
139
    cb0.aio_fildes = fd;
 
140
    cb0.aio_offset = 0;
 
141
    cb0.aio_buf = buff;
 
142
    cb0.aio_nbytes = BYTES;
 
143
    cb0.aio_reqprio = 0;
 
144
    cb0.aio_sigevent.sigev_notify = SIGEV_NONE;
 
145
 
 
146
    r = aio_read (&cb0);
 
147
    if (r != 0)
 
148
      error (1, errno, "reading from file");
 
149
 
 
150
    while (aio_error (&(cb0)) == EINPROGRESS)
 
151
      usleep (10);
 
152
 
 
153
    for (i = 0; i < BYTES; i++)
 
154
      printf ("%c ", buff[i]);
 
155
    printf ("\n");
 
156
 
 
157
    /* At this point, the first read is completed, so start another one on
 
158
       the read half of a pipe on which nothing will be written.  */
 
159
    cb1.aio_fildes = piped[0];
 
160
    cb1.aio_offset = 0;
 
161
    cb1.aio_buf = buff;
 
162
    cb1.aio_nbytes = BYTES;
 
163
    cb1.aio_reqprio = 0;
 
164
    cb1.aio_sigevent.sigev_notify = SIGEV_NONE;
 
165
 
 
166
    r = aio_read (&cb1);
 
167
    if (r != 0)
 
168
      error (1, errno, "reading from file");
 
169
 
 
170
    /* Now call aio_suspend() with the two reads.  It should return
 
171
     * immediately according to the POSIX spec.
 
172
     */
 
173
    list[0] = &cb0;
 
174
    list[1] = &cb1;
 
175
    timeout.tv_sec = 3;
 
176
    timeout.tv_nsec = 0;
 
177
    r = aio_suspend ((const struct aiocb * const *) list, ELEMS, &timeout);
 
178
 
 
179
    if (r == -1 && errno == EAGAIN)
 
180
      {
 
181
        puts ("aio_suspend([done,blocked],2,3) suspended thread");
 
182
        ++result;
 
183
      }
 
184
 
 
185
    /* Note that CB1 is still pending, and so cannot be an auto variable.
 
186
       Thus we also test that exiting with an outstanding request works.  */
 
187
  }
 
188
 
 
189
  return result;
 
190
}
 
191
 
 
192
#include "../test-skeleton.c"