fifo.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * linux/fs/fifo.c
  3. *
  4. * written by Paul H. Hargrove
  5. *
  6. * Fixes:
  7. * 10-06-1999, AV: fixed OOM handling in fifo_open(), moved
  8. * initialization there, switched to external
  9. * allocation of pipe_inode_info.
  10. */
  11. #include <linux/mm.h>
  12. #include <linux/slab.h>
  13. #include <linux/smp_lock.h>
  14. #include <linux/fs.h>
  15. #include <linux/pipe_fs_i.h>
  16. static void wait_for_partner(struct inode* inode, unsigned int* cnt)
  17. {
  18. int cur = *cnt;
  19. while(cur == *cnt) {
  20. pipe_wait(inode);
  21. if(signal_pending(current))
  22. break;
  23. }
  24. }
  25. static void wake_up_partner(struct inode* inode)
  26. {
  27. wake_up_interruptible(PIPE_WAIT(*inode));
  28. }
  29. static int fifo_open(struct inode *inode, struct file *filp)
  30. {
  31. int ret;
  32. ret = -ERESTARTSYS;
  33. if (down_interruptible(PIPE_SEM(*inode)))
  34. goto err_nolock_nocleanup;
  35. if (!inode->i_pipe) {
  36. ret = -ENOMEM;
  37. if(!pipe_new(inode))
  38. goto err_nocleanup;
  39. }
  40. filp->f_version = 0;
  41. /* We can only do regular read/write on fifos */
  42. filp->f_mode &= (FMODE_READ | FMODE_WRITE);
  43. switch (filp->f_mode) {
  44. case 1:
  45. /*
  46. * O_RDONLY
  47. * POSIX.1 says that O_NONBLOCK means return with the FIFO
  48. * opened, even when there is no process writing the FIFO.
  49. */
  50. filp->f_op = &read_fifo_fops;
  51. PIPE_RCOUNTER(*inode)++;
  52. if (PIPE_READERS(*inode)++ == 0)
  53. wake_up_partner(inode);
  54. if (!PIPE_WRITERS(*inode)) {
  55. if ((filp->f_flags & O_NONBLOCK)) {
  56. /* suppress POLLHUP until we have
  57. * seen a writer */
  58. filp->f_version = PIPE_WCOUNTER(*inode);
  59. } else
  60. {
  61. wait_for_partner(inode, &PIPE_WCOUNTER(*inode));
  62. if(signal_pending(current))
  63. goto err_rd;
  64. }
  65. }
  66. break;
  67. case 2:
  68. /*
  69. * O_WRONLY
  70. * POSIX.1 says that O_NONBLOCK means return -1 with
  71. * errno=ENXIO when there is no process reading the FIFO.
  72. */
  73. ret = -ENXIO;
  74. if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode))
  75. goto err;
  76. filp->f_op = &write_fifo_fops;
  77. PIPE_WCOUNTER(*inode)++;
  78. if (!PIPE_WRITERS(*inode)++)
  79. wake_up_partner(inode);
  80. if (!PIPE_READERS(*inode)) {
  81. wait_for_partner(inode, &PIPE_RCOUNTER(*inode));
  82. if (signal_pending(current))
  83. goto err_wr;
  84. }
  85. break;
  86. case 3:
  87. /*
  88. * O_RDWR
  89. * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
  90. * This implementation will NEVER block on a O_RDWR open, since
  91. * the process can at least talk to itself.
  92. */
  93. filp->f_op = &rdwr_fifo_fops;
  94. PIPE_READERS(*inode)++;
  95. PIPE_WRITERS(*inode)++;
  96. PIPE_RCOUNTER(*inode)++;
  97. PIPE_WCOUNTER(*inode)++;
  98. if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1)
  99. wake_up_partner(inode);
  100. break;
  101. default:
  102. ret = -EINVAL;
  103. goto err;
  104. }
  105. /* Ok! */
  106. up(PIPE_SEM(*inode));
  107. return 0;
  108. err_rd:
  109. if (!--PIPE_READERS(*inode))
  110. wake_up_interruptible(PIPE_WAIT(*inode));
  111. ret = -ERESTARTSYS;
  112. goto err;
  113. err_wr:
  114. if (!--PIPE_WRITERS(*inode))
  115. wake_up_interruptible(PIPE_WAIT(*inode));
  116. ret = -ERESTARTSYS;
  117. goto err;
  118. err:
  119. if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode))
  120. free_pipe_info(inode);
  121. err_nocleanup:
  122. up(PIPE_SEM(*inode));
  123. err_nolock_nocleanup:
  124. return ret;
  125. }
  126. /*
  127. * Dummy default file-operations: the only thing this does
  128. * is contain the open that then fills in the correct operations
  129. * depending on the access mode of the file...
  130. */
  131. struct file_operations def_fifo_fops = {
  132. .open = fifo_open, /* will set read or write pipe_fops */
  133. };