Попробуйте следующее:
SELECT to_char (2/3::float, 'FM999999990.00');
-- RESULT: 0.67
Или просто:
SELECT round (2/3::DECIMAL, 2)::TEXT
-- RESULT: 0.67
Вы обычно хотите проигнорировать SIGPIPE
и обработать ошибку непосредственно в Вашем коде. Это вызвано тем, что обработчики сигналов в C имеют много ограничений на то, что они могут сделать.
самый портативный способ сделать это должно установить SIGPIPE
обработчик к SIG_IGN
. Это будет препятствовать любому сокету или передавать запись по каналу вызвать SIGPIPE
сигнал.
Для игнорирования эти SIGPIPE
сигнал используйте следующий код:
signal(SIGPIPE, SIG_IGN);
, Если Вы используете эти send()
вызов, другая опция состоит в том, чтобы использовать MSG_NOSIGNAL
опция, которая выключит SIGPIPE
поведение на на основание вызова. Обратите внимание, что не все операционные системы поддерживают эти MSG_NOSIGNAL
флаг.
Наконец, можно также хотеть рассмотреть SO_SIGNOPIPE
флаг сокета, который может быть установлен с [1 111] в некоторых операционных системах. Это предотвратит SIGPIPE
от того, чтобы быть вызванным записями только к сокетам, на которых это установлено.
Другой метод должен изменить сокет, таким образом, это никогда не генерирует SIGPIPE на записи (). Это более удобно в библиотеках, где Вы не могли бы хотеть глобальный обработчик сигналов для SIGPIPE.
На самом основанном на BSD (MacOS, FreeBSD...) системы, (принятие Вас используют C/C++), можно сделать это с:
int set = 1;
setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
С этим в действительности, вместо сгенерированного сигнала SIGPIPE, EPIPE будет возвращен.
Вы не можете предотвратить процесс на дальнем конце канала от выхода, и если это выйдет, прежде чем Вы закончили писать, Вы получите сигнал SIGPIPE. Если Вы SIG_IGN сигнал, то Ваша запись возвратится с ошибкой - и необходимо отметить и реагировать на ту ошибку. Просто ловля и игнорирование сигнала в обработчике не являются хорошей идеей - необходимо отметить, что канал является ныне несуществующим, и измените поведение программы, таким образом, это не пишет в канал снова (потому что сигнал будет сгенерирован снова и проигнорирован снова, и Вы попробуете еще раз, и целый процесс мог продолжиться для длинный время и потратить впустую большую мощность ЦП).
Или я должен просто поймать SIGPIPE с обработчиком и проигнорировать его?
я полагаю, что это правильно на. Вы хотите знать, когда другой конец закрыл их дескриптор, и это - то, что SIGPIPE говорит Вам.
Sam
Я очень опаздываю на вечеринку, но SO_NOSIGPIPE
не переносится и может не работать в вашей системе (похоже, это вещь BSD).
Хорошей альтернативой, если вы используете, скажем, систему Linux без SO_NOSIGPIPE
, было бы установить флаг MSG_NOSIGNAL
в вашем вызове send (2).
Пример замены write (...)
на send (..., MSG_NOSIGNAL)
(см. Комментарий nobar )
char buf[888];
//write( sockfd, buf, sizeof(buf) );
send( sockfd, buf, sizeof(buf), MSG_NOSIGNAL );
В этом сообщении я описал возможное решение для случая Solaris, когда недоступны ни SO_NOSIGPIPE, ни MSG_NOSIGNAL.
Вместо этого мы должны временно подавить SIGPIPE в текущем потоке, который выполняет код библиотеки. Вот как это сделать: чтобы подавить SIGPIPE, мы сначала проверяем, ожидает ли он. Если это так, это означает, что он заблокирован в этом потоке, и мы не должны ничего делать.Если библиотека генерирует дополнительный SIGPIPE, он будет объединен с ожидающим, и это не работает. Если SIGPIPE не ожидает обработки, мы блокируем его в этом потоке, а также проверяем, был ли он уже заблокирован. Тогда мы можем выполнять наши записи. Когда нам нужно восстановить SIGPIPE в исходное состояние, мы делаем следующее: если SIGPIPE изначально ожидал обработки, мы ничего не делаем. В противном случае мы проверяем, ожидает ли он сейчас. Если это так (что означает, что наши действия сгенерировали один или несколько SIGPIPE), мы ждем его в этом потоке, очищая, таким образом, его статус ожидания (для этого мы используем sigtimedwait () с нулевым таймаутом; это необходимо для предотвращения блокировки сценарий, при котором злонамеренный пользователь отправил SIGPIPE вручную всему процессу: в этом случае мы увидим его ожидающим, но другой поток может обработать его до того, как мы внесем изменения, чтобы дождаться его). После очистки состояния ожидания мы разблокируем SIGPIPE в этом потоке, но только если он не был заблокирован изначально.
Пример кода на https://github.com/kroki/XProbes/blob/1447f3d93b6dbf273919af15e59f35cca58fcc23/src/libxprobes.c#L156