source: rtems/cpukit/libcsupport/src/libio.c @ 7f6a24ab

4.104.114.84.95
Last change on this file since 7f6a24ab was 7f6a24ab, checked in by Joel Sherrill <joel.sherrill@…>, on 08/28/95 at 15:30:29

Added unused priority ceiling parameter to rtems_semaphore_create.

Rearranged code to created thread handler routines to initialize,
start, restart, and "close/delete" a thread.

Made internal threads their own object class. This now uses the
thread support routines for starting and initializing a thread.

Insured deleted tasks are freed to the Inactive pool associated with the
correct Information block.

Added an RTEMS API specific data area to the thread control block.

Beginnings of removing the word "rtems" from the core.

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/*
2 *      @(#)libio.c     1.1 - 95/06/02
3 *     
4 *
5 * Provide UNIX/POSIX-like io system calls for RTEMS using the
6 *  RTEMS IO manager
7 *
8 * TODO
9 *
10 *  $Id$
11 */
12
13#include <rtems.h>
14#include <rtems/assoc.h>                /* assoc.h not included by rtems.h */
15
16#include <fcntl.h>                      /* O_RDONLY, et.al. */
17#if defined(solaris2)
18#define O_NDELAY O_NONBLOCK
19#endif
20#include <errno.h>
21#include <string.h>                     /* strcmp */
22#include <unistd.h>
23#include <stdlib.h>                     /* calloc() */
24
25#include "libio.h"                      /* libio.h not pulled in by rtems */
26
27/*
28 * Semaphore to protect the io table
29 */
30
31Objects_Id rtems_libio_semaphore;
32
33#define RTEMS_LIBIO_SEM         rtems_build_name('L', 'B', 'I', 'O')
34#define RTEMS_LIBIO_IOP_SEM(n)  rtems_build_name('L', 'B', 'I', n)
35
36unsigned32     rtems_libio_number_iops;
37rtems_libio_t *rtems_libio_iops;
38rtems_libio_t *rtems_libio_last_iop;
39
40#define rtems_libio_iop(fd)    ((((unsigned32)(fd)) < rtems_libio_number_iops) ? \
41                                       &rtems_libio_iops[fd] : 0)
42
43#define rtems_libio_check_fd(fd) \
44    do { \
45        if ((fd) >= rtems_libio_number_iops) \
46        { \
47            errno = EBADF; \
48            return -1; \
49        } \
50    } while (0)
51
52#define rtems_libio_check_buffer(buffer) \
53    do { \
54        if ((buffer) == 0) \
55        { \
56            errno = EINVAL; \
57            return -1; \
58        } \
59    } while (0)
60
61#define rtems_libio_check_count(count) \
62    do { \
63        if ((count) == 0) \
64        { \
65            return 0; \
66        } \
67    } while (0)
68
69#define rtems_libio_check_permissions(iop, flag) \
70    do { \
71        if (((iop)->flags & (flag)) == 0) \
72        { \
73              errno = EINVAL; \
74              return -1; \
75        } \
76    } while (0)
77
78
79void
80rtems_libio_config(
81    rtems_configuration_table *config,
82    unsigned32                 max_fds
83  )
84{
85    rtems_libio_number_iops = max_fds;
86
87    /*
88     * tweak config to reflect # of semaphores we will need
89     */
90
91    config->maximum_semaphores += 1;            /* one for iop table */
92    config->maximum_semaphores += max_fds;
93}
94
95/*
96 * Called by bsp startup code to init the libio area.
97 */
98
99void
100rtems_libio_init(void)
101{
102    rtems_status_code rc;
103
104    if (rtems_libio_number_iops > 0)
105    {
106        rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
107                                                    sizeof(rtems_libio_t));
108        if (rtems_libio_iops == NULL)
109            rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
110
111        rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1);
112    }
113
114    rc = rtems_semaphore_create(
115      RTEMS_LIBIO_SEM,
116      1,
117      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
118      RTEMS_NO_PRIORITY,
119      &rtems_libio_semaphore
120    );
121    if (rc != RTEMS_SUCCESSFUL)
122        rtems_fatal_error_occurred(rc);
123}
124
125/*
126 * Convert RTEMS status to a UNIX errno
127 */
128
129rtems_assoc_t errno_assoc[] = {
130    { "OK",        RTEMS_SUCCESSFUL,       0 },
131    { "TIMEOUT",   RTEMS_TIMEOUT,          ETIME },
132    { "NO MEMORY", RTEMS_NO_MEMORY,        ENOMEM },
133    { 0, 0, 0 },
134};
135
136static unsigned32
137rtems_libio_errno(rtems_status_code code)
138{
139    int rc;
140   
141    if ((rc = rtems_assoc_remote_by_local(errno_assoc, (unsigned32) code)))
142    {
143        errno = rc;
144        return -1;
145    }
146    return 0;
147}
148
149/*
150 * Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
151 */
152
153rtems_assoc_t access_modes_assoc[] = {
154    { "READ",     LIBIO_FLAGS_READ,  O_RDONLY },
155    { "WRITE",    LIBIO_FLAGS_WRITE, O_WRONLY },
156    { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
157    { 0, 0, 0 },
158};
159
160rtems_assoc_t status_flags_assoc[] = {
161    { "NO DELAY",  LIBIO_FLAGS_NO_DELAY,  O_NDELAY },
162    { "APPEND",    LIBIO_FLAGS_APPEND,    O_APPEND },
163    { "CREATE",    LIBIO_FLAGS_CREATE,    O_CREAT },
164    { 0, 0, 0 },
165};
166
167static unsigned32
168rtems_libio_fcntl_flags(unsigned32 fcntl_flags)
169{
170    unsigned32 flags = 0;
171    unsigned32 access_modes;
172
173    /*
174     * Access mode is a small integer
175     */
176   
177    access_modes = fcntl_flags & O_ACCMODE;
178    fcntl_flags &= ~O_ACCMODE;
179    flags = rtems_assoc_local_by_remote(access_modes_assoc, access_modes);
180
181    /*
182     * Everything else is single bits
183     */
184
185    flags |= rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
186    return flags;
187}
188
189
190static rtems_libio_t *
191rtems_libio_allocate(void)
192{
193    rtems_libio_t *iop;
194    rtems_status_code rc;
195   
196    rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
197
198    for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++)
199        if ((iop->flags & LIBIO_FLAGS_OPEN) == 0)
200        {
201            /*
202             * Got one; create a semaphore for it
203             */
204
205            rc = rtems_semaphore_create(
206              RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
207              1,
208              RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
209              RTEMS_NO_PRIORITY,
210              &iop->sem
211            );
212            if (rc != RTEMS_SUCCESSFUL)
213                goto failed;
214           
215            iop->flags = LIBIO_FLAGS_OPEN;
216            goto done;
217        }
218   
219failed:
220    iop = 0;
221   
222done:
223    rtems_semaphore_release(rtems_libio_semaphore);
224    return iop;
225}
226
227static void
228rtems_libio_free(rtems_libio_t *iop)
229{
230    rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
231
232    if (iop->sem)
233        rtems_semaphore_delete(iop->sem);
234    (void) memset(iop, 0, sizeof(*iop));
235
236    rtems_semaphore_release(rtems_libio_semaphore);
237}
238
239int
240__open(
241    const char   *pathname,
242    unsigned32    flag,
243    unsigned32    mode)
244{
245    rtems_status_code rc;
246    rtems_libio_t *iop = 0;
247    rtems_driver_name_t *np;
248    rtems_libio_open_close_args_t args;
249
250    if ((rc = rtems_io_lookup_name(pathname, &np)) != RTEMS_SUCCESSFUL)
251        goto done;
252
253    iop = rtems_libio_allocate();
254    if (iop == 0)
255    {
256        rc = RTEMS_TOO_MANY;
257        goto done;
258    }
259   
260    iop->driver = np;
261    iop->pathname = (char *) pathname;
262    iop->flags |= rtems_libio_fcntl_flags(flag);
263
264    args.iop = iop;
265    args.flags = iop->flags;
266    args.mode = mode;
267
268    rc = rtems_io_open(np->major, np->minor, (void *) &args);
269   
270done:
271    if (rc != RTEMS_SUCCESSFUL)
272    {
273        if (iop)
274            rtems_libio_free(iop);
275        return rtems_libio_errno(rc);
276    }
277   
278    return iop - rtems_libio_iops;
279}
280   
281int
282__close(
283    int  fd
284  )   
285{
286    rtems_status_code rc;
287    rtems_driver_name_t *np;
288    rtems_libio_t *iop = rtems_libio_iop(fd);
289    rtems_libio_open_close_args_t args;
290
291    rtems_libio_check_fd(fd);
292
293    np = iop->driver;
294
295    args.iop = iop;
296    args.flags = 0;
297    args.mode = 0;
298   
299    rc = rtems_io_close(np->major, np->minor, (void *) &args);
300
301    if (rc != RTEMS_SUCCESSFUL)
302        return rtems_libio_errno(rc);
303    return 0;
304}
305   
306int
307__read(
308    int       fd,
309    void *    buffer,
310    unsigned32 count
311  )
312{
313    rtems_status_code rc;
314    rtems_driver_name_t *np;
315    rtems_libio_t *iop = rtems_libio_iop(fd);
316    rtems_libio_rw_args_t args;
317
318    rtems_libio_check_fd(fd);
319    rtems_libio_check_buffer(buffer);
320    rtems_libio_check_count(count);
321    rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
322
323    np = iop->driver;
324
325    args.iop = iop;
326    args.offset = iop->offset;
327    args.buffer = buffer;
328    args.count = count;
329    args.flags = iop->flags;
330    args.bytes_moved = 0;
331
332    rc = rtems_io_read(np->major, np->minor, (void *) &args);
333
334    iop->offset += args.bytes_moved;
335
336    if (rc != RTEMS_SUCCESSFUL)
337        return rtems_libio_errno(rc);
338
339    return args.bytes_moved;
340}
341
342int
343__write(
344    int         fd,
345    const void *buffer,
346    unsigned32  count
347  )
348{
349    rtems_status_code rc;
350    rtems_driver_name_t *np;
351    rtems_libio_t *iop = rtems_libio_iop(fd);
352    rtems_libio_rw_args_t args;
353
354    rtems_libio_check_fd(fd);
355    rtems_libio_check_buffer(buffer);
356    rtems_libio_check_count(count);
357    rtems_libio_check_permissions(iop, LIBIO_FLAGS_WRITE);
358
359    np = iop->driver;
360
361    args.iop = iop;
362    args.offset = iop->offset;
363    args.buffer = (void *) buffer;
364    args.count = count;
365    args.flags = iop->flags;
366    args.bytes_moved = 0;
367
368    rc = rtems_io_write(np->major, np->minor, (void *) &args);
369
370    iop->offset += args.bytes_moved;
371
372    if (rc != RTEMS_SUCCESSFUL)
373        return rtems_libio_errno(rc);
374
375    return args.bytes_moved;
376}
377
378int
379__ioctl(
380    int         fd,
381    unsigned32  command,
382    void *      buffer)
383{
384    rtems_status_code rc;
385    rtems_driver_name_t *np;
386    rtems_libio_t *iop = rtems_libio_iop(fd);
387    rtems_libio_ioctl_args_t args;
388
389    rtems_libio_check_fd(fd);
390
391    np = iop->driver;
392
393    args.iop = iop;
394    args.command = command;
395    args.buffer = buffer;
396
397    rc = rtems_io_control(np->major, np->minor, (void *) &args);
398
399    if (rc != RTEMS_SUCCESSFUL)
400        return rtems_libio_errno(rc);
401
402    return args.ioctl_return;
403}
404   
405/*
406 * internal only??
407 */
408
409
410int
411__lseek(
412    int                  fd,
413    rtems_libio_offset_t offset,
414    int                  whence
415  )   
416{
417    rtems_libio_t *iop = rtems_libio_iop(fd);
418
419    rtems_libio_check_fd(fd);
420
421    switch (whence)
422    {
423        case SEEK_SET:
424            iop->offset = offset;
425            break;
426
427        case SEEK_CUR:
428            iop->offset += offset;
429            break;
430
431        case SEEK_END:
432            iop->offset = iop->size - offset;
433            break;
434
435        default:
436            errno = EINVAL;
437            return -1;
438    }
439    return 0;
440}
Note: See TracBrowser for help on using the repository browser.