<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>Swami Dhyan Nataraj</title>
  <link>https://nataraj.dreamwidth.org/</link>
  <description>Swami Dhyan Nataraj - Dreamwidth Studios</description>
  <lastBuildDate>Thu, 09 May 2024 12:06:09 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>nataraj</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <image>
    <url>https://v2.dreamwidth.org/12569540/750757</url>
    <title>Swami Dhyan Nataraj</title>
    <link>https://nataraj.dreamwidth.org/</link>
    <width>100</width>
    <height>100</height>
  </image>

<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/996069.html</guid>
  <pubDate>Thu, 09 May 2024 12:06:09 GMT</pubDate>
  <title>Как форкнуть процесс в соседний виртуальный терминал</title>
  <link>https://nataraj.dreamwidth.org/996069.html</link>
  <description>&lt;p&gt;Я люблю работать в консоли. Люблю автоматизацию скриптами. И если надо что-то массово параллельно обработать, то запустить все это в разных окнах tmux&apos;а или screen&apos;а, и любоваться процессом. И вот чего мне не хватало, так это возможности в каком-нибудь сложном скрипте наделать дочерних процессов и разложить их по разным окнам tmux&apos;а. Кажется что естественная хотелка, а вот как сделать -- не понятно. И вот дошли руки разобраться как же такой фокус делается&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;cutid1&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Переносим процесс в другую консоль&lt;/h1&gt;

&lt;p&gt;Для начала рассмотрим более простую задачу: как вообще в принципе перенести процесс из одной консоли в другую. В древние времена эта задача решалась ручной перепривязкой потоков ввода-вывода процесса к другому tty или каким-то подобным образом. В современном линуксе для этого есть утилита &lt;a href=&quot;https://github.com/nelhage/reptyr&quot;&gt;reptyr&lt;/a&gt; которая автоматически стырит для вас процесс из соседнего терминала и привяжет его к текущему. &lt;/p&gt;

