<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>.:: Jorge Pereira ::. &#187; C/C++</title>
	<atom:link href="http://blog.jorgepereira.com.br/category/c-cpp/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jorgepereira.com.br</link>
	<description>"UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity."</description>
	<lastBuildDate>Thu, 01 Jul 2010 04:16:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>- Depuração: Parte 1</title>
		<link>http://blog.jorgepereira.com.br/2010/07/01/depuracao-parte-1/</link>
		<comments>http://blog.jorgepereira.com.br/2010/07/01/depuracao-parte-1/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 03:06:46 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Outros]]></category>
		<category><![CDATA[linux depuração]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=952</guid>
		<description><![CDATA[Seja Elegante Talvez possa ser algo que passe despercebido por vários desenvolvedores, porém dúvido quem nunca tenha se deparado com mensagens de &#8220;log&#8221; vagas ou sem nenhum nexo ou bem pior, como mensagens idênticas replicadas por várias partes do código! A algum tempo atrás estava trabalhando em um projeto em que um respectivo desenvolvedor da [...]]]></description>
			<content:encoded><![CDATA[<blockquote>
<h2>Seja Elegante</h2>
</blockquote>
<p>Talvez possa ser algo que passe despercebido por vários desenvolvedores, porém dúvido quem nunca tenha se deparado com mensagens de &#8220;log&#8221; vagas ou sem nenhum nexo ou bem pior, como mensagens idênticas replicadas por várias partes do código!  <img src='http://blog.jorgepereira.com.br/jorge/wp-includes/images/smilies/icon_eek.gif' alt=':shock:' class='wp-smiley' /><br />
A algum tempo atrás estava trabalhando em um projeto em que <em>um respectivo desenvolvedor</em> da equipe possuia o costume de espalhar ou replicar centenas de printf() pelo código com mensagens tipo!</p>
<p>printf(&#8220;!!! FULANO &#8211; Aqui!!!&#8221;);</p>
<p>ou</p>
<p>printf(&#8220;!!! FULANO &#8211; Arquivo.cpp:  Aqui!!!\n&#8221;);</p>
<p>Precisa falar que isto e pessímo? Certo que e preciso um bom senso com o uso de mensagens de depuração pois dependendo ao invés de ajudar podem só atrapalhar. principalmente quando você necessita ter controle sobre tais mensagens, como por exemplo obter a localização da mensagem através do nome da função, arquivo e linha.</p>
<p><div class="note"><div class="notewarning">Lembrando que dependendo da situação e contexto eu sou a favor de utilizar o pragma no compilador ativando o &#8220;<em><a href="http://en.wikipedia.org/wiki/Directive_(programming)" target="_blank">poison</a></em>&#8221; desativando dentre várias funções o printf (), evitando de ter espalhada pelo sistema! Futuramente um post sobre o <em>poison</em>. </div></div></p>
<p>O pré-processador do GCC oferece (*) várias macros, as que irei utilizar em questão são:</p>
<ul>
<li>__FILE__ : Substituída pelo nome do arquivo.</li>
<li>__PRETTY_FUNCTION__ : Substituídas pelo nome nome da função.</li>
<li>__LINE__ : Substituída pelo número da linha de código.</li>
</ul>
<p>(*) <a href="http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html" target="_blank">Mais detalhes sobre as macros do GCC.</a></p>
<p><a href="http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html" target="_blank"></a>A utilização dessas macros irá facilitar a localização das mensagens de depuração, Abaixo um simples exemplo demonstrado em <a href="http://blog.jorgepereira.com.br/jorge/wp-content/uploads/2010/06/debug1.c">debug1.c</a>.</p>
<pre class="brush:csharp">/**
 * By Jorge Pereira &lt;jpereiran@gmail.com&gt;
 * Date: Tue Jun 29 02:51:44 BRT 2010
 */

#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

// Macro condicional
#ifdef DEBUG
#	warning "Debug is enabled"
#	define TRACE_DEBUG(fmt, ...) \
	fprintf(stderr, " ** DEBUG: %s:%d %s(): "fmt"\n", \
	__FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)
#else
#	warning "Debug is disabled"
#	define TRACE_DEBUG(fmt, ...)
#endif

#define MAX_STRING 5 /* tamanho maximo de uma string */

// Função simples de exemplo...
void
show_name (const char* name,
		   size_t len)
{
	size_t offset = len;

	// Verificação qualquer...
	if (len &gt; MAX_STRING)
	{
		// Abaixo mensagem de depuração, perceba que ela será ativada apenas
                // quando em tempo de compilação você ativar a macro "<strong>DEBUG</strong>"
		TRACE_DEBUG ("Ooops! Tamanho da string(%d) e excedeu o limite(%d)...",
			len, MAX_STRING);
		offset = MAX_STRING;
	}

	// Manipulação qualquer...
	write (STDOUT_FILENO, name, offset);
	write (STDOUT_FILENO, "\n", 1);
}

int
main (int argc, char* argv[])
{
	if (argc &lt; 2)
	{
		printf ("Usage: %s &lt;string&gt;\n", argv[0]);
		exit (1);
	}

	show_name (argv[1], strlen (argv[1]));

	return 0;
}</pre>
<p>Com este exemplo básico em mãos, vamos compilar e executar.</p>
<pre>[jpereira@miracleworld Codes]$ gcc -Wall -o debug1 debug1.c
debug1.c:18:3: warning: #warning "Debug is disabled"
[jpereira@miracleworld Codes]$ ./debug1 "Jorge"
Jorge
[jpereira@miracleworld Codes]$ ./debug1 "Jorge Pereira"
Jorge
[jpereira@miracleworld Codes]$</pre>
<p>Imagine que seu sistema possui inúmeros arquivos e você precisa em determinados pontos obter o máximo de informação sobre as mensagens de depuração, talvez seja interessante ter além de uma mensagem objetiva obter juntamente o nome da função, arquivo e linha de onde foi invocada tal mensagem.</p>
<pre>[jpereira@miracleworld Codes]$ gcc -Wall -DDEBUG -o debug1 debug1.c
debug1.c:13:3: warning: #warning "Debug is enabled"
[jpereira@miracleworld Codes]$ ./debug1 "Jorge"
Jorge
[jpereira@miracleworld Codes]$ ./debug1 "Jorge Pereira"
 ** DEBUG: <strong>debug1.c:36 show_name()</strong>: Ooops! Tamanho da string(13) e excedeu o limite(5)...
Jorge
[jpereira@miracleworld Codes]$</pre>
<p><div class="note"><div class="notetip"> Agora veja situação que você está trabalhando em um sistema com várias checagens complexas de cenários <em>&#8220;nada convencionais&#8221;</em> em que você não tem certeza se vai acontecer sempre ou não.<br />
Sem falar que torna-se um atrativo a possibilidade de você poder ativar/desativar o simples mecanismo, como por exemplo poder criar macros para depuração de componentes específicos (ex.: relacionadas a sockets, I/O, sgdb, &#8230;), isto poderá facilitar a identificação e remoção de bugs.</div></div></p>
<p><div class="note"><div class="noteclassic">Lembrando que este e o primeiro post entre vários que pretendo publicar relacionados a sugestões e técnicas de depuração. Fique de olho na segunda parte desta <em>saga</em> em que irei explicar uma mais dinâmica do mesmo assunto abordado neste post associando ao uso de variáveis de ambiente.<br />
Dúvidas e Sugestões, são sempre bem vindas! <img src='http://blog.jorgepereira.com.br/jorge/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  </div></div></p>
<p>Autor: Jorge Pereira</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2010/07/01/depuracao-parte-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>- Introdução aos Linux Device Drivers (ILDD)</title>
		<link>http://blog.jorgepereira.com.br/2010/06/21/introducao-aos-linux-device-drivers-ildd/</link>
		<comments>http://blog.jorgepereira.com.br/2010/06/21/introducao-aos-linux-device-drivers-ildd/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 20:10:00 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[drivers kernel linux]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=1031</guid>
		<description><![CDATA[Olá, Caso você tenha necessidade ou curiosidade em relação a Device Drivers no Linux, este com certeza será um bom material para iniciar-se na &#8220;brincadeira&#8221;. Introdução aos Linux Device Drivers (ILDD) é um curso que tem por objectivo apresentar os princípios básicos do desenvolvimento de device drivers no Linux kernel. Pretende-se com este curso, que [...]]]></description>
			<content:encoded><![CDATA[<p>Olá,</p>
<p>Caso você tenha necessidade ou curiosidade em relação a <em>Device Drivers</em> no Linux, este com certeza será um bom material para iniciar-se na &#8220;brincadeira&#8221;.</p>
<p style="text-align: center;"><img class="size-full wp-image-1043 aligncenter" title="Linux Device Driver" src="http://blog.jorgepereira.com.br/jorge/wp-content/uploads/2010/06/device_driver.jpg" alt="" width="241" height="241" /></p>
<blockquote><p><em>Introdução aos Linux Device Drivers (ILDD) é um curso que tem por objectivo apresentar os princípios básicos do desenvolvimento de </em><a href="http://en.wikipedia.org/wiki/Device_driver" target="_blank"><em>device drivers</em></a><em> no </em><a href="http://en.wikipedia.org/wiki/Linux" target="_blank"><em>Linux</em></a><em> </em><a href="http://www.kernel.org" target="_blank"><em>kernel</em></a><em>. Pretende-se com este curso, que o leitor tenha contacto com várias ferramentas e sub-sistemas existentes no </em><a href="http://www.kernel.org" target="_blank"><em>kernel</em></a><em>, adquirindo assim as bases que lhe irão permitir desenvolver o suporte para a grande maioria dos dispositivos. Alguns dos temas introduzidos são: estrutura básica de um device driver, comunicação com o userspace, memória dinâmica, eventos assíncronos, primitivas de sincronização e comunicação com o hardware.</em></p>
<p><em>Este curso aborda o tema de uma perspectiva pedagógica, através da sistematização dos conceitos em conjunto com uma forte componente prática, na qual se convida o leitor à implementação gradual de um </em><a href="http://en.wikipedia.org/wiki/Device_driver" target="_blank"><em>device driver</em></a><em> que dará suporte a um dispositivo especificamente concebido para o efeito. O leitor poderá ainda consultar a literatura de referência, de onde se destacam os excelentes títulos: </em><a href="http://lwn.net/Kernel/LDD3" target="_blank"><em>Linux Device Drivers</em></a><em>, </em><a href="http://www.oreilly.com/catalog/linuxkernel" target="_blank"><em>Understanding the Linux Kernel</em></a><em> e </em><a href="http://www.kroah.com/lkn" target="_blank"><em>Linux Kernel in a Nutshell</em></a><em>.</em></p>
<p><em>O autor, com a ajuda dos seus revisores, investiu mais de um ano de trabalho na elaboração e preparação deste curso, no sentido de oferecer à comunidade, não só um manual de aprendizagem abrangente, mas também uma importante referência futura. Caso encontre alguns erros ou tenha sugestões que visam melhorar ou complementar este trabalho, não hesite em </em><a href="http://www.adassumpcao.net/contacts"><em>contactar</em></a><em> o autor.</em></p></blockquote>
<p><a href="http://www.adassumpcao.net/introducao-aos-linux-device-drivers" target="_blank">Download aqui</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2010/06/21/introducao-aos-linux-device-drivers-ildd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>- Conhecendo e utilizando a LD_PRELOAD</title>
		<link>http://blog.jorgepereira.com.br/2010/06/11/conhecendo-e-utilizando-a-ld_preload/</link>
		<comments>http://blog.jorgepereira.com.br/2010/06/11/conhecendo-e-utilizando-a-ld_preload/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 06:55:59 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Outros]]></category>
		<category><![CDATA[ld_preload linux hacking]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=460</guid>
		<description><![CDATA[Muitas pessoas utilizam, utilizaram ou vão utilizar a variável LD_PRELOAD, e por sua vez nem sempre sabem para que ela serve! Caso este seja o seu problema, problema este não mais será!! O que acontece basicamente e que o linker dinâmico do Linux (assim como em tantos outros sistemas operacionais) utiliza diversas formas, alguma delas [...]]]></description>
			<content:encoded><![CDATA[<p>Muitas pessoas utilizam, utilizaram ou vão utilizar a variável <strong>LD_PRELOAD</strong>, e por sua vez nem sempre sabem para que ela serve! Caso este seja o seu problema, problema este não mais será!! <img src='http://blog.jorgepereira.com.br/jorge/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>O que acontece basicamente e que o linker dinâmico do Linux (assim como em tantos outros sistemas operacionais) utiliza diversas formas, alguma delas sendo através de variáveis de ambiente para controlar seu comportamento. Sendo que neste caso a variável <strong>LD_PRELOAD</strong> informa ao linker dinâmico que carregue as bibliotecas listadas nela antes de carregar quaisquer outras bibliotecas necessárias, enquando <strong>LD_LIBRARY_PATH</strong> especifica um caminho alternativo para usar ao procurar bibliotecas que serão carregadas.</p>
<p>Partindo deste principio podemos fazer com que um programa a ser executado seja &#8220;hijacked&#8221; por outro programa, ou seja. Podemos fazer por <em>exemplo</em> que a função hehe() previamente chamada pelo programa &#8220;A&#8221; tenha seu comportamento alterado sem precisar fazer quaisquer alteração no programa &#8220;A&#8221;. Um pouco complexo? talvez! Mais vamos por a mão na massa! hands on!</p>
<p>Digamos que você tem o programa &#8220;main&#8221; conforme o código de exemplo abaixo, perceba que o código e super simples. apenas declaro um ponteiro de caracteres, aloco memória e em seguida copio uma sequência de caracteres para o ponteiro previamente alocado. Simples, certo?</p>
<p>1) Abaixo código de exemplo de nosso &#8220;<a href="http://blog.jorgepereira.com.br/jorge/wp-content/uploads/2010/06/main.c">main.c</a>&#8221; ou clique aqui para download.</p>
<pre class="brush:csharp">/*
 *  Filename: hijack_main.c
 *  Created: Wed Jun  9 22:11:12 BRT 2010
 *  Author: Jorge Pereira &lt;jpereiran@gmail.com&gt;
 */
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

int
main (int argc,
      char* argv[])
{
  char* nome = (char*)malloc (100);

  strcpy (nome, "Jorge Pereira");
  printf ("NOME: %s\n", nome);

  free (nome);
  return 0;
}</pre>
<p># Vamos compilar e executar o nosso exemplo &#8220;main.c&#8221;</p>
<pre>$ gcc -Wall -o main main.c
$ ./main
NOME: Jorge Pereira
$</pre>
<p>Até aqui tudo bem, porém imagine você em uma determinada situação em que precisa saber quantos bytes está sendo alocado por um determinado programa? e você por alguns instantes imagina sobre a possibilidade de poder fazer algum tipo de &#8220;overload&#8221; de uma determinada função na qual você conhece sua assinatura. (Digamos, você sabe a assinatura do método, quantidade e tipos dos parâmetros, &#8230;).</p>
<p>Pois bem, neste exemplo que irei demonstrar será para sobrecarregar todas as chamadas feitas pelo meu programa &#8220;main&#8221; às funções malloc() e free() e em seguida exibir uma mensagem no caso do malloc() imprimindo seu parâmetro que e o tamanho de bytes alocados, e na função free() exibindo os ponteiros que foram liberados.</p>
<p>Neste caso, iremos criar uma biblioteca chamada &#8220;libhijack_hehe.so&#8221; que será carregada através da variável mágica <strong>LD_PRELOAD</strong> em parceria com nosso querido linker dinâmico.</p>
<p>2) Abaixo código de exemplo de &#8220;<a href="http://blog.jorgepereira.com.br/jorge/wp-content/uploads/2010/06/hijack_hehe.c">hijack_hehe.c</a>&#8220;, ou clique aqui para download.</p>
<pre class="brush:csharp">/*
 *  Filename: hijack_hehe.c
 *  Created: Wed Jun  9 22:11:12 BRT 2010
 *  Author: Jorge Pereira &lt;jpereiran@gmail.com&gt;
 */
#define _GNU_SOURCE
#include &lt;stdint.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdarg.h&gt;

#include &lt;dlfcn.h&gt;

#define HIJACK_DEBUG(fmt, ...) \
	fprintf(stderr, " ** DEBUG: %s:%d %s(): "fmt"\n", \
	__FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)

static void* (*hack_malloc)(size_t size) = NULL;
static void  (*hack_free)(void *p) = NULL;

static void* rest_malloc = NULL;

void*
malloc (size_t size)
{
  if (hack_malloc == NULL)
  {
    hack_malloc = (void *(*)(size_t)) dlsym (RTLD_NEXT, "malloc");
    rest_malloc = NULL;
  }

  if (rest_malloc == NULL)
  {
    rest_malloc = hack_malloc (size);
    HIJACK_DEBUG ("Alocando (%d) bytes, chunck(%p)", size, (void*)rest_malloc);
    return rest_malloc;
  }

  hack_malloc = NULL;
  return rest_malloc;
}

void
free (void *p)
{
	HIJACK_DEBUG ("Desalocando (%p)", p);

  if (hack_free == NULL)
  {
    hack_free = (void (*)(void *)) dlsym(RTLD_NEXT, "free");
  }

  hack_free (p);
}</pre>
<p>Agora vamos compilar, executar e analisar o comportamento.</p>
<pre>$ gcc -Wall -shared -ldl -o libhijack_hehe.so hijack_hehe.c
$ LD_PRELOAD=./libhijack_hehe.so ./main
 ** DEBUG: hijack_hehe.c:35 malloc(): Alocando (100) bytes, chunck(0x9273008)
NOME: Jorge Pereira
 ** DEBUG: hijack_hehe.c:46 free(): Desalocando (0x9273008)
$</pre>
<p>Percebeu algo diferente na execução com a <strong>LD_PRELOAD</strong> passando como parâmetro a nossa libhijack_hehe.so? pois bem, todas as chamadas às funções malloc() e free() foram sobrecarregadas e passaram a se comportar conforme as versões que escrevi em <strong>hijack_hehe.c</strong>. Caso tenha ficado curioso, e so re-escrever tais exemplos com outras funções que você deseja sobrecarregar e ver o comportamento. Lembrando que basta utilizar a criatividade e perceberá na quantidade de coisas que podem ser feita com tal técnica.</p>
<p>Exemplo: Nas funções que fazem checagem com strcmp(), uso da crypt(), &#8230; entre outras.</p>
<p>Referências</p>
<ul>
<li>man 8 ld.so</li>
</ul>
<p><strong> Autor: </strong>Jorge Pereira<br />
<strong> Data:</strong> Wed Jun  9 23:42:26 BRT 2010</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2010/06/11/conhecendo-e-utilizando-a-ld_preload/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>- Diferenças entre Glibc x uClibc</title>
		<link>http://blog.jorgepereira.com.br/2009/01/26/diferencas-entre-glibc-x-uclibc/</link>
		<comments>http://blog.jorgepereira.com.br/2009/01/26/diferencas-entre-glibc-x-uclibc/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 10:01:12 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[glibc]]></category>
		<category><![CDATA[uclib]]></category>
		<category><![CDATA[uclinux]]></category>
		<category><![CDATA[wrt54g]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=92</guid>
		<description><![CDATA[Esses dias estava conversando com um amigo sobre um projeto simples utilizando uClinux / uClibc em um dispositivo WRT54g, quando também falamos sobre algumas peculiaridades em relação ao uso da Glibc e uClibc. Para aqueles que nunca tiveram lido sobre o assunto e tem curiosidade, uma dica seria o texto abaixo, pois irá ter uma [...]]]></description>
			<content:encoded><![CDATA[<p>Esses dias estava conversando com um amigo sobre um projeto simples utilizando <a href="http://www.uclinux.org" target="_blank"><em>uClinux</em></a> / <a href="http://www.uclibc.org/" target="_blank"><em>uClibc</em></a> em um dispositivo <em><a href="http://en.wikipedia.org/wiki/Linksys_WRT54G_series" target="_blank">WRT54g</a></em>, quando também falamos sobre algumas peculiaridades em relação ao uso da <a href="http://pt.wikipedia.org/wiki/GNU_C_Library" target="_blank"><em>Glibc</em></a> e <a href="http://www.uclibc.org/" target="_blank"><em>uClibc.</em></a> Para aqueles que nunca tiveram lido sobre o assunto e tem curiosidade, uma dica seria o texto abaixo, pois irá ter uma idéia sobre as principais diferenças entre as duas bibliotecas.  <img src='http://blog.jorgepereira.com.br/jorge/wp-includes/images/smilies/icon_biggrin.gif' alt=':grin:' class='wp-smiley' /> </p>
<p style="text-align: center;"><a href="http://www.uclibc.org/downloads/Glibc_vs_uClibc_Differences.txt" target="_blank">Glibc x uClibc<br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2009/01/26/diferencas-entre-glibc-x-uclibc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>- Checando processos com a libproc</title>
		<link>http://blog.jorgepereira.com.br/2009/01/13/checando-processos-com-a-libproc/</link>
		<comments>http://blog.jorgepereira.com.br/2009/01/13/checando-processos-com-a-libproc/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 17:18:44 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[procps]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=421</guid>
		<description><![CDATA[Creio que quase todas as pessoas que utilizam Linux tiveram a necessidade de utilizar algum dos comandos kill, killall, ps, pgrep,&#8230; entre tantos outros programas que fazem parte do pacote procps[1]. Justamente a minha necessidade foi diferente, estava precisando em algum momento verificar se um determinado executável estava em execução na lista de processos, foi [...]]]></description>
			<content:encoded><![CDATA[<p>Creio que quase todas as pessoas que utilizam Linux tiveram a necessidade de utilizar algum dos comandos <em>kill, killall, ps, pgrep</em>,&#8230; entre tantos outros programas que fazem parte do pacote procps[1].</p>
<p>Justamente a minha necessidade foi diferente, estava precisando em algum momento verificar se um determinado executável estava em execução na lista de processos, foi desta forma que baixei o código fonte do pacote procps e fui da uma olhada para entender sua API que por sinal não existe nenhuma documentação! isto mesmo, existe apenas o pacote <em>procps</em> e o <em>procps-devel</em> que possui os headers utilizado para a acessar os métodos existentes na <em>libproc</em> (geralmente em /lib/libproc.so) conforme abaixo.</p>
<p><strong>[jpereira@jiraya codes]$</strong> ls -1 /usr/include/procps/<br />
alloc.h<br />
devname.h<br />
escape.h<br />
procps.h<br />
pwcache.h<br />
readproc.h<br />
sig.h<br />
slab.h<br />
sysinfo.h<br />
version.h<br />
wchan.h<br />
whattime.h<br />
<strong>[jpereira@jiraya codes]$</strong></p>
<p>Desta forma segue um simples código de exemplo utilizado para verificar se o programa especifico passado como parâmetro está em execução.</p>
<pre class="brush:csharp">/**
 * Autor: Jorge Pereira &lt;jpereiran@gmail.com&gt;
 * Data:  Ter Jan 13 14:29:29 BRST 2009
 * Desc:  Simples aplicacao utilizada para verificar se existe um
 * processo em execucao utilizando a procps (libproc)
 *
 * Build: gcc -o checkps checkps.c -lproc
 **/
#include &lt;string.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stddef.h&gt;
#include &lt;stdbool.h&gt;

#include &lt;readproc.h&gt;

bool check_process(const char *proc)
{
	int32_t flags = 0;
	PROCTAB *ptp  = NULL;
	bool 	 st   = false;
	proc_t task;

	memset(&amp;task, 0, sizeof (task));

	if (!proc || strlen(proc) &lt; 1)
		return false;

	flags = PROC_FILLCOM | PROC_FILLSTATUS;

	if ((ptp = openproc (flags)) == NULL)
		return false;

	while(!st &amp;&amp; readproc(ptp, &amp;task))
	{
        const char *cmd = (task.cmdline != NULL) ? task.cmdline[0] : task.cmd;

		st = !strncmp(proc, cmd, strlen(proc));
		memset (&amp;task, 0, sizeof (task));
	}

	closeproc (ptp);

    return st;
}

int main (int argc, char *argv[])
{
    if (argc &lt; 2)
    {
        printf ("Usage: %s &lt;nome do processo&gt;\n", argv[0]);
        exit(EXIT_SUCCESS);
    }

    printf("O Programa (%s) %sesta em execucao\n", argv[1], check_process(argv[1]) ? "" : "nao ");

    return EXIT_SUCCESS;
}</pre>
<p>Baixando este código de exemplo, compilando e fazendo uma checagem se existe o processo &#8220;dbus-launch&#8221; em execução! <img src='http://blog.jorgepereira.com.br/jorge/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>[jpereira@jiraya tmp]$</strong><strong> </strong>wget http://blog.jorgepereira.com.br/jorge/wp-content/uploads/2009/01/checkps.c<strong><br />
</strong><strong>[jpereira@jiraya tmp]$</strong><strong> </strong>gcc -o checkps checkps.c -lproc<strong><br />
</strong><strong>[jpereira@jiraya tmp]$</strong> ./checkps dbus-launch<strong><br />
</strong>O Programa (<em>dbus-launch</em>) está em execução<strong><br />
</strong><strong>[jpereira@jiraya tmp]$</strong><strong> </strong>./checkps dbus-lanche<strong><br />
</strong>O Programa (<em>dbus-lanche</em>) não está em execução<strong><br />
</strong><strong>[jpereira@jiraya tmp]$</strong><strong><br />
</strong></p>
<ul>
<li><a href="http://procps.sourceforge.net/" target="_blank">Mais informações sobre o procps</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2009/01/13/checando-processos-com-a-libproc/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>- C++ Portability Guide</title>
		<link>http://blog.jorgepereira.com.br/2008/12/19/c-portability-guide/</link>
		<comments>http://blog.jorgepereira.com.br/2008/12/19/c-portability-guide/#comments</comments>
		<pubDate>Fri, 19 Dec 2008 20:14:40 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[c/c++]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=407</guid>
		<description><![CDATA[Para aqueles que precisam desenvolver aplicações em C++ que seja o mais portável possível entre compiladores, ótimo quando durante o desenvolvimento existe a necessidade que o mesmo código ou boa parte seja portável o suficiente para rodar no Linux e no Win32. Este sem sombra de dúvidas e um excelente documento desenvolvido e utilizado no [...]]]></description>
			<content:encoded><![CDATA[<p>Para aqueles que precisam desenvolver aplicações em C++ que seja o mais portável possível entre compiladores, ótimo quando durante o desenvolvimento existe a necessidade que o mesmo código ou boa parte seja portável o suficiente para rodar no Linux e no Win32.</p>
<p>Este sem sombra de dúvidas e um excelente documento desenvolvido e utilizado no desenvolvimento do Mozilla, vale a pena conferir!</p>
<p><a href="https://developer.mozilla.org/En/C___Portability_Guide" target="_blank"><img class="aligncenter size-full wp-image-408" title="Mozilla Developer Center" src="http://blog.jorgepereira.com.br/jorge/wp-content/uploads/2008/12/mdc-logo.png" alt="" width="262" height="42" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2008/12/19/c-portability-guide/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>- utilizando mmap() para mapear arquivos na memoria</title>
		<link>http://blog.jorgepereira.com.br/2008/10/09/utilizando-mmap-para-mapear-arquivos-na-memoria/</link>
		<comments>http://blog.jorgepereira.com.br/2008/10/09/utilizando-mmap-para-mapear-arquivos-na-memoria/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 02:02:00 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[mmap]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=143</guid>
		<description><![CDATA[&#8230; Conforme definição do Wikipédia sobre a chamada mmap(), vemos abaixo! Em computação, mmap é uma chamada de sistema do Unix, em conformidade com o POSIX, que mapeia arquivos ou dispositivos na memória. É um método de E/S de arquivo mapeado em memória. Ela implementa naturalmente a paginação por demanda, pois os conteúdos iniciais dos [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230; Conforme definição do <a href="http://pt.wikipedia.org/wiki/Mmap" target="_blank">Wikipédia</a> sobre a chamada <strong><em>mmap()</em></strong>, vemos abaixo!</p>
<blockquote><p><em>Em <a title="Computação" href="http://pt.wikipedia.org/wiki/Computa%C3%A7%C3%A3o">computação</a>, <strong>mmap</strong> é uma <a title="Chamada de sistema" href="http://pt.wikipedia.org/wiki/Chamada_de_sistema">chamada de sistema</a> do <a title="Unix" href="http://pt.wikipedia.org/wiki/Unix">Unix</a>, em conformidade com o <a title="POSIX" href="http://pt.wikipedia.org/wiki/POSIX">POSIX</a>, que mapeia <a title="Arquivo" href="http://pt.wikipedia.org/wiki/Arquivo">arquivos</a> ou dispositivos na memória. É um método de E/S de arquivo mapeado em memória. Ela implementa naturalmente a <a title="Paginação" href="http://pt.wikipedia.org/wiki/Pagina%C3%A7%C3%A3o">paginação</a> por demanda, pois os conteúdos iniciais dos arquivos não são inteiramente lidos do disco e não usam a <a class="mw-redirect" title="Memória RAM" href="http://pt.wikipedia.org/wiki/Mem%C3%B3ria_RAM">memória RAM</a> física completamente. A real leitura do disco é feita de maneira &#8220;preguiçosa&#8221;, após uma posição específica ter sido acessada.</em></p></blockquote>
<p>Ou seja, podemos fazer muitas coisas utilizando a chamada <em>mmap()</em>, principalmente quando e preciso manipular arquivos de grande portes, e você não quer ter <em>buffers</em> auxiliares entre tantas outras possibilidades, que na grande maioria seguimos o seguinte fluxo.</p>
<p style="text-align: center;">open() -&gt; read() || write() -&gt; close()</p>
<p>Abaixo segue o  código <a href="http://blog.jorgepereira.com.br/jorge/wp-content/uploads/2008/10/cp-no-mmap.c">cp-no-mmap.c</a> detalhando melhor meu comentário!</p>
<pre class="brush:csharp">/**
 * Autor: Jorge Pereira
 * Data: Thu Oct  9 22:47:47 BRT 2008
 * Desc: Exemplo de um codigo para copia de arquivos.
 * Arquivo: cp-no-mmap.c
 */
#include &lt;stdio.h&gt;
#include &lt;stdint.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;err.h&gt;

#define IO_SIZE 4096

int
main(int argc, char *argv[])
{
int32_t fdr, fdw;
ssize_t reads;

/* Como de costume, temos um buffer temporario para auxiliar a copia */
char buf[IO_SIZE];

if(argc &lt; 3)
{
  printf("Usage: %s  \n", argv[0]);
  exit(EXIT_FAILURE);
}

/* Arquivo de origem */
fdr = open(argv[1], O_RDONLY);
if(fdr &lt; 0)
{
  err(1, "Falha ao abrir (%s)", argv[1]);
  exit(EXIT_FAILURE);
}

/* Arquivo de destino */
fdw = open(argv[2], O_CREAT | O_RDWR, 0644);
if(fdw &lt; 0)
{
  err(1, "Falha ao abrir (%s)", argv[2]);
  exit(EXIT_FAILURE);
}

/* Inicio da copia */
while ((reads = read(fdr, buf, sizeof(buf))) &gt; 0)
{
  if(write(fdw, buf, reads) &lt; reads)
  {
    err(1, "Problemas com write()");
    break;
  }
}

/* fechando os descritores */
close(fdr);
close(fdw);

return EXIT_SUCCESS;
}</pre>
<p>O Arquivo de exemplo se chama &#8220;Prison.Break.S04E07.HDTV.XviD-0TV.avi&#8221;, abaixo segue o tamanho dele para termos idéia em relação ao tempo de cópia!</p>
<p><strong>[jpereira@jiraya blog]$</strong> ls -lh Prison.Break.S04E07.HDTV.XviD-0TV.avi<br />
-rw-r&#8211;r&#8211; 1 jpereiran jpereiran <strong>351M</strong> 2008-10-09 22:06 Prison.Break.S04E07.HDTV.XviD-0TV.avi<br />
<strong>[jpereira@jiraya blog]$</strong> gcc -o cp-no-mmap cp-no-mmap.c<br />
<strong>[jpereira@jiraya blog]$</strong> time ./cp-no-mmap Prison.Break.S04E07.HDTV.XviD-0TV.avi Prison.Break.S04E07.HDTV.XviD-0TV.avi.copia<br />
<strong>real    0m3.115s</strong><br />
user    0m0.008s<br />
sys     0m2.496s<br />
<strong>[jpereiran@jiraya blog]$</strong></p>
<p>Agora veremos exemplo do mesmo código chamado <a href="http://blog.jorgepereira.com.br/jorge/wp-content/uploads/2008/10/cp-mmap.c">cp-mmap.c</a> utilizando uma chamada <em>mmap()</em>, fazendo com que todos os <em>bytes</em> lidos pela chamada <em>read()</em> sejam salvos em uma região de memória previamente mapeada para que possamos efetuar operações de leitura, e escrita caso seja necessário! repare que não esta sendo utilizado um buffer auxiliar para salvar os dados do <em>read()</em>, como e feito de costume! <img src='http://blog.jorgepereira.com.br/jorge/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush:csharp">/**
 * Autor: Jorge Pereira
 * Data: Thu Oct  9 22:47:47 BRT 2008
 * Desc: Exemplo de um codigo para copia de arquivos utilizando mmap()
 * Arquivo: cp-mmap.c
 */
#include &lt;stdio.h&gt;
#include &lt;stdint.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;err.h&gt;

#define IO_SIZE 4096

int
main(int argc, char *argv[])
{
int32_t fdr, fdw, fdm;
ssize_t reads;
/* repare que ao inves de utilizarmos um buffer auxilia, iremos ter um ponteiro apenas */
void *mem;

if(argc &lt; 3)
{
  printf("Usage: %s  \n", argv[0]);
  exit(EXIT_FAILURE);
}

/* Arquivo de origem */
fdr = open(argv[1], O_RDONLY);
if(fdr &lt; 0)
{
  err(1, "Falha ao abrir (%s)", argv[1]);
  exit(EXIT_FAILURE);
}

/* Arquivo de destino */
fdw = open(argv[2], O_CREAT | O_RDWR, 0644);
if(fdw &lt; 0)
{
  err(1, "Falha ao abrir (%s)", argv[2]);
  exit(EXIT_FAILURE);
}

/* tal device abaixo ira prover caracteres nulos '\0', estaremos apenas fazendo
* o mapeamento do dispositivo para uma regiao de memoria com tamanho definido
* neste caso por "IO_SIZE", com protecao R+W e sendo visivel apenas para o
* processo corrente, sem offsets referente a paginas de memoria.
*
* 1) Abrindo o device /dev/zero
* 2) Fazendo o mapeamento na linha 67
*
* OBS: Na duvida consulte a man do mmap(), e veja um exemplo utilizando mais
* detalhes conforme sua necessidade!
*/
if((fdm = open("/dev/zero", O_RDWR)) &lt; 0)
{
  err(1, "Falha ao abrir (%s)", argv[2]);
  exit(EXIT_FAILURE);
}
mem = mmap(NULL, IO_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fdm, 0);
close(fdm);

/**
* Inicio da copia, repare que estamos lendo do disco e "copiando" para regiao
* de  memoria mapeada, e escrevendo apartir do mesmo mapeamento! funcionando
* como uma variavel temporaria.
*/
while ((reads = read(fdr, mem, IO_SIZE)) &gt; 0)
{
  if(write(fdw, mem, reads) &lt; reads)
  {
    err(1, "Problemas com write()");
    break;
 }
}

munmap(mem, IO_SIZE);

/* fechando os descritores */
close(fdr);
close(fdw);

return EXIT_SUCCESS;
}</pre>
<p>Abaixo vamos compilar e fazer o mesmo teste, copiando o mesmo arquivo!<br />
<strong>[jpereira@jiraya blog]$</strong> gcc -o cp-mmap cp-mmap.c<br />
<strong>[jpereira@jiraya blog]$</strong> time ./cp-mmap Prison.Break.S04E07.HDTV.XviD-0TV.avi Prison.Break.S04E07.HDTV.XviD-0TV.avi.copia<br />
real     <strong>0m2.777s</strong><br />
user    0m0.020s<br />
sys     0m2.056s<br />
<strong>[jpereiran@jiraya blog]$</strong></p>
<p><strong>Conclusão</strong></p>
<p>Repare que o ganho e imperceptível quando executamos tais rotinas em computadores x86 compostos de processadores de alta capacidade, sem falar dos discos rígidos de alta rotação! certo?<br />
Porém quando você está trabalhando em um ambiente embarcado limitado de recursos, que quaisquer ganho de performance e velocidade e bem vindo! este foi meu caso em que precisava-se efetuar operações de I/O em um SD-CARD com um processador ARM um tanto quanto &#8220;humilde&#8221;, e tais dados além de ser copiados eram necessário gerar chaves MD5 entre outros detalhes com tal <em>stream</em> de dado, lembro que o ganho ficou por volta de 20% e 30% com o mapeamento utilizando <em>mmap(). </em>Dúvidas e comentários serão bem vindos</p>
<p><strong>Referências</strong></p>
<ul>
<li>man 2 open</li>
<li>man 2 mmap</li>
<li>http://www.gnu.org/software/libtool/manual/libc/Memory_002dmapped-I_002fO.html</li>
</ul>
<p><strong>Autor</strong></p>
<p>Jorge Pereira</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2008/10/09/utilizando-mmap-para-mapear-arquivos-na-memoria/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>- Ponteiros? Agora você aprende!</title>
		<link>http://blog.jorgepereira.com.br/2008/09/24/ponteiros-agora-voce-aprende/</link>
		<comments>http://blog.jorgepereira.com.br/2008/09/24/ponteiros-agora-voce-aprende/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 00:18:57 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=141</guid>
		<description><![CDATA[Muitas pessoas reclamam por não entender sobre ponteiros, então segue um video explicando passo-a-passo sobre o assunto, bem hilário o video!]]></description>
			<content:encoded><![CDATA[<p>Muitas pessoas reclamam por não entender sobre <a href="http://en.wikipedia.org/wiki/Pointer" target="_blank">ponteiros</a>, então segue um video explicando passo-a-passo sobre o assunto, bem hilário o video! <img src='http://blog.jorgepereira.com.br/jorge/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align: center;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="src" value="http://www.youtube.com/v/CObg3tbT2lg&amp;hl=en&amp;fs=1" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/CObg3tbT2lg&amp;hl=en&amp;fs=1" allowfullscreen="true"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2008/09/24/ponteiros-agora-voce-aprende/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>- Mandamentos do desenvolvedor UNIX</title>
		<link>http://blog.jorgepereira.com.br/2008/09/13/mandamentos-do-desenvolvedor-unix/</link>
		<comments>http://blog.jorgepereira.com.br/2008/09/13/mandamentos-do-desenvolvedor-unix/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 23:35:22 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=91</guid>
		<description><![CDATA[Ao decorrer deste POST você irá perceber que não tem os famosos dez mandamentos, e sim alguns passos! Porém a idéia e citar algumas obras para que os interessados sobre o assunto tenham como uma referência em seus estudos, uma citação seria Henry Spencer Coding Style [1]. Sem nenhuma sombra de dúvida, um dos guidelines [...]]]></description>
			<content:encoded><![CDATA[<p>Ao decorrer deste POST você irá perceber que não tem os famosos dez mandamentos, e sim alguns passos! Porém a idéia e citar algumas obras para que os interessados sobre o assunto tenham como uma referência em seus estudos, uma citação seria <em>Henry Spencer Coding Style</em> [1]. Sem nenhuma sombra de dúvida, um dos guidelines mais famoso de C e seu nome original é <em>&#8220;The Ten Commandments for C Programmers&#8221;</em>. Uma referência respeitada é &#8220;Annotated Edition&#8221; do próprio Spencer.</p>
<p>Alguns clássicos da cultura, história e literatura de C seria o famoso [2]. Assim como um outros mais genéricos [3][4] que inclui alguns clássicos do C++ e do OOP.</p>
<p>Porém o POST e específico sobre desenvolvimento Unix, a principio podemos começar por <a href="http://pt.wikipedia.org/wiki/Filosofia_Unix" target="_blank">Filosofia Unix</a> e lembrando que nos dias de hoje sempre estamos trabalhando com softwares e suas diversas licenças, sendo muito interessante e indispensável o conhecimento sobre as principais licenças[5] de softwares!</p>
<p>[1] <a href="http://www.quut.com/c/ten-commandments.html" target="_blank">The Ten Commandments for C Programmers</a><br />
[2] <a href="http://www.quut.com/c/" target="_blank">Programming in C</a><a href="http://www.quut.com/c/" target="_blank"></a><br />
[3] <a href="http://www.mycplus.com/Programming-Tutorials-Index.asp" target="_blank">http://www.mycplus.com/Programming-Tutorials-Index.asp</a><br />
[4] <a href="http://www.di-mgt.com.au/cprog.html" target="_blank">http://www.di-mgt.com.au/cprog.html</a><br />
[5] <a href="http://blog.jorgepereira.com.br/2006/10/15/entendendo-o-softwarelivre/" target="_blank">http://blog.jorgepereira.com.br/2006/10/15/entendendo-o-softwarelivre/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2008/09/13/mandamentos-do-desenvolvedor-unix/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>- getch() no Linux</title>
		<link>http://blog.jorgepereira.com.br/2008/07/29/getch-no-linux/</link>
		<comments>http://blog.jorgepereira.com.br/2008/07/29/getch-no-linux/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 12:38:23 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=86</guid>
		<description><![CDATA[Se você já precisou algum dia trabalhar diretamente com leituras de teclas a partir da STDIN sem a interação do &#60;ENTER&#62; conforme maioria das funções estilo gets(), fgets(). e estava a procura de algo no estilo getch() e percebeu que não existe implementação idêntica no Linux. pode ficar tranqüilo, abaixo segue uma implementação chamada getch.c [...]]]></description>
			<content:encoded><![CDATA[<p>Se você já precisou algum dia trabalhar diretamente com leituras de teclas a partir da <em><strong>STDIN</strong></em> sem a interação do &lt;ENTER&gt; conforme maioria das funções estilo gets(), fgets(). e estava a procura de algo no estilo <strong><em>getch()</em></strong> e percebeu que não existe implementação idêntica no Linux. pode ficar tranqüilo, abaixo segue uma implementação chamada <a href="http://blog.jorgepereira.com.br/jorge/wp-content/uploads/2008/07/getch.c">getch.c</a> que fiz para leitura de teclas pressionadas sem a interação do &lt;ENTER&gt;. Lembrando que está e um alternativa caso não queira utilizar a função getch() existente na biblioteca <strong>ncurses</strong> e sendo obrigado a ter tal dependência incluída no seu projeto para tão pouco uso!</p>
<pre class="brush:csharp">/*
 * Autor: Jorge Pereira
 * Data:  Tue Jul 29 09:35:42 BRT 2008
 * Desc:  Implementacao da funcao getch() no Linux,
 * podendo ser feito leitura de um unico byte por vez.
 *
 */
#include &lt;stdio.h&gt;
#include &lt;stdint.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;
#include &lt;termios.h&gt;
#include &lt;sys/ioctl.h&gt;

#ifdef getch
#undef getch
#endif
typedef unsigned int keybd_t;

keybd_t getch (void)
{
	struct termio old_tty;	 /* current terminal settings */
	struct termio new_tty;	 /* new terminal settings     */
	keybd_t	key = 0;         /* character "buffer"	      */

	if (ioctl(STDIN_FILENO, TCGETA, &amp;old_tty) &lt; 0)
	{
		fprintf(stderr,"Port ioctl(TCGETA) it's failed, exiting...\n");
		exit(EXIT_FAILURE);
	}

	new_tty 	 = old_tty;		/* copy terminal settings    */
	new_tty.c_lflag &amp;= ~(ICANON | ECHO);	/* set flags in teminal      */
	new_tty.c_cc[4]  = 01;			/* struct for raw mode	     */

	if (ioctl(STDIN_FILENO, TCSETA, &amp;new_tty) &lt; 0)
	{
		fprintf(stderr,"Port ioctl(TCSETA) it's failed, exiting...\n");
		exit(EXIT_FAILURE);
	}

	if(read(STDIN_FILENO, &amp;key, sizeof(key)) &lt; 0)
	{
		fprintf(stderr,"Problems in read()\n");
		exit(EXIT_FAILURE);
	}

	if (ioctl(STDIN_FILENO, TCSETA, &amp;old_tty) &lt; 0)
	{
		fprintf(stderr,"Port ioctl(TCSETA) it's failed, exiting...\n");
		exit(EXIT_FAILURE);
	}

	return key;
}

#if defined(RUN_MAIN)
int
main (void)
{
    keybd_t key;

    printf ("(*) Teste para funcao getch(), pressione  para sair!\n");

    while ((key = getch()) != 0x1b)
    {
        char ch = (key &gt;= 'a' &amp;&amp; key &lt;= 'z') || (key &gt;= 'A' &amp;&amp; key &lt;= 'Z') || (key &gt;= '0' &amp;&amp; key &lt;= '9') ? key: ' ';

        printf (" -&gt; key char(%c) hex(0x%08x) dec(%d)\n", ch, key, key);
    }

    printf ("(*) Saindo...\n");

    return EXIT_SUCCESS;
}
#endif</pre>
<p>Adicionei um bloco <em><strong>ifdef</strong></em> com um main(), para que seja possível executar e testar a função. Abaixo segue exemplo de compilação.</p>
<p><strong>[jorge@jiraya codigos]$</strong> gcc -W -Wall -DRUN_MAIN -o getch getch.c<br />
<strong>[jorge@</strong><strong>jiraya</strong><strong> </strong><strong>codigos]$</strong> ./getch<br />
(*) Teste para funcao getch(), pressione &lt;ESC&gt; para sair!<br />
-&gt; key char(a) hex(0&#215;00000061) dec(97)<br />
-&gt; key char(b) hex(0&#215;00000062) dec(98)<br />
-&gt; key char(c) hex(0&#215;00000063) dec(99)<br />
-&gt; key char(d) hex(0&#215;00000064) dec(100)<br />
(*) Saindo&#8230;<br />
<strong>[jorge@</strong><strong>jiraya</strong><strong> </strong><strong>codigos]$</strong></p>
<p>Caso queira adicionar o ao seu projeto, basta remover o bloco <strong><em>#ifdef</em></strong> e utilizar normalmente! <img src='http://blog.jorgepereira.com.br/jorge/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2008/07/29/getch-no-linux/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>- Acessando quantidade de espaço de uma partição</title>
		<link>http://blog.jorgepereira.com.br/2008/07/25/acessando-quantidade-de-espaco-de-uma-particao/</link>
		<comments>http://blog.jorgepereira.com.br/2008/07/25/acessando-quantidade-de-espaco-de-uma-particao/#comments</comments>
		<pubDate>Sat, 26 Jul 2008 01:04:40 +0000</pubDate>
		<dc:creator>jpereira</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blog.jorgepereira.com.br/?p=85</guid>
		<description><![CDATA[Esses dias estive desenvolvendo uma feature de um sistema na qual existe uma regra de negócio para os arquivos a ser salvos em um determinado dispositivo, precisando saber se existe espaço entre outras verificações. conversando com um amigo ele disse que precisou fazer isto outro dia e não tinha encontrado muita coisa sobre o assunto, [...]]]></description>
			<content:encoded><![CDATA[<p>Esses dias estive desenvolvendo uma <em>feature</em> de um sistema na qual existe uma regra de negócio para os arquivos a ser salvos em um determinado dispositivo, precisando saber se existe espaço entre outras verificações. conversando com um amigo ele disse que precisou fazer isto outro dia e não tinha encontrado muita coisa sobre o assunto, como estava com o código na mão resolvi mostrar um simples exemplo com o mesmo comportamento do comando <strong><em>df</em></strong> encontrado em qualquer Unix.</p>
<p>[sourcecode language='cpp']<br />
/*<br />
* Source: statfs.c<br />
* Autor: Jorge Pereira<br />
* Data: Tue Jul 29 09:35:42 BRT 2008<br />
* Desc: Exemplo acessando a quantidade de espaço de uma partição no Linux.<br />
*/<br />
#include <stdio.h><br />
#include <stdlib.h><br />
#include <string.h><br />
#include <errno.h><br />
#include <stdint.h><br />
#include <sys/vfs.h></p>
<p>inline long _tok(long b, long bs)<br />
{<br />
return ( b * (long long) bs + 1024 / 2 ) / 1024;<br />
}</p>
<p>int main(int argc, char *argv[])<br />
{<br />
struct statfs s;</p>
<p>if (argc < 2)<br />
{<br />
printf ("Usage: %s \n", argv[0]);<br />
exit (1);<br />
}</p>
<p>if (statfs(argv[1], &amp;s) != 0)<br />
{<br />
printf ("Problemas ao tentar abrir (%s), msg='%s'\n", argv[1], strerror(errno));<br />
exit (1);<br />
}</p>
<p>printf(" + SYSTEMA ARQUIVOS: (%s) \n", argv[1]);<br />
printf(" +-- CAPACIDADE:     (%lu)\n", _tok(s.f_blocks, s.f_bsize));<br />
printf(" +-- OCUPADO:        (%lu)\n", _tok(s.f_blocks-s.f_bfree, s.f_bsize));<br />
printf(" +-- LIVRE:          (%lu)\n", _tok(s.f_bavail, s.f_bsize));</p>
<p>return EXIT_SUCCESS;<br />
}<br />
[/sourcecode]</p>
<p>Basta compilar, e executar o exemplo conforme abaixo.</p>
<p><strong>[jorge@jiraya c]$ </strong>gcc -o statfs statfs.c<br />
<strong>[jorge@jiraya c]$</strong> pwd<br />
/home/codes/c<br />
<strong>[jorge@jiraya c]$</strong> ./statfs  $PWD<br />
+ SYSTEMA ARQUIVOS: (/home/codigos/c)<br />
+&#8211; CAPACIDADE:     (<em>48444420</em>)<br />
+&#8211; OCUPADO:        (<em>13660960</em>)<br />
+&#8211; LIVRE:          (<em>32341984</em>)<br />
<strong>[jorge@jiraya c]$</strong> df  $PWD<br />
Filesystem           1K-blocks      Used Available Use% Mounted on<br />
/dev/sda3             <em>48444420</em> <em>13660960</em> <em>32341984</em> 30% /home<br />
<strong>[jorge@jiraya c]$</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgepereira.com.br/2008/07/25/acessando-quantidade-de-espaco-de-uma-particao/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
