heredoc.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "sh.h"
  2. /*
  3. ** Launch heredoc: double left redirection <<
  4. ** Unset term caps modes
  5. ** retrieve text through a prompt
  6. ** Set term caps modes
  7. ** pipe the text in STDIN
  8. ** wait the fork
  9. */
  10. void prompt_redirection_init(t_e *e, t_pipe *p, t_pr *t, t_pr *t2)
  11. {
  12. char *txt;
  13. int i;
  14. set_term_modes(0);
  15. txt = prompt_heredoc(e, txt, t->otxt, i);
  16. set_term_modes(1);
  17. pipe(e->pipefd);
  18. if (fork() == 0)
  19. {
  20. close(e->pipefd[STDIN]);
  21. ft_putstr_fd(txt, e->pipefd[STDOUT]);
  22. ft_strdel(&txt);
  23. exit(0);
  24. }
  25. wait(NULL);
  26. close(e->pipefd[STDOUT]);
  27. prompt_redirection_exec(e, p, t, t2);
  28. }
  29. /*
  30. ** backup STDIN, dup pipe on STDIN
  31. ** if double redirections: open_right_redirections
  32. ** exec the cmd which read on pipe
  33. ** wait fork
  34. ** if double redirections: close file fd, restore STDOUT
  35. ** restore STDIN
  36. */
  37. void prompt_redirection_exec(t_e *e, t_pipe *p, t_pr *t, t_pr *t2)
  38. {
  39. int stdfd;
  40. stdfd = dup(STDIN);
  41. dup2(e->pipefd[STDIN], STDIN);
  42. if (t2 != NULL)
  43. open_right_redirections(e, p, t2);
  44. if (fork() == 0)
  45. {
  46. manage_cmd_2(e, cmd_splitting(e, t->itxt, ' '));
  47. exit(0);
  48. }
  49. wait(NULL);
  50. if (t2 != NULL)
  51. {
  52. close(e->fd_file);
  53. close(STDOUT);
  54. dup(e->fdout);
  55. }
  56. close(e->pipefd[STDIN]);
  57. close(STDIN);
  58. dup(stdfd);
  59. }
  60. /*
  61. ** prompt to enter text, get entered lines
  62. ** join them till it encounter the end of file string except first time
  63. ** read, join the buffer till it encounter ENTER
  64. ** if ctrl + d: print '\n'; return txt
  65. ** return the text
  66. */
  67. char *prompt_heredoc(t_e *e, char *txt, char *eof, int i)
  68. {
  69. t_e *h;
  70. i = 0;
  71. h = (t_e*)malloc(sizeof(t_e));
  72. h->cmd = ft_strnew(0);
  73. while (ft_strcmp(h->cmd, eof) != 0)
  74. {
  75. if (i == 0)
  76. txt = ft_strnew(0);
  77. else
  78. {
  79. txt = ft_strjoinf(txt, ft_strjoinf(h->cmd, "\n", 1), 3);
  80. h->cmd = ft_strnew(0);
  81. }
  82. ft_putchar('>');
  83. if (here_edition(h, 1) == 1)
  84. {
  85. ft_putchar('\n');
  86. return (ft_strjoinf(txt, ft_strjoinf(h->cmd, "\n", 1), 3));
  87. }
  88. i++;
  89. }
  90. ft_strdel(&h->cmd);
  91. free(h);
  92. return (txt);
  93. }
  94. /*
  95. ** break loop if encounter ENTER
  96. ** if heredoc: print '\n'
  97. ** join the buffer
  98. ** if ctrl + d: end of file
  99. ** handle keys moving
  100. */
  101. int here_edition(t_e *h, int heredoc)
  102. {
  103. int ret;
  104. h->key = ft_strnew(4);
  105. while ((ret = read(0, h->key, 1)) > 0)
  106. {
  107. if (h->key[0] == 10)
  108. {
  109. if (heredoc == 1)
  110. ft_putchar('\n');
  111. break ;
  112. }
  113. if (ft_isprint(h->key[0]) == 1)
  114. {
  115. ft_putchar(h->key[0]);
  116. h->key[ret] = '\0';
  117. h->cmd = ft_strjoinf(h->cmd, h->key, 1);
  118. }
  119. if (h->key[0] == 4)
  120. return (1);
  121. else
  122. handle_keys(h, 0);
  123. }
  124. return (0);
  125. }