&lt;p&gt;Предположим у вас есть программа:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    #!/usr/bin/perl

    print &quot;My PID is $$\n&quot;; # print current process PID;
    sleep 10;

    while(1){
      print ++$i, &quot;\n&quot;;
      sleep 1;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Эта программа выводит в консоль свой PID, и через некоторое время начинает в той же консоли считать секунды.&lt;/p&gt;

&lt;p&gt;Если запустить эту программу в одной консоли, а в соседней консоли выполнить команду &lt;/p&gt;

&lt;p&gt;&lt;code&gt;reptyr [PID-number]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;где &lt;code&gt;PID-number&lt;/code&gt; номер процесса который напечатала наша тестовая программа в самом начале, то выполнение программы в исходной консоли прекратиться, а в новой продолжиться как ни в чем ни бывало.&lt;/p&gt;

&lt;p&gt;Достаточно просто.&lt;/p&gt;

&lt;h1&gt;Перенос дочернего процесса в другую консоль&lt;/h1&gt;

&lt;p&gt;Однако если вы попробуете проделать тот же самый фокус не с отдельно работающей программой, а с дочерним процессом &lt;code&gt;reptyr&lt;/code&gt; на вас наругается:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    [-] Process 739989 (test2.pl) shares 739990&apos;s process group. Unable to attach.
    (This most commonly means that 739990 has sub-processes).
    Unable to attach to pid 739990: Invalid argument
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Дело в том, что когда вы делаете форк, порожденный процесс оказывается в одной группе с родительским процессом (и родительский процесс оказывается лидером группы), и по какой-то причине &lt;code&gt;reptyr&lt;/code&gt; с такой ситуацией не справляется. Поэтому прежде чем тырить дочерний процесс, надо сначала вывести его из группы. Делается это вызовом &lt;code&gt;setpgid&lt;/code&gt;, в котором дочерний процесс назначается сам себе лидером группы, и таким образом выходит из группы родительского процесса. После этого &lt;code&gt;reptyr&lt;/code&gt; вполне справляется с переносом дочернего процесса в новую консоль. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    #!/usr/bin/perl

    use POSIX;

    $pid = fork();
    if ($pid)
    {
      # parent process
      print &quot;Child PID is $pid\n&quot;;
      sleep 10;
      while (1) {print &quot;.\n&quot;; sleep 1};
    } else
    {
      # child process
      (setpgid($$,$$) != -1)           || die &quot;Can&apos;t set own group: $!&quot;;
      sleep 10;
      while (1) {print ++$i,&quot;\n&quot;; sleep 1};
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Эта программа выводит на экран &lt;code&gt;PID&lt;/code&gt; порожденного дочернего процесса, после чего спустя десять секунд, родительский процесс начинает выводить на экран точки с частотой один раз в секунду, а дочерний процесс начинает эти секунды вслух считать. Если не предпринимать никаких действий выводы обоих процессов будут смешаны в одной консоли, в которой их запустили. &lt;/p&gt;

&lt;p&gt;Однако если в соседнем терминале запустить&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reptyr [child-PID-number]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;где &lt;code&gt;child-PID-number&lt;/code&gt; -- &lt;code&gt;PID&lt;/code&gt; дочернего процесса напечатанный нашей программой, то в результате вывод дочернего процесса (цифры) переедет в новую консоль, а вывод родительского процесса (точки) останется в той консоли в которой его изначально запустили. &lt;/p&gt;

&lt;p&gt;Чего собственно говоря и хотелось добиться.&lt;/p&gt;

&lt;h1&gt;Материалы для раздумий&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Статья в которой подробно объясняется материал групп и сессий: &lt;a href=&quot;https://blog.nelhage.com/2011/02/changing-ctty/&quot;&gt;https://blog.nelhage.com/2011/02/changing-ctty/&lt;/a&gt; Понимание этого материала помогло таки найти финальное решение&lt;/li&gt;
&lt;li&gt;Мои попытки выспросить нужное решение на linux.org.ru: &lt;a href=&quot;https://www.linux.org.ru/forum/development/17555795&quot;&gt;https://www.linux.org.ru/forum/development/17555795&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Заметка на stackoverflow написанная по результатм: &lt;a href=&quot;https://stackoverflow.com/questions/78428371/how-to-fork-process-into-another-virtual-terminal/78428372&quot;&gt;https://stackoverflow.com/questions/78428371/how-to-fork-process-into-another-virtual-terminal/78428372&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=996069&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/996069.html</comments>
  <category>dev</category>
  <category>linux</category>
  <lj:security>public</lj:security>
  <lj:reply-count>8</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/994659.html</guid>
  <pubDate>Sun, 09 Jul 2023 11:50:58 GMT</pubDate>
  <title>Выпустил релиз игры Goblin Camp v0.23</title>
  <link>https://nataraj.dreamwidth.org/994659.html</link>
  <description>&lt;p&gt;Goblin Camp — попытка создать опенсорсный клон игры Dwarf Fortress. Смысл игры в управлении поселением Гоблинов (или в оригинале Гномов), при этом управления косвенного, в игре не предусмотрено прямого управления Гоблинами/Гномами, можно лишь ставить задачи в общем виде, а вот как подопечные поведут себя в результате — вопрос мастерства организации...&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://gitlab.com/dhyannataraj/goblin-camp/-/releases/v0.23&quot;&gt;https://gitlab.com/dhyannataraj/goblin-camp/-/releases/v0.23&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Изначально Goblin Camp написал некто Ilkka Halila, в 2010, повозился с ней годик и забросил. Мне как любителю Dwarf Fortress, Rim World и прочих симуляторов колоний с непрямым управлением, постоянно хотелось запустить в них руки, но сильно останавливала закрытость кода. Возможность писать моды есть, но тратить свое время на разбирательство в закрытом коде, я считаю неуважением к человечеству, поэтому стараюсь избегать к этого… И вот я в какой-то момент таки нашел ту программу в которую запустить руки не зазорно.&lt;/p&gt;

&lt;p&gt;На тот момент Gobln Camp была давно заброшена и категорически не собиралась на современных дистрибутивах. Пришлось приложить не нулевое количество усилий, чтобы оно заработало и задышало.&lt;/p&gt;

&lt;p&gt;Этот релиз закрывает проблему с работой графических тайлов. Оригинальная версия от Ilkka Halila использовала библиотеку SDL версии 1, а сейчас доступна только SDL2. Пришлось разбираться и переделывать.&lt;/p&gt;

&lt;p&gt;Кроме того, есть у меня подозрение, что графические тайлы там вообще никогда толком не работали: они не целиком загружались. Там были существенные проблемы с вычислением координат мышки и смещения при перетаскивании.&lt;/p&gt;

&lt;p&gt;Самый лучший баг был такой: если устроить перетаскивание и перемещать мышь строго влево-вверх, то при отпускании кнопки мыши, оно дополнительно срабатывало как однократное нажатие левой кнопки. Если был хоть раз в процессе вильнул вниз или вправо, эффекта не возникало.&lt;/p&gt;

&lt;p&gt;Плюс современная библиотека libtcod (которая лежит в основе движка игры) на этот старый код выдает кучу deprecation-warning’ов. Начал их постепенно зачищать…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog.nataraj.ru/static/media/C7881498-B8BD-96DE-B468-557D7F6C2039.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blog.nataraj.ru/~/It/%D0%92%D1%8B%D0%BF%D1%83%D1%81%D1%82%D0%B8%D0%BB%20%D1%80%D0%B5%D0%BB%D0%B8%D0%B7%20%D0%B8%D0%B3%D1%80%D1%8B%20Goblin%20Camp%20v0.23&quot;&gt;Оригинал&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=994659&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/994659.html</comments>
  <category>it</category>
  <category>dev</category>
  <category>c++</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/994413.html</guid>
  <pubDate>Sat, 01 Apr 2023 11:35:50 GMT</pubDate>
  <title>Еще один веселый способ выстрелить себе в ногу</title>
  <link>https://nataraj.dreamwidth.org/994413.html</link>
  <description>&lt;p&gt;Сижу, переделываю код. Есть необходимость отучить постгрес запускать разные сервисные процессы. Решил по случаю переделать это по уму...&lt;/p&gt;

&lt;p&gt;Переделываю кусок, запускаю, проверяю, переделываю, проверяю и тут падает оконная система... Вся.&lt;/p&gt;

&lt;p&gt;Логинюсь обратно, восстанавливаю рабочий контекст, перехожу к проверке и оконная система падает снова.&lt;/p&gt;

&lt;p&gt;Я, матерсь, выключаю компьютер, включаю компьютер, возвращаюсь к прерванной мысли, и оконная система падает снова.&lt;/p&gt;

&lt;p&gt;Понимая, что дальше работать несудьба, прикидывая чего такое в компе должно сдохнуть чтобы было вот так вот, в ужасе понимая, что если это проблема в железе, то вообще трындец, мне в понедельник надо выходить в онлайн, другого компа у меня нет, и на работе замену выдать не успеют, все будут на конференции, я сворачиваю работу и начинаю двигаться к следующей точке сегодняшнего дня.&lt;/p&gt;

&lt;p&gt;Пока еду, до меня начинает доходить...&lt;/p&gt;

&lt;p&gt;Там для порождения сервисных процессов есть спец. фабрика, которая в качестве результата возвращает pid нового процесса. Для оторванных процессов я стал возвращать -1.&lt;/p&gt;

&lt;p&gt;Видимо по какой-то своей внутренней логике, она после запуска сразу посылала одному из процессов какой-то сигнал (имеет право).
А в линуксе процесс с номером -1 — это корневой процесс (скажите sudo pkill -9 -1, только не на подакшене, плиз)&lt;/p&gt;

&lt;p&gt;Что это был за сигнал, и почему он будучи посланным от юзера (я постгрес запускал под собой) таки доходил до системного процесса — я не знаю, и наверное не буду разбираться, просто оторву посыл сигналов задезейбленным воркерам, благо там это тоже централизовано). Но эпичность допущенной ошибки меня восхитила. Можно мерить в сатиФаустах...&lt;/p&gt;

&lt;p&gt;PS: и да, оконная система падала по нажатию Ctrl+C. Нажимаешь Ctrl+С в консоле и исчезает всё включая консоль!&lt;/p&gt;

&lt;p&gt;Оно при принужительном завершении основного процесса кидало сигнал завершения детям, а он вместо этого уходил корневому процессу системы&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=994413&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/994413.html</comments>
  <category>dev</category>
  <lj:security>public</lj:security>
  <lj:reply-count>3</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/994285.html</guid>
  <pubDate>Thu, 28 Jul 2022 20:16:26 GMT</pubDate>
  <title>Призовая игра с встраиванием питона</title>
  <link>https://nataraj.dreamwidth.org/994285.html</link>
  <description>&lt;p&gt;Я не возьмусь определять что мне более отвратительно libboost или python. Но право скажу собранные вместе в boost::python они производят на свет субстанцию непревзойденного свойства.&lt;/p&gt;

&lt;pre&gt;
 #include &amp;lt;boost/python.hpp&amp;gt;
 #include &amp;lt;stdio.h&amp;gt;

int main()
{
  Py_InitializeEx(0);

  boost::python::object modMath = boost::python::import(&quot;math&quot;);
  boost::python::object cosFunc = modMath.attr(&quot;cos&quot;);

  Py_Finalize();
}
&lt;/pre&gt;

&lt;p&gt;С 2.7м питоном работает нормально, с третьем падает с невнятной ошибкой при отработке хуков при выходе...&lt;/p&gt;

&lt;p&gt;Историю с локализацией места проблемы в портируемой программе с последующим вынесением в приведенный standalone, я опущу из-за малосодержательности и нецензурности... Скажу только, что gdb плюс правильно выбранные места для breakpoint&apos;ов рулят.&lt;/p&gt;

&lt;p&gt;Далее в процессе плясок вокруг этого примера вдруг обнаруживаю что  вот так не падает:&lt;/p&gt;

&lt;pre&gt;
int main()
{
  Py_InitializeEx(0);
  {
    boost::python::object modMath = boost::python::import(&quot;math&quot;);
    boost::python::object cosFunc = modMath.attr(&quot;cos&quot;);
  }
  Py_Finalize();
}
&lt;/pre&gt;

&lt;p&gt;Ага! думаю я. Оно позвало деструктор до финалайза а не после и все перестало падать... Надо сделать так же!&lt;/p&gt;

&lt;p&gt;Но вот проблема... аналог переменной cosFunc в портируемой программе глобальная... Создается пустая, а потом после инициалайза заполняется. Можно было бы раскинуть мозгами, как запихнуть туда указатель вместо самого объекта, и сказать ему в нужный момент delete. Но менять весь остальной код очень не хотелось...&lt;/p&gt;

&lt;p&gt;А нельзя ли так, чтобы для сложного объекта вызвался деструктор а сам объект опять заполнить пустым значением?&lt;/p&gt;

&lt;p&gt;Оказывается можно:&lt;/p&gt;

&lt;pre&gt;
int main()
{
  Py_InitializeEx(0);
  boost::python::object cosFunc;
  {
    boost::python::object modMath  = boost::python::import(&quot;math&quot;);
    cosFunc = modMath.attr(&quot;cos&quot;);
  }
  cosFunc = boost::python::object();
  Py_Finalize();
}
&lt;/pre&gt;

&lt;p&gt;оно заменяет сложное значение &lt;code&gt;cosFunc&lt;/code&gt; тривиальным, при этом для заменяемого значения вызывается деструктор.&lt;/p&gt;

&lt;p&gt;И вот так -- тоже не падает...&lt;/p&gt;

&lt;p&gt;P.S. Отдельно доставила рекомендация документации на 1.55 boost::python просто не вызывать &lt;code&gt;Py_Finalize()&lt;/code&gt;, типа не надо вам это.&lt;/p&gt;

&lt;p&gt;P.P.S. Пришел к мысли что сам питон не падает только потому что и так ползает. And you should not boost it.&lt;/p&gt;

&lt;p&gt;P.P.P.S. Честно говоря не верил, что осилю с этим разобраться. Без знания, что буста, что питона... Ан нет, получилось...&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=994285&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/994285.html</comments>
  <category>извращения</category>
  <category>it</category>
  <category>dev</category>
  <lj:security>public</lj:security>
  <lj:reply-count>5</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/993763.html</guid>
  <pubDate>Sun, 24 Jul 2022 14:37:56 GMT</pubDate>
  <title>Этот ваш python течет...</title>
  <link>https://nataraj.dreamwidth.org/993763.html</link>
  <description>&lt;pre&gt;#include &amp;lt;Python.h&amp;gt;

int main()
{
  Py_Initialize();
  Py_Finalize();
}&lt;/pre&gt;

&lt;p&gt;Собрать с санитайзером ASan, хоть со вторым, хоть с третьим питоном&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clang-11  test.c  -fsanitize=address -g -O0 -I /usr/include/x86_64-linux-gnu/python2.7 -I /usr/include/python2.7 -lpython2.7&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clang-11  test.c  -fsanitize=address -g -O0 -I /usr/include/x86_64-linux-gnu/python3.9 -I /usr/include/python3.9 -lpython3.9&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Результат один: кучка мемори ликов. В 2.7 побольше, в 3.9 небольшая...&lt;/p&gt;

&lt;p&gt;А если под полезной нагрузкой, так их вообще на много экранов...&lt;/p&gt;

&lt;p&gt;И эти люди мне запрещают ковыряться в носу!&lt;/p&gt;

&lt;p&gt;Надо позаимствовать у Витуса тег &quot;злые люди&quot;....&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=993763&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/993763.html</comments>
  <category>dev</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/992927.html</guid>
  <pubDate>Wed, 06 Jul 2022 13:44:32 GMT</pubDate>
  <title>СЯУ How to git ignore</title>
  <link>https://nataraj.dreamwidth.org/992927.html</link>
  <description>&lt;p&gt;&lt;strong&gt;TL;TR:&lt;/strong&gt; это про &lt;code&gt;.git/info/exclude&lt;/code&gt;, если знаете, то можно пропускать.           &lt;/p&gt;

&lt;p&gt;С постгресом у меня была вечная проблема: я пытаюсь таки перейти на разработку в vim&apos;е (с переменным успехом, но последовательно движусь). Для того чтобы в vim&apos;е переходить по имени функции к месту ее определения нужно созать tags-файлы при помощи утилиты ctags. Все хорошо, но потом эти tags файлы в огромном количестве болтаются в выводе &lt;code&gt;git status&lt;/code&gt;. А если добаивть их в &lt;code&gt;.gitignore&lt;/code&gt; то надо постоянно следить за этой незакоммиченной правкой (в апстрим ее никто не возьмет)&lt;/p&gt;

&lt;p&gt;И вот мне это окончательно надоело и я пошел гуглить. Выяснилось, что есть еще локальный гитигнор, который называется &lt;code&gt;.git/info/exclude&lt;/code&gt;. Работает абсолютно идентично, но в remote не попадает.&lt;/p&gt;

&lt;p&gt;Добавил туда &lt;code&gt;tags&lt;/code&gt;, и теперь доволен как слон... :-)&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=992927&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/992927.html</comments>
  <category>сяу</category>
  <category>git</category>
  <category>dev</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/992328.html</guid>
  <pubDate>Sun, 03 Jul 2022 19:34:27 GMT</pubDate>
  <title>perl redo: Век живы, век учись</title>
  <link>https://nataraj.dreamwidth.org/992328.html</link>
  <description>Читая книжку по внутренностям perl&apos;а открыл для себя оператор `redo` который позволяет повторить выполнение блока кода. В случае если этот блок -- тело цикла, то цикл на следующую итерацию при этом не переходит:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
my $i=0;
foreach (1,2,3)
{
  print $_,&amp;quot;\n&amp;quot;;
  $i++;
  redo if $i&amp;lt;2;
}
&lt;/pre&gt;&lt;br /&gt;печатает &lt;br /&gt;&lt;pre&gt;
1
1
2
3
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;PS так, постойте... В DW был же маркдаун... Куда делася? Не вижу как включить...&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=992328&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/992328.html</comments>
  <category>it</category>
  <category>сяу</category>
  <category>perl</category>
  <category>dev</category>
  <lj:security>public</lj:security>
  <lj:reply-count>6</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/991085.html</guid>
  <pubDate>Tue, 14 Sep 2021 21:10:53 GMT</pubDate>
  <title>Structure Aware Fuzzing: синтаксическое дерево</title>
  <link>https://nataraj.dreamwidth.org/991085.html</link>
  <description>Краткое содержание предыдущих серий:&lt;br /&gt;&lt;br /&gt;Fuzzing -- метод тестирования когда в программу на вход подаются случайные данные.&lt;br /&gt;&lt;br /&gt;Structure Aware Fuzzing -- данные остаются все так же случайные, но все-таки синтаксически или структурно верные. Нужно чтобы проникнуть глубже синтаксического анализатора.&lt;br /&gt;&lt;br /&gt;LibBlobStamper -- библиотека которую я пишу, которая позволяет на основании псевдо случайных данных выдаваемых фаззером, воспроизводимо генерировать синтаксически корректные данные. &lt;a href=&quot;https://github.com/postgrespro/libblobstamper&quot;&gt;https://github.com/postgrespro/libblobstamper&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Вот сегодня у меня новое достижение. Я таки сумел сгенерировать данные под парсер синтаксических деревьев:&lt;br /&gt;&lt;br /&gt;&lt;a name=&quot;cutid1&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;
((((231 + 108) ^ ((39 - 156) ^ (((116 * 109) - (100 ^ (47 + 78))) / (206 / 166)))) ^ ((((253 - 125) + (171 * 215)) + (183 - (((162 / 178) - 23) - (199 + 10)))) - (192 * 61))) + (((((1 / 161) ^ 167) / (189 / 52)) * ((178 + 110) / ((((225 / 16) * 237) - 95) - 28))) * (((84 - 88) * (226 + 29)) - 180)))
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Там все пока что еще максимально сыро, много что прибито гвоздями и даже в основной код не затащено t/320-galley-recursion-experiments.cpp. Но работает, блин!&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=991085&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/991085.html</comments>
  <category>it</category>
  <category>fuzzing</category>
  <category>dev</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/990194.html</guid>
  <pubDate>Sun, 02 May 2021 20:05:12 GMT</pubDate>
  <title>Рабочие заметки тестера по-жизни</title>
  <link>https://nataraj.dreamwidth.org/990194.html</link>
  <description>Решил я инициализировать std::vector&lt;std::string&gt; массивом из без малого 40000 слов. Ну захотелось так...&lt;br /&gt;Собираться все это безобразие g++-8 решило аж полторы минуты, или clang-11 за 40 секунд.&lt;/std::string&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=990194&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/990194.html</comments>
  <category>dev</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/983408.html</guid>
  <pubDate>Wed, 08 Jan 2020 22:48:08 GMT</pubDate>
  <title>Собираем Goblin Camp</title>
  <link>https://nataraj.dreamwidth.org/983408.html</link>
  <description>У меня внезапно случился каникулярный проект.&lt;br /&gt;&lt;br /&gt;Вместо того чтобы нормально поработать, пока все отдыхают и от меня отстали, меня вставило, и я сделал еще один подход к попытке сборки игрушки Goblin Camp.&lt;br /&gt;&lt;br /&gt;Это, говорят, некая подобная Dwarf Fortress игра, которую забросили в 2012 году.&lt;br /&gt;&lt;br /&gt;Проблема с ней в том, что автор в качестве структуро-образующего фреймворка выбрал libboost, который в свою очередь оказался очень капризным и чувствительным к версиям практически всего...&lt;br /&gt;&lt;br /&gt;Сначала я пытался подобрать дистрибутив дебиана, собрав его в chroot&apos;е так чтобы нужная комбинация таки совпала... Я старательно пытался его ставить в разные позы с разными компиляторами, но не осилил. При этом часть проблем вылезала именно с внутренностями boost&apos;а который был приложен к исходникам программы. Это еще в прошлый подход.&lt;br /&gt;&lt;br /&gt;В этот подход я пришел к идее, что надо исключить из уравнения одну из переменных, или даже две. Попробовать собрать все это дело с бустом который идет в дебиане (благо к нему приложены все патчи необходимые для работы с идущим с дистрибутивом компиляторе) и выкинуть нафиг систему сборки bjam которая отдельно доставляет проблемы, и в которой вообще непонятно что происходит и собрать все нормальным cmake&apos;ом (на который, если продолжать возиться с проектом все равно переходить)&lt;br /&gt;&lt;br /&gt;И вот тут вот получилось. Не без проблем, libboost все равно показал себя как крайне не стабильная... мнэ... субстанция, но DuckDuckGo, StackOverfrow, strace и 83 кило упертости таки победили...&lt;br /&gt;&lt;br /&gt;Результат экзерсисов сложил в отдельную ветку и снабдил инструкцией.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/dhyannataraj/goblin-camp/tree/cmake-build&quot;&gt;https://gitlab.com/dhyannataraj/goblin-camp/tree/cmake-build&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=983408&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/983408.html</comments>
  <category>it</category>
  <category>dev</category>
  <category>c++</category>
  <lj:security>public</lj:security>
  <lj:reply-count>5</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/982626.html</guid>
  <pubDate>Sat, 05 Oct 2019 13:00:44 GMT</pubDate>
  <title>Патчи в постргес</title>
  <link>https://nataraj.dreamwidth.org/982626.html</link>
  <description>Меня можно поздравить с тем, что у меня таки приняли мелко-патчи в постгрес.&lt;br /&gt;До самого основного патча еще далеко, но уже хоть что-то. &lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/postgres/postgres/commit/773df883e8f7543958d0d719c025b5f47c5a67f0&quot;&gt;773df883&lt;/a&gt; - Support reloptions of enum type. В постгресе строковый тип опций таблиц использовался фактически как enum, всякий раз писать функцию валидации походу не правильно, лучше прямо сделать его enum&apos;ом.&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/postgres/postgres/commit/640c19869f8c4b5c34d3982b5e1cd40e62abbb85&quot;&gt;640c1986&lt;/a&gt; - Add dummy_index_am to src/test/modules/ so it can be used for test purposes and as an access method example&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=982626&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/982626.html</comments>
  <category>dev</category>
  <category>it</category>
  <category>postgres</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/978672.html</guid>
  <pubDate>Thu, 18 Apr 2019 10:57:22 GMT</pubDate>
  <title>Программстское портфолио (опенсорсное)</title>
  <link>https://nataraj.dreamwidth.org/978672.html</link>
  <description>Многое из того что я когда-то делал по программистской работе или не доступно окружающим, или уже более не используется, по независящим от меня причинам. Но еще есть опенсорс, и вот из него уж точно слова не выкинешь. В этом месте предполагается поместить сводный список моих опенсорсных достижений.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Postgres&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/postgres/postgres/commit/4cb658af70027c3544fb843d77b2e84028762747&quot;&gt;4cb658af&lt;/a&gt; - Refactor reloption handling for index AMs in-core - Не надо использовать StdRdOptions для хранения опций индексов, таская за собой не используемые для дела опции heap&apos;а&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/postgres/postgres/commit/1bbd608fdae7af314d8e2229e369a45a3da83cd8&quot;&gt;1bbd608f&lt;/a&gt; - Split handling of reloptions for partitioned tables - Партиционированные таблицы все равно не используют ни одной опции. Поэтому завязывать их хранение на StdRdOptions совершенно ни к чему.&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/postgres/postgres/commit/396773762425126a85243fc85a267d401496beb8&quot;&gt;39677376&lt;/a&gt; - Add some assertions to view reloption macros - Дополнительная проверка перед преобразованием типа &lt;br /&gt;&lt;a href=&quot;https://gitlab.com/postgres/postgres/commit/773df883e8f7543958d0d719c025b5f47c5a67f0&quot;&gt;773df883&lt;/a&gt; - Support reloptions of enum type. В постгресе строковый тип опций таблиц использовался фактически как enum, всякий раз писать функцию валидации походу не правильно, лучше прямо сделать его enum&apos;ом.&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/postgres/postgres/commit/640c19869f8c4b5c34d3982b5e1cd40e62abbb85&quot;&gt;640c1986&lt;/a&gt; - Add dummy_index_am to src/test/modules/ so it can be used for test purposes and as an access method example&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/postgres/postgres/commit/4b95cc1dc36c9d1971f757e9b519fcc442833f0e&quot;&gt;4b95cc1d&lt;/a&gt; - Add more tests for reloptions - Опции таблиц как выяснилось не тестировались ранее. Перед тем как их ломать, было решено для начала научиться тестировать то что есть. Правда с поламыванием воз и ныне там...&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/postgres/postgres/commit/d6061f83a166b015657fda8623c704fcb86930e9&quot;&gt;d6061f83&lt;/a&gt; - Improve pageinspect module - Модуль pageinspect позволяющий изучать страницы хранилища postgres, с помощью этого патча научился разбирать на части содержимое записи, и показывать их в человеко-читаемом виде.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;xmlsec&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/lsh123/xmlsec/commit/0606b7421d17b36600f27e338f82dd473d753ec9&quot;&gt;0606b742&lt;/a&gt; - Поддержка подписи GOST2012.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;AFL++&lt;/b&gt;&lt;br /&gt;&lt;a hfref=&quot;https://github.com/AFLplusplus/AFLplusplus/commit/3a6dea420fcf05cc2abff4199e35cb86316c961c&quot;&gt;3a6dea4&lt;/a&gt; &amp;ndash; расшифровка кода ошибки при получении свойств CPUs при определении количества доступных процессоров в &lt;code&gt;afl-gotcpu.c&lt;/code&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/AFLplusplus/AFLplusplus/commit/f3ec554803043cfe1e50a898f032936aa7819952&quot;&gt;f3ec554&lt;/a&gt; &amp;ndash; Показывать в заголовке окна фаззинга &quot;AFL&quot; вместо &quot;american fuzzy lop&quot; если user-defined часть заголовка слишклм длинная. (Позволяет задавать более длинные user-defined тексты в заголовке)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;LibTAP++&lt;/b&gt;&lt;br /&gt;Библиотека для TAP-тестирования C++&apos;ных проектов &lt;a href=&quot;https://gitlab.com/dhyannataraj/libtappp&quot;&gt;LibTAP++&lt;/a&gt; оказалась заброшена, пришлось взять над ней шефство и сделать форк.&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/dhyannataraj/libtappp/-/commit/153f1d11f92be9c5a4e78bb89cf206d70eb8e634&quot;&gt;153f1d11&lt;/a&gt; &amp;ndash; правки позволяющие использовать эту библиотеку в проектах использующих современные стандарты C++&lt;br /&gt;&lt;br /&gt;&lt;b&gt;perl&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;свои модули&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://metacpan.org/pod/Lingua::StarDict::Writer&quot;&gt;&lt;b&gt;Lingua::StarDict::Writer&lt;/b&gt;&lt;/a&gt; &amp;ndash; модуль для создания StarDict словарей&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;патчи&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;code&gt;Lingua::StarDict::Gen&lt;/code&gt;&lt;/b&gt; &amp;mdash; &lt;a href=&quot;https://metacpan.org/changes/distribution/Lingua-StarDict-Gen&quot;&gt;версия 0.09&lt;/a&gt;: исправил серьезную проблему с сортировкой из-за которой пропадали слова.&lt;br /&gt;&lt;b&gt;&lt;code&gt;Template&lt;/code&gt;&lt;/b&gt; &amp;mdash; &lt;a href=&quot;https://github.com/abw/Template2/commit/849569e84059538a5e20affd959b55b5a088c244&quot;&gt;849569e&lt;/a&gt;: доработка документации: доступ к элементам хэша со &quot;сложными&quot; именами&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Misc&lt;/b&gt;&lt;br /&gt;&lt;i&gt;subtutleeditor&lt;/i&gt; - &lt;a hferf=&quot;https://github.com/kitone/subtitleeditor/commit/1dd00d036344f72ab8d647d3f5614940c95e2384&quot;&gt;1dd00d03&lt;/a&gt; - Fix building with older version of enchant - у кого-то в системе был уже enchant-2 и он послал фикс для сборки. А в дебиане до сих пор enchant без двойки, в результате собираться перестало. Сделал так чтобы собиралось в обоих случаях.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;KDE networkmanagement&lt;/i&gt; - &lt;a href=&quot;https://cgit.kde.org/networkmanagement.git/commit/?id=99d3dbe854029cd3df593e6398ff73921ce7ea15&quot;&gt;99d3dbe8&lt;/a&gt; - Show APN string for the APN selected by the user in Mobile Connection - чего-то оно там неправильно показывало при настройке USB-модема. Давно это было.&lt;br /&gt;&lt;i&gt;KDE networkmanagement&lt;/i&gt; - &lt;a href=&quot;https://cgit.kde.org/networkmanagement.git/commit/?id=d395cfe7037ae7abd7d10c6b742657771d4c61a0&quot;&gt;d395cfe7&lt;/a&gt; - Hide non-Internet APNs in Mobile Connection Wizard.- В serviceproviders.xml начали разделять APN&apos;ы по типам назначения (internet|mms|wap) а KDE&apos;шный network manager об этом не знал, и показывал все в кучу.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;preeny&lt;/i&gt; &amp;ndash; &lt;a href=&quot;https://github.com/zardus/preeny/commit/e317826b59f177b57207d0d85e3fb03262559b61&quot;&gt;e317826&lt;/a&gt;: добавил библиотеку &lt;code&gt;setstdin&lt;/code&gt; позволяющая, через подмену системных вызовов подавать программе требуемые данные на стандартный вход. Нужен этот инструмент например при фаззинге, например AFL++&apos;ом, когда другого способа передать какую-либо константную строку на вход исследуемой программе просто нету.&lt;br /&gt;&lt;br /&gt;*будет пополняться*&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=978672&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/978672.html</comments>
  <category>it</category>
  <category>прикрепленные посты</category>
  <category>dev</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/977593.html</guid>
  <pubDate>Sun, 31 Mar 2019 20:07:44 GMT</pubDate>
  <title>pg-dev: Налаживаемость патчей из коммитфеста</title>
  <link>https://nataraj.dreamwidth.org/977593.html</link>
  <description>и не только налаживаемость. Но еще и компилируемость...&lt;br /&gt;&lt;br /&gt;Для тех кто занимается разработкой постгреса. В рассылке товарищи показали интересный сервис:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://commitfest.cputube.org/&quot;&gt;http://commitfest.cputube.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Там для патчей текущего и предстоящего комитфеста приведена статистика того как эти патчи накладываются на текущей мастер, и собираются ли после этого. В том числе и виндой. Что чертовски полезно для нашей безвиндовой ситуации...&lt;br /&gt;&lt;br /&gt;Чего этому сервису не хватает, так это системы оповещений. Я по всей видимости буду писать скриптик который из моих статусов (ну и не только моих, пусть в параметрах указывается) будет делать RSS-feed.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=977593&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/977593.html</comments>
  <category>dev</category>
  <category>it</category>
  <category>postgres</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/976586.html</guid>
  <pubDate>Fri, 08 Mar 2019 13:32:35 GMT</pubDate>
  <title>Недостаточно магии...</title>
  <link>https://nataraj.dreamwidth.org/976586.html</link>
  <description>&lt;pre&gt;ERROR:  incompatible library &quot;/home/nataraj/.../lib/postgresql/dummy_index.so&quot;: missing magic block
HINT:  Extension libraries are required to use the PG_MODULE_MAGIC macro.&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=976586&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/976586.html</comments>
  <category>dev</category>
  <category>postgres</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/975289.html</guid>
  <pubDate>Sun, 17 Feb 2019 19:09:51 GMT</pubDate>
  <title>Вопрос суровым vim&apos;ерам про git</title>
  <link>https://nataraj.dreamwidth.org/975289.html</link>
  <description>А кто-нибудь знает, можно ли обучить vim подсвечивать строки которые появились после коммита N?&lt;br /&gt;&lt;br /&gt;Вот чтобы типа создал ветку, наложил патч, закоммитил, и далее видишь, какие строки приехали из мастера, какие с патчем, а какие ты сам нарисовал после и еще не закоммитил...&lt;br /&gt;&lt;br /&gt;Было бы очень удобно... Бывает ли такое? мне чего-то не нагуглилось...&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=975289&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/975289.html</comments>
  <category>vim</category>
  <category>dev</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/973161.html</guid>
  <pubDate>Tue, 01 Jan 2019 18:18:23 GMT</pubDate>
  <title>Слава извращенцам</title>
  <link>https://nataraj.dreamwidth.org/973161.html</link>
  <description>Понадобилось мне собрать пострес под винду (там какая-то MSVS-специфичная ошибка). Надо. А трогать эту субстанцию больше необходимого ну очень не хочется.&lt;br /&gt;Коллега поделился образом вируталки в которой все окружение для сборки уже подготовлено, только клонируй и запусти. Спасибо коллеге...&lt;br /&gt;&lt;br /&gt;Преодолевая трудности (нельзя просто так взять и сделать бридж для вайфайной карты) пытаюсь ее запустить у себя на ноутбуке. Ноут не тянет... Он и фейсбук в браузере не очень тянет, какая виртуалка...&lt;br /&gt;&lt;br /&gt;Хорошо, обращаюсь к знакомому, у которого на рабочих станциях лиукс, типа дай погонять... Он говорит, что погонять не даст, но выдаст свой старый виндовый комп, который мощнее всех его линуксовых, за одно и линукс на него типа поставишь...&lt;br /&gt;&lt;br /&gt;Преодолевая трудности (нет драйверов для сиди-рома, дебиановский лайв-сиди почему-то не видит сетевуху), перекидываю данные с самого маленького диска на остальные (их там много было) и ставлю на малый диск линукс...&lt;br /&gt;&lt;br /&gt;Тут выясняется что на этот маленький диск образ виртуалки просто не помещается... Диск совсем маленький. Ну я в результате кладу его на диски с данными которые от винды остались, ntfs&apos;ные...&lt;br /&gt;&lt;br /&gt;Итого. Для того чтобы собрать постгрес под винду, я снес винду, чтобы поставить линукс, положить  виртуалку на ntfs&apos;ный диск запустить винду в виртуалке и таки собрать постгрес...&lt;br /&gt;&lt;br /&gt;И вы еще удивляетесь что я медленно программирую...&lt;br /&gt;&lt;br /&gt;PS поставил бы еще тег &quot;слабоумие и отвага&quot;, но он про другое...&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=973161&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/973161.html</comments>
  <category>it</category>
  <category>postgres</category>
  <category>dev</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/972908.html</guid>
  <pubDate>Tue, 01 Jan 2019 16:07:32 GMT</pubDate>
  <title>Using vim for postgres development</title>
  <link>https://nataraj.dreamwidth.org/972908.html</link>
  <description>I&apos;ve written a wiki article about configuring vim for postgres development.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://wiki.postgresql.org/wiki/Configuring_vim_for_postgres_development&quot;&gt;https://wiki.postgresql.org/wiki/Configuring_vim_for_postgres_development&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I actually started to restore my vim configuration (I&apos;ve lost it some time ago) and found out that these information is scattered along the web. And it is better to keep it in one place.&lt;br /&gt;&lt;br /&gt;I&apos;ve described in the article all options and plugins that I used for pg development.&lt;br /&gt;&lt;br /&gt;If you have your own vim experience and know some tools that can be used to make development and following codestyle more easy, please add them there.&lt;br /&gt;&lt;br /&gt;PS. I&apos;ve already written about it to the mailing list. Just want to write about it in the blog too...&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=972908&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/972908.html</comments>
  <category>dev</category>
  <category>postgres_en</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/971488.html</guid>
  <pubDate>Sun, 25 Nov 2018 13:44:05 GMT</pubDate>
  <title>вопрос по git</title>
  <link>https://nataraj.dreamwidth.org/971488.html</link>
  <description>Вот например некто ведет разработку, и в процессе ведения шел патчи. И каждая новая версия патча -- улучшенная версия предыдущего.&lt;br /&gt;И если для первого патча, я создаю ветку от master&apos;а и накладываю патч, то как быть для второй версии этого патча, мне не понятно.&lt;br /&gt;Накладывать второй патч так же надо на мастер. Но должен он оказаться в той же ветке что и первый патч, просто следующим коммитом. Как быть. Какой workfwolw правильный?&lt;br /&gt;&lt;br /&gt;git checkout master&lt;br /&gt;git branch patch_v1&lt;br /&gt;git checkout patch_v1&lt;br /&gt;pathc -p1 &amp;lt;patch_vi.diff&lt;br /&gt;git commit -a&lt;br /&gt;&lt;br /&gt;git checkout master&lt;br /&gt;git branch patch_v2&lt;br /&gt;git checkout patch_v2&lt;br /&gt;pathc -p2 &amp;lt;patch_vi.diff&lt;br /&gt;git commit -a&lt;br /&gt;&lt;br /&gt;git rebase patch_v1&lt;br /&gt;&lt;br /&gt;(Я так не пробовал. Боюсь ;-) )&lt;br /&gt;&lt;br /&gt;Как вы решаете такие задачи?&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=971488&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/971488.html</comments>
  <category>it</category>
  <category>dev</category>
  <category>git</category>
  <lj:security>public</lj:security>
  <lj:reply-count>10</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/966391.html</guid>
  <pubDate>Fri, 07 Sep 2018 10:33:15 GMT</pubDate>
  <title>Таки похоже GitLab</title>
  <link>https://nataraj.dreamwidth.org/966391.html</link>
  <description>После некоторых размышлений, пришел к выводу что Git-проекты следует таки переносить на GitLab. Он как никак опенсорсный (хотя ставил я его, это долбанный набор скриптов неустановленного качества непонятно чем повязанный). Отдельно на bitbucket&apos;е меня отвратила atlassian-авторизация... Не хочу корпораций. Даже среднего размера...&lt;br /&gt;&lt;br /&gt;Хотя конечно гитлаб -- тот еще гугл, судя по историям поглащений. Но пока маленький и не супер опасный. И внятной альтернативы не вижу...&lt;br /&gt;&lt;br /&gt;В остальном меня на github&apos;е ничего не держит, кроме pull-реквестов к gost-engine&apos;у... Ну это мы как-то переживем... Буду по ходу дела мигрировать... &lt;a href=&quot;https://gitlab.com/dhyannataraj/&quot;&gt;https://gitlab.com/dhyannataraj/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;PS и да, если кто-то знает лучшую альтернативу -- сообщайте...&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=966391&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/966391.html</comments>
  <category>dev</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/958117.html</guid>
  <pubDate>Mon, 16 Apr 2018 20:59:09 GMT</pubDate>
  <title>Программистский дыбр</title>
  <link>https://nataraj.dreamwidth.org/958117.html</link>
  <description>Мои фрагментарные патчи постгресса перенесли на следующий коммит-фест, который будет уже в сентябре, после релиза. Наверное надо будет что-то ревьюйнуть. Видимо посмотреть предложенный Глуховский патч, раз уж он по моей теме топчится... Но это когда цикл задач снова до постгресса дойдет. А вообще все это оч. сильно фрустрирует. Че-то я все меньше и меньше уверен в том, что хочу на таких условиях в постгресе ковыряться.&lt;br /&gt;&lt;br /&gt;Стоящую на повестке дня документацию для gost engine&apos;а ковырять откровенно лень и не хочется. Но видимо надо будет в какой-то момент себя заставить.&lt;br /&gt;&lt;br /&gt;Вместо этого я занялся другим знатным извращением. Похоже что Opticbook 3800 сам себя в SANE не добавит, и с этим надо что-то делать... При том что там известный чип под который есть бэкенд. С вероятностью удастся обойтись малой кровью. Но для этого все равно надо начать понимать код и USB-шную мать его специфику. Для этого я по дешевке прикупил поддерживаемый сканер с аналогичным чипом, и собираюсь ставить эксперименты сначала над ним. Я собираюсь статически прилинковать бэкенд к испоняемому бинарнику и научиться из него мануально ставить сканер в требуемую мне позу: моргать лампой, ездить головой.&lt;br /&gt;&lt;br /&gt;Пока у меня получилось прилинковать бэкенд и опросить сканеры (и получить почему-то пустой список). Все осложняется тем, что оно желает automake&apos;а более старого чем тот, что у меня на ноутбуке, и разработку приходится вести в двух точках: в lxc-контейнере запускать automake, если поправить Makefile.am, и результат перекидывать на ноут, где есть физический usb.&lt;br /&gt;&lt;br /&gt;Короче, это должна получиться славная охота, если удастся это провернуть до конца...&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=958117&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/958117.html</comments>
  <category>it</category>
  <category>dev</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/953404.html</guid>
  <pubDate>Sun, 04 Mar 2018 18:50:53 GMT</pubDate>
  <title>Вопрос по Си</title>
  <link>https://nataraj.dreamwidth.org/953404.html</link>
  <description>&lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;https://vitus-wagner.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/silk/identity/user.png&apos; alt=&apos;[personal profile] &apos; width=&apos;17&apos; height=&apos;17&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;https://vitus-wagner.dreamwidth.org/&apos;&gt;&lt;b&gt;vitus_wagner&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;https://beldmit.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/silk/identity/user.png&apos; alt=&apos;[personal profile] &apos; width=&apos;17&apos; height=&apos;17&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;https://beldmit.dreamwidth.org/&apos;&gt;&lt;b&gt;beldmit&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, ну и кто еще в теме разбирается...&lt;br /&gt;&lt;br /&gt;Расскажите, насколько легальна в Си вот такая штука:&lt;br /&gt;&lt;br /&gt;Есть некий массив сопоставляющий имя и значение, и есть еще возможность значения по умолчанию, которое имени не имеет.&lt;br /&gt;&lt;br /&gt;Чувак предлагает делать так: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#define NAME_DEFAULT ((const char *) -1)        /* pseudo-name for default value */&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;А потом проверять &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if(Chto_to-&amp;gt;name == NAME_DEFAULT)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Где name -- это char*&lt;br /&gt;&lt;br /&gt;Для меня это какое-то страшное сишное конлдунство, я не могу оценить насколько оно корректно и переносимо между компиляторами.&lt;br /&gt;&lt;br /&gt;Потому как я бы право слово скорее #define NAME_DEFAULT &quot;&quot; сделал бы. Ибо пустого имени все равно не бывает. И потом при помощи сравнения строк его проверял бы. Но может это у меня просто нету правильной сишной закалки.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=953404&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/953404.html</comments>
  <category>dev</category>
  <category>c</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>19</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/953113.html</guid>
  <pubDate>Wed, 28 Feb 2018 15:12:47 GMT</pubDate>
  <title>postgres_commitfest_feed окупился</title>
  <link>https://nataraj.dreamwidth.org/953113.html</link>
  <description>&lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;https://postgres-commitfest-feed.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/silk/identity/feed.png&apos; alt=&apos;[syndicated profile] &apos; width=&apos;16&apos; height=&apos;16&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;https://postgres-commitfest-feed.dreamwidth.org/&apos;&gt;&lt;b&gt;postgres_commitfest_feed&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; уже окупился. Отловил желающего потоптаться по той части кода, которую я сейчас ковыряю. Прямо на ранних подступах отловил.&lt;br /&gt;Польза.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=953113&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/953113.html</comments>
  <category>dev</category>
  <category>postgres</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/952975.html</guid>
  <pubDate>Tue, 27 Feb 2018 10:44:08 GMT</pubDate>
  <title>perl: Ловим утечки памяти</title>
  <link>https://nataraj.dreamwidth.org/952975.html</link>
  <description>Заметка скорее для себя, чем...&lt;br /&gt;&lt;br /&gt;Если быть более точным, то не ловим, а убеждаемся что они есть, и по возможности локализуем.&lt;br /&gt;Значит есть такой модуль Memory::Usage &lt;a name=&quot;cutid1&quot;&gt;&lt;/a&gt;, он по факту лазиет в /proc и запоминает информацию о памяти потребляемой процессом. Его после инициальизации дергаешь время от времени. После чего получаешь от него сводку, че было с памятью. &lt;br /&gt;&lt;br /&gt;Я делал это так:&lt;br /&gt;&lt;pre&gt;use Memory::Usage;                                                                                                                                                                              
use IO::Socket::SSL;                                                                                                                                                                            
                                                                                                                                                                                                
my $mu = Memory::Usage-&amp;gt;new();                                                                                                                                                                  
                                                                                                                                                                                                
foreach my $i(1..5)                                                                                                                                                                             
{                                                                                                                                                                                               
  print $i,&quot;\n&quot;;                                                                                                                                                                                
  $mu-&amp;gt;record($i);                                                                                                                                                                              
  foreach (1..100)                                                                                                                                                                              
  {                                                                                                                                                                                             
    # то что как мы предполагаем течет памятью                                                                                                                                                  
    my $cl = IO::Socket::SSL-&amp;gt;new(&apos;ru.wikipedia.org:443&apos;);
    close $cl;
  }                                                                                                                                                                                             
}                                                                                                                                                                                               
                                                                                                                                                                                                
$mu-&amp;gt;dump();&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;И получал вот такой вот вывод:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;  time    vsz (  diff)    rss (  diff) shared (  diff)   code (  diff)   data (  diff)
     0  14460 ( 14460)  10576 ( 10576)   5012 (  5012)   1840 (  1840)   5660 (  5660) 1
    17  16788 (  2328)  14136 (  3560)   6416 (  1404)   1840 (     0)   7852 (  2192) 2
    34  17844 (  1056)  15244 (  1108)   6416 (     0)   1840 (     0)   8908 (  1056) 3
    50  18900 (  1056)  16356 (  1112)   6416 (     0)   1840 (     0)   9964 (  1056) 4
    67  20088 (  1188)  17464 (  1108)   6416 (     0)   1840 (     0)  11152 (  1188) 5&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;По которому видно, что расход памяти постоянно растет, несмотря на то что мы только и делаем, что открываем сокет и закрываем его.&lt;br /&gt;&lt;br /&gt;Помимо этого модуля есть еще Test::LeakTrace который вроде как умеет следить за тем, какие скаляры появились в памяти пока исполнялся заданный участок кода, но я так и не разобрался как им пользоваться, мне в него попадает всякая внутренняя перловая кухня, из серии подключение новых package&apos;ей и т.п. Может когда-то в будущем...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=952975&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/952975.html</comments>
  <category>dev</category>
  <category>perl</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/952348.html</guid>
  <pubDate>Thu, 22 Feb 2018 18:05:20 GMT</pubDate>
  <title>Постгресодыбр</title>
  <link>https://nataraj.dreamwidth.org/952348.html</link>
  <description>Медленно но верно движусь в направлении закрытия своих опесорсных долгов.&lt;br /&gt;А то патчи понимаешь, написаны, но не зкаоммичены. Безобразие.&lt;br /&gt;Мой мега патч полностью переделывающий работу с опциятми таблиц был в результате мучительно медленного взаимодействия с комьюнити порезан на части и отправлен на коммитфест.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://commitfest.postgresql.org/15/1314/&quot;&gt;https://commitfest.postgresql.org/15/1314/&lt;/a&gt; (уже закомимчен) - тесты на работу опций таблицы. (Таковых раньше не было)&lt;br /&gt;&lt;a href=&quot;https://commitfest.postgresql.org/17/1489/&quot;&gt;https://commitfest.postgresql.org/17/1489/&lt;/a&gt; - добавляет тип опции Enum (а то раньше его по сути эмулировали строковой опцией, с рукописной функции валидации)&lt;br /&gt;&lt;a href=&quot;https://commitfest.postgresql.org/17/1536/&quot;&gt;https://commitfest.postgresql.org/17/1536/&lt;/a&gt; - вместо единого бинарного преставления опций для более половины типов relation&apos;ов, вводит индивидуальные представления на каждый тип. Иначе получалось, что задаешь ты индексу fillfactor  а память под него резервируется на все опции которые возможны для heap&apos;а. Потому что универсально.&lt;br /&gt;&lt;br /&gt;Последнее вот только что доковырял.&lt;br /&gt;Как последние два закоммитят, можно будет финальный патч коммитить. Который старый механизм работы опций разрушает до основания, а затем...&lt;br /&gt;&lt;br /&gt;Еще есть странный &lt;a href=&quot;https://commitfest.postgresql.org/17/1486/&quot;&gt;https://commitfest.postgresql.org/17/1486/&lt;/a&gt; который тоже к теме опций отношения имеет.&lt;br /&gt;Там история в том, что если задать опции работы TOAST&apos;а для таблицы в которой TOAST&apos;а нет, то постгрес это молча съест, а значения опций просто потеряются. Я в этом патче предлагаю непущать, но в рассылке меня убедили что так нельзя. Поэтому наверное вместо этого надо будет пренудительно создавать TOAST-таблицу ставить туда опции и предупреждать, что &quot;чувак, ты что-то странное делаешь&quot;. Но пока какой-то финальной отмашки я в рассылке не получил, и непонятно, получу ли...&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=952348&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/952348.html</comments>
  <category>dev</category>
  <category>postgres</category>
  <category>it</category>
  <lj:security>public</lj:security>
  <lj:reply-count>7</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://nataraj.dreamwidth.org/952294.html</guid>
  <pubDate>Tue, 30 Jan 2018 14:21:04 GMT</pubDate>
  <title>An RSS feed with new Commitfest patches</title>
  <link>https://nataraj.dreamwidth.org/952294.html</link>
  <description>Hi!&lt;br /&gt;&lt;br /&gt;I&apos;d like to tell everybody that I&apos;ve created an RSS feed that streams notification about new patches posted to Postgres Commitfest.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://perl.nataraj.su/commitfest-rss/commitfest-rss.pl&quot;&gt;http://perl.nataraj.su/commitfest-rss/commitfest-rss.pl&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now it just parses the site and make a feed from that data. If you also use RSS feeds and like to watch for new commits, feel free to use it.&lt;br /&gt;&lt;br /&gt;May be once this feature will be implemented in commitfest.postgresql.org. But I am not able to implement it there myself as I do not write python.&lt;br /&gt;&lt;br /&gt;Source code of the script can be found at &lt;a href=&quot;https://www.postgresql.org/message-id/3411074.go5RRV3d10%40x200m&quot;&gt;my message to psql-www mailing list&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Feel free to write comments in that mail-list, personal email, or in the blog (you will need OpenID to authorize there)&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=nataraj&amp;ditemid=952294&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://nataraj.dreamwidth.org/952294.html</comments>
  <category>dev</category>
  <category>it</category>
  <category>postgres_en</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
</channel>
</rss>
