pipe.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "fspr_arch_file_io.h"
  17. #include "fspr_strings.h"
  18. #include "fspr_portable.h"
  19. #include "fspr_arch_inherit.h"
  20. /* Figure out how to get pipe block/nonblock on BeOS...
  21. * Basically, BONE7 changed things again so that ioctl didn't work,
  22. * but now fcntl does, hence we need to do this extra checking.
  23. * The joys of beta programs. :-)
  24. */
  25. #if BEOS
  26. #if !BONE7
  27. # define BEOS_BLOCKING 1
  28. #else
  29. # define BEOS_BLOCKING 0
  30. #endif
  31. #endif
  32. static fspr_status_t pipeblock(fspr_file_t *thepipe)
  33. {
  34. #if !BEOS_BLOCKING
  35. int fd_flags;
  36. fd_flags = fcntl(thepipe->filedes, F_GETFL, 0);
  37. # if defined(O_NONBLOCK)
  38. fd_flags &= ~O_NONBLOCK;
  39. # elif defined(O_NDELAY)
  40. fd_flags &= ~O_NDELAY;
  41. # elif defined(O_FNDELAY)
  42. fd_flags &= ~O_FNDELAY;
  43. # else
  44. /* XXXX: this breaks things, but an alternative isn't obvious...*/
  45. return APR_ENOTIMPL;
  46. # endif
  47. if (fcntl(thepipe->filedes, F_SETFL, fd_flags) == -1) {
  48. return errno;
  49. }
  50. #else /* BEOS_BLOCKING */
  51. # if BEOS_BONE /* This only works on BONE 0-6 */
  52. int on = 0;
  53. if (ioctl(thepipe->filedes, FIONBIO, &on, sizeof(on)) < 0) {
  54. return errno;
  55. }
  56. # else /* "classic" BeOS doesn't support this at all */
  57. return APR_ENOTIMPL;
  58. # endif
  59. #endif /* !BEOS_BLOCKING */
  60. thepipe->blocking = BLK_ON;
  61. return APR_SUCCESS;
  62. }
  63. static fspr_status_t pipenonblock(fspr_file_t *thepipe)
  64. {
  65. #if !BEOS_BLOCKING
  66. int fd_flags = fcntl(thepipe->filedes, F_GETFL, 0);
  67. # if defined(O_NONBLOCK)
  68. fd_flags |= O_NONBLOCK;
  69. # elif defined(O_NDELAY)
  70. fd_flags |= O_NDELAY;
  71. # elif defined(O_FNDELAY)
  72. fd_flags |= O_FNDELAY;
  73. # else
  74. /* XXXX: this breaks things, but an alternative isn't obvious...*/
  75. return APR_ENOTIMPL;
  76. # endif
  77. if (fcntl(thepipe->filedes, F_SETFL, fd_flags) == -1) {
  78. return errno;
  79. }
  80. #else /* BEOS_BLOCKING */
  81. # if BEOS_BONE /* This only works on BONE 0-6 */
  82. int on = 1;
  83. if (ioctl(thepipe->filedes, FIONBIO, &on, sizeof(on)) < 0) {
  84. return errno;
  85. }
  86. # else /* "classic" BeOS doesn't support this at all */
  87. return APR_ENOTIMPL;
  88. # endif
  89. #endif /* !BEOS_BLOCKING */
  90. thepipe->blocking = BLK_OFF;
  91. return APR_SUCCESS;
  92. }
  93. APR_DECLARE(fspr_status_t) fspr_file_pipe_timeout_set(fspr_file_t *thepipe, fspr_interval_time_t timeout)
  94. {
  95. if (thepipe->is_pipe == 1) {
  96. thepipe->timeout = timeout;
  97. if (timeout >= 0) {
  98. if (thepipe->blocking != BLK_OFF) { /* blocking or unknown state */
  99. return pipenonblock(thepipe);
  100. }
  101. }
  102. else {
  103. if (thepipe->blocking != BLK_ON) { /* non-blocking or unknown state */
  104. return pipeblock(thepipe);
  105. }
  106. }
  107. return APR_SUCCESS;
  108. }
  109. return APR_EINVAL;
  110. }
  111. APR_DECLARE(fspr_status_t) fspr_file_pipe_timeout_get(fspr_file_t *thepipe, fspr_interval_time_t *timeout)
  112. {
  113. if (thepipe->is_pipe == 1) {
  114. *timeout = thepipe->timeout;
  115. return APR_SUCCESS;
  116. }
  117. return APR_EINVAL;
  118. }
  119. APR_DECLARE(fspr_status_t) fspr_os_pipe_put_ex(fspr_file_t **file,
  120. fspr_os_file_t *thefile,
  121. int register_cleanup,
  122. fspr_pool_t *pool)
  123. {
  124. int *dafile = thefile;
  125. (*file) = fspr_pcalloc(pool, sizeof(fspr_file_t));
  126. (*file)->pool = pool;
  127. (*file)->eof_hit = 0;
  128. (*file)->is_pipe = 1;
  129. (*file)->blocking = BLK_UNKNOWN; /* app needs to make a timeout call */
  130. (*file)->timeout = -1;
  131. (*file)->ungetchar = -1; /* no char avail */
  132. (*file)->filedes = *dafile;
  133. if (!register_cleanup) {
  134. (*file)->flags = APR_FILE_NOCLEANUP;
  135. }
  136. (*file)->buffered = 0;
  137. #if APR_HAS_THREADS
  138. (*file)->thlock = NULL;
  139. #endif
  140. if (register_cleanup) {
  141. fspr_pool_cleanup_register((*file)->pool, (void *)(*file),
  142. fspr_unix_file_cleanup,
  143. fspr_pool_cleanup_null);
  144. }
  145. #ifndef WAITIO_USES_POLL
  146. /* Start out with no pollset. fspr_wait_for_io_or_timeout() will
  147. * initialize the pollset if needed.
  148. */
  149. (*file)->pollset = NULL;
  150. #endif
  151. return APR_SUCCESS;
  152. }
  153. APR_DECLARE(fspr_status_t) fspr_os_pipe_put(fspr_file_t **file,
  154. fspr_os_file_t *thefile,
  155. fspr_pool_t *pool)
  156. {
  157. return fspr_os_pipe_put_ex(file, thefile, 0, pool);
  158. }
  159. APR_DECLARE(fspr_status_t) fspr_file_pipe_create(fspr_file_t **in, fspr_file_t **out, fspr_pool_t *pool)
  160. {
  161. int filedes[2];
  162. if (pipe(filedes) == -1) {
  163. return errno;
  164. }
  165. (*in) = (fspr_file_t *)fspr_pcalloc(pool, sizeof(fspr_file_t));
  166. (*in)->pool = pool;
  167. (*in)->filedes = filedes[0];
  168. (*in)->is_pipe = 1;
  169. (*in)->fname = NULL;
  170. (*in)->buffered = 0;
  171. (*in)->blocking = BLK_ON;
  172. (*in)->timeout = -1;
  173. (*in)->ungetchar = -1;
  174. (*in)->flags = APR_INHERIT;
  175. #if APR_HAS_THREADS
  176. (*in)->thlock = NULL;
  177. #endif
  178. #ifndef WAITIO_USES_POLL
  179. (*in)->pollset = NULL;
  180. #endif
  181. (*out) = (fspr_file_t *)fspr_pcalloc(pool, sizeof(fspr_file_t));
  182. (*out)->pool = pool;
  183. (*out)->filedes = filedes[1];
  184. (*out)->is_pipe = 1;
  185. (*out)->fname = NULL;
  186. (*out)->buffered = 0;
  187. (*out)->blocking = BLK_ON;
  188. (*out)->flags = APR_INHERIT;
  189. (*out)->timeout = -1;
  190. #if APR_HAS_THREADS
  191. (*out)->thlock = NULL;
  192. #endif
  193. #ifndef WAITIO_USES_POLL
  194. (*out)->pollset = NULL;
  195. #endif
  196. fspr_pool_cleanup_register((*in)->pool, (void *)(*in), fspr_unix_file_cleanup,
  197. fspr_pool_cleanup_null);
  198. fspr_pool_cleanup_register((*out)->pool, (void *)(*out), fspr_unix_file_cleanup,
  199. fspr_pool_cleanup_null);
  200. return APR_SUCCESS;
  201. }
  202. APR_DECLARE(fspr_status_t) fspr_file_namedpipe_create(const char *filename,
  203. fspr_fileperms_t perm, fspr_pool_t *pool)
  204. {
  205. mode_t mode = fspr_unix_perms2mode(perm);
  206. if (mkfifo(filename, mode) == -1) {
  207. return errno;
  208. }
  209. return APR_SUCCESS;
  210. }