[e2324c0] | 1 | /* |
---|
| 2 | * pipe.c: anonymous pipe |
---|
| 3 | * |
---|
| 4 | * Author: Wei Shen <cquark@gmail.com> |
---|
| 5 | * |
---|
| 6 | * The license and distribution terms for this file may be |
---|
| 7 | * found in the file LICENSE in this distribution or at |
---|
| 8 | * http://www.rtems.com/license/LICENSE. |
---|
| 9 | * |
---|
| 10 | * $Id$ |
---|
| 11 | */ |
---|
| 12 | |
---|
[694c3ac6] | 13 | #ifdef HAVE_CONFIG_H |
---|
| 14 | #include "config.h" |
---|
| 15 | #endif |
---|
| 16 | |
---|
[e2324c0] | 17 | #include <stdio.h> |
---|
| 18 | #include <fcntl.h> |
---|
| 19 | #include <rtems/libio_.h> |
---|
| 20 | #include <rtems/seterr.h> |
---|
| 21 | |
---|
| 22 | /* Incremental number added to names of anonymous pipe files */ |
---|
| 23 | uint16_t rtems_pipe_no = 0; |
---|
| 24 | |
---|
| 25 | /* |
---|
| 26 | * Called by pipe() to create an anonymous pipe. |
---|
| 27 | */ |
---|
| 28 | int pipe_create( |
---|
| 29 | int filsdes[2] |
---|
| 30 | ) |
---|
| 31 | { |
---|
| 32 | rtems_filesystem_location_info_t loc; |
---|
| 33 | rtems_libio_t *iop; |
---|
| 34 | int err = 0; |
---|
| 35 | /* Create /tmp if not exists */ |
---|
[7baa484] | 36 | if (rtems_filesystem_evaluate_path("/tmp", 3, RTEMS_LIBIO_PERMS_RWX, &loc, TRUE) |
---|
[e2324c0] | 37 | != 0) { |
---|
| 38 | if (errno != ENOENT) |
---|
| 39 | return -1; |
---|
| 40 | if (mkdir("/tmp", S_IRWXU|S_IRWXG|S_IRWXO|S_ISVTX) != 0) |
---|
| 41 | return -1; |
---|
| 42 | } |
---|
| 43 | else |
---|
| 44 | rtems_filesystem_freenode(&loc); |
---|
| 45 | |
---|
| 46 | /* /tmp/.fifoXXXX */ |
---|
| 47 | char fifopath[15]; |
---|
| 48 | memcpy(fifopath, "/tmp/.fifo", 10); |
---|
| 49 | sprintf(fifopath + 10, "%04x", rtems_pipe_no ++); |
---|
| 50 | |
---|
| 51 | /* Try creating FIFO file until find an available file name */ |
---|
| 52 | while (mkfifo(fifopath, S_IRUSR|S_IWUSR) != 0) { |
---|
[44be50c] | 53 | if (errno != EEXIST){ |
---|
[e2324c0] | 54 | return -1; |
---|
[44be50c] | 55 | } |
---|
[e2324c0] | 56 | /* Just try once... */ |
---|
| 57 | return -1; |
---|
| 58 | sprintf(fifopath + 10, "%04x", rtems_pipe_no ++); |
---|
| 59 | } |
---|
| 60 | |
---|
| 61 | /* Non-blocking open to avoid waiting for writers */ |
---|
| 62 | filsdes[0] = open(fifopath, O_RDONLY | O_NONBLOCK); |
---|
| 63 | if (filsdes[0] < 0) { |
---|
| 64 | err = errno; |
---|
[44be50c] | 65 | /* Delete file at errors, or else if pipe is successfully created |
---|
| 66 | the file node will be deleted after it is closed by all. */ |
---|
| 67 | unlink(fifopath); |
---|
[e2324c0] | 68 | } |
---|
[44be50c] | 69 | else { |
---|
[e2324c0] | 70 | /* Reset open file to blocking mode */ |
---|
[44be50c] | 71 | iop = rtems_libio_iop(filsdes[0]); |
---|
| 72 | iop->flags &= ~LIBIO_FLAGS_NO_DELAY; |
---|
[e2324c0] | 73 | |
---|
[44be50c] | 74 | filsdes[1] = open(fifopath, O_WRONLY); |
---|
[e2324c0] | 75 | |
---|
[44be50c] | 76 | if (filsdes[1] < 0) { |
---|
[e2324c0] | 77 | err = errno; |
---|
| 78 | close(filsdes[0]); |
---|
[44be50c] | 79 | } |
---|
[e2324c0] | 80 | unlink(fifopath); |
---|
[44be50c] | 81 | } |
---|
[e2324c0] | 82 | |
---|
| 83 | rtems_set_errno_and_return_minus_one(err); |
---|
| 84 | } |
---|
[44be50c] | 85 | |
---|