Форум программистов, компьютерный форум CyberForum.ru

С++ под Linux

Войти
Регистрация
Восстановить пароль
 
4ik
4 / 4 / 1
Регистрация: 05.02.2013
Сообщений: 84
#1

Не работает dup2 - C++ Linux

24.11.2016, 22:38. Просмотров 386. Ответов 10
Метки нет (Все метки)

Здравствуйте!
Пытаюсь ассоциировать ввод с выводом, но почему-то все равно выводит все в обычный поток вывода
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <string>
 
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
 
int main() {
std::string str;
 
if (fork() == 0) {
if (dup2(0, 1) < 0) {
std::cerr « "dup2\n";
} else {
std::cout « "QweEwq\n";
}
exit(0);
}
else {
wait(NULL);
}
 
fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);// не блокирующий ввод
std::istreambuf_iterator<char> it(std::cin), end;
str.assign(it,end);
 
std::cout « "***\n" « str « ' ' « str.length() « '\n';
 
return 0;
}
Сам dup2 возращает нормальное значение. Подумал что мб 0,1,2 нельзя ассоциировать между собой но не нашел инфы, вроде как можно. Вот вывод программы:
[@ ex]$ ./a.out
QweEwq
***
0
То есть он выводит в 1 все и еще не попадает в 0. То есть вроде как dup2 выполняется корректно, но ассоциации нету. Не подскажите в чем проблема?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.11.2016, 22:38     Не работает dup2
Посмотрите здесь:

Программа в VS работает, в Linux не работает C++ Linux
C++ Linux Программа работает при запуске в CodeLite, но не работает при запуске в консоли

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
drfaust
256 / 146 / 37
Регистрация: 02.10.2008
Сообщений: 530
Записей в блоге: 1
Завершенные тесты: 1
25.11.2016, 08:43     Не работает dup2 #2
Может потому что дескрипторы 0 и 1 изначально привязаны к stdin и stdout ?
4ik
4 / 4 / 1
Регистрация: 05.02.2013
Сообщений: 84
25.11.2016, 15:09  [ТС]     Не работает dup2 #3
То есть их нельзя ассоциировать между собой?
drfaust
256 / 146 / 37
Регистрация: 02.10.2008
Сообщений: 530
Записей в блоге: 1
Завершенные тесты: 1
26.11.2016, 09:35     Не работает dup2 #4
ХЗ, как работает dup2. Обычный dup создает дубликат дескриптора.
Тут мы имеем два разных дескриптора с разными режимами, один на чтение, другой на запись.

Самому интересно стало.
Например выдержка из мана:
dup2 делает newfd копией oldfd, закрывая newfd, если требуется.
Что бы это значило? Закрывает newfd, если тот открыт а потом ассоциирует oldfd<=>newfd?

Ждём знающих людей.
Как вариант можно попробовать посмотреть через fcntl(1,F_GETFL) - есть ли какие изменения до и после dup2
gng
627 / 473 / 128
Регистрация: 08.09.2013
Сообщений: 1,224
26.11.2016, 16:00     Не работает dup2 #5
4ik, не совсем понял, чего вы хотите добиться.
При запуске программы дескрипторы 0,1,2 ассоциируются с консолью. dup2 работает, как и описано в мане. Новый десктиптор закрывается и сразу (атомарно) ассоциируется со старым.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
 
int main() {
        for (int i=0; i<3; i++) write (i, "tty\n", 5);
 
        int fd= open ("/dev/null", O_WRONLY);
        if (dup2(fd, 1) < 0) write (2, "Err!\n", 6);
        else write (1, "NULL\n", 6);
 
        if (dup2(2, 1) < 0) write (2, "Err!\n", 6);
        else write (1, "tty!\n", 6);
        return 0;
}
drfaust
256 / 146 / 37
Регистрация: 02.10.2008
Сообщений: 530
Записей в блоге: 1
Завершенные тесты: 1
26.11.2016, 17:28     Не работает dup2 #6
Т.е. после dup2(0,1) мы должны вместо stdout получить stdin, а stdout окажется закрытым?
Так должно получится?

З.Ы. потому я и просил посмотреть на fcntl до и после dup2
gng
627 / 473 / 128
Регистрация: 08.09.2013
Сообщений: 1,224
26.11.2016, 20:25     Не работает dup2 #7
Цитата Сообщение от drfaust Посмотреть сообщение
Т.е. после dup2(0,1) мы должны вместо stdout получить stdin, а stdout окажется закрытым?
Я представляю этот процесс немного по другому.
До dup2 0,1,2 указывают на /dev/ttyX.
После dup2(0,1) файл /dev/ttyX закрывается с дескриптором 1 и сразу же открывается тот же /dev/ttyX с тем же дескриптором 1. По сути - ничего не меняется.
drfaust
256 / 146 / 37
Регистрация: 02.10.2008
Сообщений: 530
Записей в блоге: 1
Завершенные тесты: 1
26.11.2016, 22:27     Не работает dup2 #8
Тут ты не прав.
/dev/tty* это отдельное устройство со своим терминалом и достучаться до него - крайне системно-специфичная задача.

Дескрипторы 0,1,2 - это стандарнтые ус-ва ввода вывода
для конкретной программы. Если я делаю
Bash
1
ls > 1.txt
то дескриптор 1 будет ассоциирован с файлом ./1.txt , а не с каким-то терминалом
gng
627 / 473 / 128
Регистрация: 08.09.2013
Сообщений: 1,224
27.11.2016, 14:48     Не работает dup2 #9
Цитата Сообщение от drfaust Посмотреть сообщение
то дескриптор 1 будет ассоциирован с файлом ./1.txt , а не с каким-то терминалом
Речь, судя по вопросу ТС, о другом.
Пока дескрипторы 0,1,2 указывают на /dev/tty, вызов dup2 (0,1) ничего не меняет.
Если они будут указывать на разные файлы, этот вызов, очевидно, закроет файл 1, и направит 1 на тот же файл,что и 0.
Впрочем, мой пример выше всё это демонстрирует.
4ik
4 / 4 / 1
Регистрация: 05.02.2013
Сообщений: 84
27.11.2016, 19:10  [ТС]     Не работает dup2 #10
Моя задача была отказаться от пайпа с помощью подачи инфы на вход а потом чтения оттуда без блокировки. То есть доч процессу мы отправляем какуюто строку а потом в доч ее считываем просто через cin. Можно ли так сделать?
gng
627 / 473 / 128
Регистрация: 08.09.2013
Сообщений: 1,224
27.11.2016, 20:37     Не работает dup2 #11
Цитата Сообщение от 4ik Посмотреть сообщение
Можно ли так сделать?
Сомневаюсь, что это то, что вам надо.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
 
int main() {
  int fd= open ("/tmp/pipe", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  if (fork()) {
      sleep (1);
      if (dup2(fd, 1) < 0) std::cerr << "Error!\n";
      else std::cout << "Sending string.\n";
      close (1);
      wait(0);
  }
  else {
    std::string s;
    if (dup2(fd, 0) < 0) std::cerr << "Error!\n";
    else {
      std::getline (std::cin, s);
      std::cout << "Receive " << s << std::endl;
      close (0);
    }
  }
  close (fd);
  return 0;
}
Yandex
Объявления
27.11.2016, 20:37     Не работает dup2
Ответ Создать тему
Опции темы

Текущее время: 15:01. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru