Я тут в FreeBSD перевел программку в фоновый режим — daemon — и наблюдаю непонятное явление.
Пока это было просто консольное приложение я выводил на экран функцией printf:
printf("Bla bla bla\n");
Теперь приходится открывать system console — /dev/console — и писать туда.
fCon = fopen("/dev/console", "w");
fprintf(fCon, "Bla bla bla\n");
Этот вывод идет на терминал ttyv0. Если при этом я logged in на этом терминале то все нормально. Но если я даю команду exit, дальше вывод на этот экран идет без возврата каретки, ступеньками.
Я могу, конечно, добавить возврат каретки явно:
fprintf(fCon, "Bla bla bla\r\n");
Но, вроде, везде говорят что в UNIX это не нужно. В чем дело, где об этом можно почитать?
The mode string can also include the letter "b" after either the "+" or the first letter. This is strictly for compatibility with ISO/IEC 9899:1990 ("ISO C90") and has effect only for fmemopen(); otherwise "b" is ignored.
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>Но, вроде, везде говорят что в UNIX это не нужно.
В дисковых файлах, в UNIX, действительно строки разделяют символом '\n' без '\r'.
Но вот для терминала, как для устройства, символы '\n' и 'r' имеют разный смысл. Первый переходит на следующую строку, второй возвращает курсор к началу строки.
Но дело в том, что между программой, которая пишет на терминал/консоль, отправляя байтики в stdout и самим терминалом/консолью существует еще один компонент, называется line discipline.
И у этого компонента есть своё состояние и свои функции. Например, он может автоматически превращать '\n' в последовательность "\n\r".
Я думаю, у тебя шелл при логине включает этот режим, а при выходе выключает. Отсюда вся разница.
ЛБ>В чем дело, где об этом можно почитать?
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>Теперь приходится открывать system console — /dev/console — и писать туда.
Вообще-то это совсем не то, как надо делать. Надо писать лог.
Можно через syslog(), можно через свой файл. Можно в сокет, из которого будут читать желающие. Можно комбинировать эти подходы.
/dev/console это, конечно, финальное назначение как минимум части логов, но в остальном это место, предназначенное только для самых-самых системных компонентов вроде бутлоадера, ядра и init.
ЛБ>Этот вывод идет на терминал ttyv0. Если при этом я logged in на этом терминале то все нормально. Но если я даю команду exit, дальше вывод на этот экран идет без возврата каретки, ступеньками.
Про это уже сказали — дисциплина терминала (man termios), текущее состояние опции ONLCR.
Здравствуйте, netch80, Вы писали:
N>Вообще-то это совсем не то, как надо делать. Надо писать лог. N>Можно через syslog(), можно через свой файл. Можно в сокет, из которого будут читать желающие. Можно комбинировать эти подходы. N>/dev/console это, конечно, финальное назначение как минимум части логов, но в остальном это место, предназначенное только для самых-самых системных компонентов вроде бутлоадера, ядра и init.
В вспомогательном сервисе блокировок я пишу syslog. Сейчас это выглядит так:
В основном сервисе тоже есть события которые я намерен писать в log. Но есть туча других событий. У меня в зависимости от установки параметра verbosity выводятся сообщения о критических ошибках после которых идет abort, о некритических ошибках типа ошибок сетевой передачи, об ошибках протокола HTTP (400, 403, 404, 413, 414, 418, 444, 503), сообщения об успешно выполненных запросах (200, 304), сообщения об установлении соединений и о их закрытии, и просто информационные сообщения типа "Service is starting." Всему этому в log делать нечего. Все это мне нужно во время отладки а в реальной жизни будет -v0 когда в консоль будет выводится сообщение о критической ошибке перед вызовом abort и я рассчитываю но то что такое никогда не произойдет. Скорее все-таки -v1 но не выше.
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>В основном сервисе тоже есть события которые я намерен писать в log. Но есть туча других событий. У меня в зависимости от установки параметра verbosity выводятся сообщения о критических ошибках после которых идет abort, о некритических ошибках типа ошибок сетевой передачи, об ошибках протокола HTTP (400, 403, 404, 413, 414, 418, 444, 503), сообщения об успешно выполненных запросах (200, 304), сообщения об установлении соединений и о их закрытии, и просто информационные сообщения типа "Service is starting." Всему этому в log делать нечего.
С чего бы это? В syslog() можно выставлять уровни, в syslogd можно разделять выходные файлы по уровням. Это я не вспоминаю, что ещё есть фильтрации по категориям и по имени сервиса.
Ну и свои фильтрации перед ним же можете добавлять.
Вопрос не в том, что именно отправлять, а в том, что прямая запись в console это грубый вредный хак.