<?xml version="1.0" encoding="ISO-8859-1"?>
<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>Geek Vault</title>
	<atom:link href="http://www.geekvault.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.geekvault.org</link>
	<description>Because geeks like to talk.</description>
	<lastBuildDate>Tue, 26 Mar 2013 12:17:28 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Como automatizar as entradas de teclado no Linux</title>
		<link>http://www.geekvault.org/2013/03/como-automatizar-as-entradas-de-teclado-no-linux/</link>
		<comments>http://www.geekvault.org/2013/03/como-automatizar-as-entradas-de-teclado-no-linux/#comments</comments>
		<pubDate>Tue, 26 Mar 2013 12:11:03 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[Stuffs]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[automatização]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=663</guid>
		<description><![CDATA[Volta e meia se faz necessário criar algo um pouco mais automatizado. Como podemos fazer isso em Linux? Se lembrarmos da máxima &#8220;Em UNIX tudo é um arquivo&#8221;, a coisa fica um pouco mais simples. Por tudo, é realmente TUDO, inclusive o teclado Já entendeu como? Basta utilizar um redirect Como exemplo, vamos tentar automatizar [...]]]></description>
				<content:encoded><![CDATA[<p>Volta e meia se faz necessário criar algo um pouco mais automatizado. Como podemos fazer isso em Linux?<br />
Se lembrarmos da máxima &#8220;Em UNIX tudo é um arquivo&#8221;, a coisa fica um pouco mais simples. Por tudo, é realmente TUDO, inclusive o teclado <img src='http://www.geekvault.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Já entendeu como? Basta utilizar um redirect <img src='http://www.geekvault.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Como exemplo, vamos tentar automatizar o fdisk, algo um tanto quanto complexo não? Vamos supor que você queira criar uma partição primária com todo o espaço disponível em /dev/sdb, pode fazer com o seguinte script:</p>
<pre>#!/bin/sh
cat &lt;&lt; EOF | fdisk /dev/sdb
n
p
1

w
EOF
partprobe</pre>
<p>Agora basta  salvar e executar o script, ele ira inserir os comandos &#8216;n&#8217;,'p&#8217;,&#8217;1&#8242;,&#8217;Enter&#8217;,'w&#8217; no fdisk, como faria uma pessoa de forma iterativa. No final irá chamar o partprobe para reler as tabelas dos discos.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2013/03/como-automatizar-as-entradas-de-teclado-no-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como utilizar mutex para evitar race-conditions em pThreads?</title>
		<link>http://www.geekvault.org/2012/12/como-utilizar-mutex-para-evitar-race-conditions-em-pthreads/</link>
		<comments>http://www.geekvault.org/2012/12/como-utilizar-mutex-para-evitar-race-conditions-em-pthreads/#comments</comments>
		<pubDate>Thu, 20 Dec 2012 17:37:11 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[ANSI C]]></category>
		<category><![CDATA[OpenSource]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[mutex]]></category>
		<category><![CDATA[paralelismo]]></category>
		<category><![CDATA[pthread]]></category>
		<category><![CDATA[race-condition]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=657</guid>
		<description><![CDATA[Apenas uma dica rápida, outro dia me peguei programando em pThreads e, como qualquer coisa um pouco mais complexa, cai no famoso &#8220;race-condition&#8221;, quando uma thread tenta utilizar dados ao mesmo tempo em que outra thread tenta (por exemplo) criar os dados. Existem várias formas de se resolver isso, porém acredito que a mais simples [...]]]></description>
				<content:encoded><![CDATA[<p>Apenas uma dica rápida, outro dia me peguei programando em pThreads e, como qualquer coisa um pouco mais complexa, cai no famoso &#8220;race-condition&#8221;, quando uma thread tenta utilizar dados ao mesmo tempo em que outra thread tenta (por exemplo) criar os dados.<br />
Existem várias formas de se resolver isso, porém acredito que a mais simples é a utilização de mutex (atenção, isso é exclusivo do SO, no nosso caso sistemas baseados em UNIX como Linux ou FreeBSD). A idéia do mutex é:</p>
<ol>
<li>Cria uma variável do tipo pthread_mutex_t</li>
<li>Inicializa</li>
<li>Dentro da thread, efetue um lock na área crítica da memória</li>
<li>Trabalhe na memória</li>
<li>Efetue um unlock da área crítica.</li>
</ol>
<p>Vamos ao exemplo mais simples possível:<span id="more-657"></span>Em nosso programa temos uma estrutura chamada &#8220;tst&#8221;, ela possui alguns dados que são populados pela thread create(), e lidos pela thread consume().</p>
<pre class="brush:c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;
#include &lt;string.h&gt;
#include &lt;time.h&gt;

typedef struct tst{
  int id;
  char nome[80];
  float valor;
  int valid;
  int qtd;
}TST;</pre>
<p>Agora, vamos criar o mutex como sendo uma variável global mesmo (podíamos ter colocado dentro da estrutura)</p>
<pre class="brush:c">pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER;</pre>
<p>(A utilização da PTHREAD_MUTEX_INITIALIZER evita algumas linhas de código e inicializa o mutex mais simples possível)</p>
<p>Agora, vamos à função responsável por popular os dados:</p>
<pre class="brush:c">void *create(void *data){
  int i;
  TST* lData = (TST*)data;
  int amount = lData[0].qtd;
  pthread_mutex_lock(&amp;data_mutex);
  for(i=0;i&lt;amount;i++){
    lData[i].id = i;
    snprintf(lData[i].nome,80,"Struct %d",i);
    lData[i].valor=i*i;
    lData[i].valid = 1;
  }
  pthread_mutex_unlock(&amp;data_mutex);
  return NULL;
}</pre>
<p>Em si, não tem nada de especial nessa função, ela recebe um void* (padrão de threads), transforma o mesmo no tipo TST declarado acima, efetua o lock da mutex com</p>
<pre class="brush:c">pthread_mutex_lock(&amp;data_mutex);</pre>
<p>Trabalha nos dados normalmente e de forma segura e, finalmente, libera o lock:</p>
<pre class="brush:c">pthread_mutex_unlock(&amp;data_mutex);</pre>
<p>Agora, vamos ver a função responsável por ler os dados:</p>
<pre class="brush:c">void *consume(void *data){
  int i=0;
  TST *lData = (TST*)data;
  int amount = lData[0].qtd;
  for(i=0;i&lt;amount;i++){
    fprintf(stderr,"%03d:%d\t%s\t%.2f\t%d\t%d\n",i,lData[i].id,lData[i].nome,lData[i].valor,lData[i].valid,lData[i].qtd);
  }
  return NULL;
}</pre>
<p>Também nada de especial, como estamos apenas lendo, não existe motivo para efetuar um lock dos dados nesse momento, então a função é bem fácil, apenas pega os dados os mostra.</p>
<p>O resto do programa não é nada novo para ninguém, cria os dados iniciais, cria as duas threads e aguarda o fim das mesmas:</p>
<pre class="brush:c">int main(int argc, char *argv[]){
  pthread_t threads[2];
  TST data[100];
  int i;
  memset(data,'\0',sizeof(TST)*100);
  for(i=0;i&lt;100;i++)
    data[i].qtd=100;
  for(i=0;i&lt;2;i++){
    if(pthread_create(&amp;threads[i],NULL,(i==0?&amp;create:&amp;consume),data)!=0){
      perror("pthread_create");
      return 1;
    }
  }
  for(i=0;i&lt;2;i++){
    if(pthread_join(threads[i],NULL)!=0){
      perror("pthread_join");
      return 1;
    }
  }
  fprintf(stderr,"Finished!\n");
  return 0;
}</pre>
<p>Claro que existe muito mais que se pode fazer com mutex, mas isso fica para outro dia <img src='http://www.geekvault.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>PS: Obviamente, para compilar basta incluir a lib pthread:</p>
<pre class="brush:bash">$ gcc -o consumer consumer.c -lpthread</pre>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2012/12/como-utilizar-mutex-para-evitar-race-conditions-em-pthreads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook resolve vender fotos do Instagram, sem pagar os usuários (atualizado).</title>
		<link>http://www.geekvault.org/2012/12/facebook-resolve-vender-fotos-do-instagram-sem-pagar-os-usuarios/</link>
		<comments>http://www.geekvault.org/2012/12/facebook-resolve-vender-fotos-do-instagram-sem-pagar-os-usuarios/#comments</comments>
		<pubDate>Tue, 18 Dec 2012 15:42:39 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Pensamentos]]></category>
		<category><![CDATA[Segurança]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[instagram]]></category>
		<category><![CDATA[Noticias]]></category>
		<category><![CDATA[venda]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=648</guid>
		<description><![CDATA[Normalmente não gosto de colocar esse tipo de notícia, porém essa me chamou a atenção. De acordo com essa notícia no Slashdot, a partir do dia 16/01/2013, o Facebook irá possibilitar a venda de fotos tiradas pelo Instagram (para propagando por exemplo), sem que o usuário receba um centavo disso. Ok, eles tem esse direito, [...]]]></description>
				<content:encoded><![CDATA[<p>Normalmente não gosto de colocar esse tipo de notícia, porém essa me chamou a atenção. De acordo com <a href="http://yro.slashdot.org/story/12/12/18/1334204/instagram-wants-to-sell-users-photos-without-notice" target="_blank">essa</a> notícia no <a href="http://slashdot.org" target="_blank">Slashdot,</a> a partir do dia 16/01/2013, o Facebook irá possibilitar a venda de fotos tiradas pelo Instagram (para propagando por exemplo), sem que o usuário receba um centavo disso.<br />
Ok, eles tem esse direito, basta ler a EULA do serviço do Instagram, porém será que isso não é algo extremo de mais? E outra, isso vale apenas para o Instagram ou também para o Facebook? Será que o Facebook pode começar a vender os posts das pessoas?<br />
Moral da história, sempre lenha entre as linhas de qualquer contrato, e tenha muito cuidado com privacidade no mundo digital.<span id="more-648"></span>ATUALIZAÇÃO: Aparentemente o Instagram voltou atrás e explicou melhor o que está acontecendo, veja <a href="http://blog.instagram.com/post/38252135408/thank-you-and-were-listening">in loco</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2012/12/facebook-resolve-vender-fotos-do-instagram-sem-pagar-os-usuarios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gerando números aleatórios em CUDA, utilizando CURAND.</title>
		<link>http://www.geekvault.org/2012/10/gerando-numeros-aleatorios-em-cuda-utilizando-curand/</link>
		<comments>http://www.geekvault.org/2012/10/gerando-numeros-aleatorios-em-cuda-utilizando-curand/#comments</comments>
		<pubDate>Sat, 20 Oct 2012 02:51:33 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[ANSI C]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[CUDA]]></category>
		<category><![CDATA[OpenSource]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Stuffs]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=634</guid>
		<description><![CDATA[Como muitos sabem, uma das minhas maiores paixões justamente a programação paralela. Faz um certo tempo (desde o mestrado), que não programo para paralelismo, nem em algoritmos genéticos, nem autômatos celulares, etc. Obviamente isso muito me fazia falta e, resolvi fazer um upgrade na máquina, trocando a velha boa de guerra GeForce 8500 GT, por [...]]]></description>
				<content:encoded><![CDATA[<p>Como muitos sabem, uma das minhas maiores paixões justamente a programação paralela. Faz um certo tempo (desde o mestrado), que não programo para paralelismo, nem em algoritmos genéticos, nem autômatos celulares, etc. Obviamente isso muito me fazia falta e, resolvi fazer um upgrade na máquina, trocando a velha boa de guerra GeForce 8500 GT, por uma GTX 580 (pequeno upgrade <img src='http://www.geekvault.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ).</p>
<p>Para relembrar como se programa em CUDA, resolvi utilizar a versão 5.0, recém lançada, e entender como funciona a biblioteca CURAND para a geração de números aleatórios em GPU (extremamente importante ao utilizarmos AG). Os resultados que obtive foram, extremamente satisfatórios, veja dois exemplos de execução:</p>
<ul>
<li>Geração de 787.021.824 números aleatórios utilizando uma distribuição binomial</li>
</ul>
<blockquote><p>*********INFO********<br />
*min:0<br />
*max:100<br />
*qtd:787021824<br />
*output:binomial.csv<br />
*distribution: BINOMIAL<br />
*Verify? NO<br />
********************<br />
[*] Initializing host memory&#8230;OK (0.00000 ms)<br />
[*] Initializing GPU memory&#8230;OK (1.76182 ms)<br />
[*] Creating random numbers&#8230;OK (3018.16577 ms)<br />
[*] Accumulatting&#8230;OK (1090.85291 ms)<br />
[*] Writing accumulatted values to &#8216;binomial.csv&#8217;&#8230;OK<br />
[*] Cleaning up memory&#8230;OK</p></blockquote>
<p>Geração de 787.021.824 números aleatórios utilizando uma distribuição uniforme:</p>
<blockquote><p>[*] Initializing host memory&#8230;OK (0.00000 ms)<br />
[*] Initializing GPU memory&#8230;OK (1.76829 ms)<br />
[*] Creating random numbers&#8230;OK (36.34749 ms)<br />
[*] Accumulatting&#8230;OK (707.11194 ms)<br />
[*] Writing accumulatted values to &#8216;/home/zarnick/tmp/uniform.csv&#8217;&#8230;OK<br />
[*] Cleaning up memory&#8230;OK</p></blockquote>
<p>Essa velocidade, convence?</p>
<p><span id="more-634"></span>Apesar da velocidade ser extrema, honestamente o código ainda está muito ruim, mas lá vai mesmo assim.<br />
Todo o código foi baseado em 2 funções que utilizam a biblioteca CURAND para gerar os números:</p>
<blockquote><p>__device__ int dBinomialRand(int n, float p, curandState *s);</p>
<p>__global__ void createRandomNumbers(int *vet, int dist, int min, int max, int qtd);</p></blockquote>
<p>E 1 função que utiliza as funções atómicas (extremamente mais fácil do que criar e cuidar de MUTEX) para efetuar a acumulação (contagem de quantas vezes um número aparece):</p>
<blockquote><p>__global__ void accumulate(int *vet, int *dest, int min, int max, int qtd);</p></blockquote>
<p>Sem mais delongas, vamos aos códigos.</p>
<blockquote><p>__global__ void createRandomNumbers(int *vet, int dist, int min, int max, int qtd){<br />
&nbsp;&nbsp;int tid = threadIdx.x + blockIdx.x*blockDim.x;</p>
<p>&nbsp;&nbsp;curandState s;</p>
<p>&nbsp;&nbsp;curand_init(tid,0,0,&amp;s);<br />
&nbsp;&nbsp;while(tid &lt; qtd){<br />
&nbsp;&nbsp;&nbsp;&nbsp;switch(dist){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case UNIFORM: vet[tid] = min + curand_uniform(&amp;s) * (max-min);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case BINOMIAL: vet[tid] = dBinomialRand(max,0.5,&amp;s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default: break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;tid += blockDim.x * gridDim.x;<br />
&nbsp;&nbsp;}<br />
}</p></blockquote>
<p>O funcionamento é bem simples, para cada thread, é utilizada uma semente (que é o próprio id da thread), é então criado uma estrutura do tipo curandState que é a responsável por iniciar a sequência de números aleatórios em curand_init() (para os preguiçosos, os parâmetros são, semente, início da sequência, offset e o curandState).<br />
Uma vez feito isso, caso seja uma distribuição do tipo uniforme, apenas cria um número para cada thread em cada bloco do grid, entre os valores min e max passados, caso seja binomial, chame a outra função para fazer isso.<br />
É simples assim para criar um número aleatório.<br />
E para criar um número binomial&#8230;</p>
<blockquote><p>
__device__ int dBinomialRand(int n, float p, curandState *s){<br />
&nbsp;&nbsp;int x = 0;<br />
&nbsp;&nbsp;int i;<br />
&nbsp;&nbsp;for(i=0;i&lt;n;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(curand_uniform(s) &gt; p )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;return x;<br />
}
</p></blockquote>
<p>A função de acumulação é tão simples, que vou apenas mostrá-la:</p>
<blockquote><p>
__global__ void accumulate(int *vet, int *dest, int min, int max, int qtd)<br />
{<br />
&nbsp;&nbsp;int tid = threadIdx.x + blockIdx.x*blockDim.x;<br />
&nbsp;&nbsp;while(tid &lt; qtd){<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(vet[tid] &gt;= min &amp;&amp; vet[tid] &lt; max)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;atomicAdd(&amp;dest[vet[tid]-min],1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;tid += blockDim.x*gridDim.x;<br />
&nbsp;&nbsp;}<br />
}
</p></blockquote>
<p>E a qualidade dos números? Bom, aqui está um pequeno gráfico que plotei com as duas funções:</p>
<p><a href="http://www.geekvault.org/wp-content/uploads/2012/10/random.jpg"><img class="aligncenter size-full wp-image-636" title="random" src="http://www.geekvault.org/wp-content/uploads/2012/10/random.jpg" alt="Random numbers generated by CURAND on the GPU" width="640" height="480" /></a>A qualidade me parece correta não?</p>
<p>Como &#8220;sempre&#8221;, o código fonte e uma descrição mais detalhada pode ser encontrada em <a href="http://trac.geekvault.org/cuda/wiki/cuRand" target="_blank">http://trac.geekvault.org/cuda/wiki/cuRand.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2012/10/gerando-numeros-aleatorios-em-cuda-utilizando-curand/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mudando as cores do ViM</title>
		<link>http://www.geekvault.org/2012/09/mudando-as-cores-do-vim/</link>
		<comments>http://www.geekvault.org/2012/09/mudando-as-cores-do-vim/#comments</comments>
		<pubDate>Tue, 25 Sep 2012 14:17:22 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[Stuffs]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[cores]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[temas]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=630</guid>
		<description><![CDATA[Ok, dica rápida. Para quem não sabe, é possível trocar as cores do ViM (Vi-iMproved) para alguns temas. Primeiramente veja quais são os temas disponíveis em /usr/share/vim/vim72/colors (ou diretório equivalente). Para escolher algum tema, coloque em seu .vimrc (ou no /etc/vimrc) o comando :colorscheme &#60;tema&#62; Por exemplo, para utilizar o tema &#8220;darkblue&#8221;, coloque: :colorscheme darkblue [...]]]></description>
				<content:encoded><![CDATA[<p>Ok, dica rápida.</p>
<p>Para quem não sabe, é possível trocar as cores do ViM (Vi-iMproved) para alguns temas. Primeiramente veja quais são os temas disponíveis em /usr/share/vim/vim72/colors (ou diretório equivalente).<br />
Para escolher algum tema, coloque em seu .vimrc (ou no /etc/vimrc) o comando</p>
<blockquote><p>:colorscheme &lt;tema&gt;</p></blockquote>
<p>Por exemplo, para utilizar o tema &#8220;darkblue&#8221;, coloque:</p>
<blockquote><p>:colorscheme darkblue</p></blockquote>
<p>O mesmo pode ser feito apenas para uma seção, porém não ira ser permanente.</p>
<p>Fica a dica.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2012/09/mudando-as-cores-do-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Habemus Youtube</title>
		<link>http://www.geekvault.org/2012/09/habemus-youtube/</link>
		<comments>http://www.geekvault.org/2012/09/habemus-youtube/#comments</comments>
		<pubDate>Tue, 11 Sep 2012 10:48:43 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Stuffs]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[aplicativos]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=627</guid>
		<description><![CDATA[Não é nenhuma novidade que a Apple cancelou o contrato com a Google (em partes, ainda bem, uma vez que os apps da Google estavam esquecidos no mundo iOS), no meio disso tudo, no iOS 6 não temos mais Google Maps por padrão (agora é a versão da Apple) e, recentemente, o YouTube também saiu [...]]]></description>
				<content:encoded><![CDATA[<p>Não é nenhuma novidade que a Apple cancelou o contrato com a Google (em partes, ainda bem, uma vez que os apps da Google estavam esquecidos no mundo iOS), no meio disso tudo, no iOS 6 não temos mais Google Maps por padrão (agora é a versão da Apple) e, recentemente, o YouTube também saiu dos pequenos dispositivos. Pois bem, ontem a Google lançou o app oficial (again) do YouTube, apenas para o iPhone por enquanto, mas uma versão do iPad está para vir.</p>
<p>Pessoalmente ainda não fiz o download (falta de tempo para analisar direito), mas para quem quiser, você pode fazer o download diretamente da <a href="http://itunes.apple.com/us/app/youtube/id544007664?mt=8">App Store</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2012/09/habemus-youtube/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problema com iOS e FMDB: Out of Memory</title>
		<link>http://www.geekvault.org/2012/08/problema-com-ios-e-fmdb-out-of-memory/</link>
		<comments>http://www.geekvault.org/2012/08/problema-com-ios-e-fmdb-out-of-memory/#comments</comments>
		<pubDate>Tue, 28 Aug 2012 11:09:48 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[SQLite3]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[FMDB]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=619</guid>
		<description><![CDATA[Recentemente comecei a programar em iOS, em um dos aplicativos que estou fazendo estou utilizando, drasticamente, acesso a um banco de dados do tipo SQLite3. Obviamente, para facilitar a minha vida, utilizo um wrapper chamado FMDB, ele é muito bom, da uma &#8220;objetificada&#8221; no acesso ao banco de dados, recomendo a todos. Porém recentemente estava [...]]]></description>
				<content:encoded><![CDATA[<p>Recentemente comecei a programar em iOS, em um dos aplicativos que estou fazendo estou utilizando, drasticamente, acesso a um banco de dados do tipo SQLite3. Obviamente, para facilitar a minha vida, utilizo um wrapper chamado <a href="https://github.com/ccgus/fmdb">FMDB</a>, ele é muito bom, da uma &#8220;objetificada&#8221; no acesso ao banco de dados, recomendo a todos. Porém recentemente estava tendo um problema ao acessar a minha tabela principal:</p>
<blockquote><p>Error calling sqlite3_step (21: out of memory) rs</p></blockquote>
<p><span id="more-619"></span>Desnecessário falar que, como o aplicativo ainda está em início de desenvolvimento, o erro &#8220;out of memory&#8221; não faz o menor sentido, a tabela em questão possui pouco mais de 6 linhas com 7 colunas cada, não fazia sentido.</p>
<p>Pois bem, aparentemente, no que o FMDB é muito bom em trabalhar com o banco, simplificando a criação da query, ele não é muito bom em mostrar erros. O problema em sí não é estouro de memória, mas sim que, na query que eu utilizo para montar o objeto, eu tento efetuar uma nova busca em uma outra tabela, na mesma conexão, ou seja:<br />
<code> <br />
FMResultSet *result = [[self database] executeQuery:@"select * from tabela"];<br />
NSMutableArray *models = [[NSMutableArray alloc] init];<br />
while([result next]){<br />
&nbsp;&nbsp;GVModel *model = [[GVDrinkModel alloc] init];<br />
&nbsp;&nbsp;[model setCampo1:[result stringForColumn:@"campo1"]];<br />
&nbsp;&nbsp;[model setCampo2:[result stringForColumn:@"campo2"]];<br />
&nbsp;&nbsp;[model setCampo3:[result stringForColumn:@"campo3"]];<br />
&nbsp;&nbsp;[model setCampo4:[result stringForColumn:@"campo4"]];<br />
&nbsp;&nbsp;[model setCampo5:[result stringForColumn:@"campo5"]];<br />
&nbsp;&nbsp;[model setCampo6:[result dateForColumn:@"campo6"]];<br />
&nbsp;&nbsp;NSData *imageData = [result dataForColumn:@"campo7"];<br />
&nbsp;&nbsp;[model setCampo7:[UIImage imageWithData:imageData]];<br />
&nbsp;&nbsp;[model setCampoExt8:[self getCampo8WithModel:model];<br />
&nbsp;&nbsp;[model setCampoExt9:[self getCampo9WithModel:model];<br />
&nbsp;&nbsp;[model setCampoExt10:[self getCampo10WithModel:model];<br />
&nbsp;&nbsp;[models addObject:model];<br />
}<br />
</code><br />
Para resolver esse problema, temos duas formas:</p>
<ol>
<li>Alterar a query para efetuar um join com as outras tabelas externas e montar o resultado de acordo com as tabelas, ou</li>
<li>Após pegar apenas os campos internos, finalizar e abrir o banco de dados novamente.</li>
</ol>
<p>Ambas as formas tem seus prós e contras, a vantagem de utilizar um join é a simplificação no acesso ao banco de dados, porém o mesmo <strong>deve</strong> estar bem estruturado. Caso você não saiba fazer um join, ou simplismente queira algo de desenvolvimento rápido, utilize a segunda opção. Porém atenção, se o banco estiver estruturado corretamente, um join <strong>quase sempre</strong> será mais rápido.</p>
<p>No meu caso específico, como 2 acesso externos geram dois arrays de n valores, optei (por desenho) uma mistura das soluções:<br />
<code><br />
FMResultSet *result = [[self database] executeQuery:@"select t1.campo1, t1.campo2, t1.campo3, t1.campo4, t1.campo5, t1.campo6, t1.campo7, t2.campo8 from tabela t1, tabela t2 where t1.pk = t2.fk"];<br />
NSMutableArray *models = [[NSMutableArray alloc] init];<br />
while([result next]){<br />
&nbsp;&nbsp;GVModel *model = [[GVDrinkModel alloc] init];<br />
&nbsp;&nbsp;[model setCampo1:[result stringForColumn:@"campo1"]];<br />
&nbsp;&nbsp;[model setCampo2:[result stringForColumn:@"campo2"]];<br />
&nbsp;&nbsp;[model setCampo3:[result stringForColumn:@"campo3"]];<br />
&nbsp;&nbsp;[model setCampo4:[result stringForColumn:@"campo4"]];<br />
&nbsp;&nbsp;[model setCampo5:[result stringForColumn:@"campo5"]];<br />
&nbsp;&nbsp;[model setCampo6:[result dateForColumn:@"campo6"]];<br />
&nbsp;&nbsp;NSData *imageData = [result dataForColumn:@"campo7"];<br />
&nbsp;&nbsp;[model setCampo7:[UIImage imageWithData:imageData]];<br />
&nbsp;&nbsp;[model setCampoExt8:[result dataForColumn:@"campo8"];<br />
&nbsp;&nbsp;[models addObject:model];<br />
}<br />
for(GVModel *model in models){<br />
&nbsp;&nbsp;[model setCampoExt9:[self getCampo9WithModel:model];<br />
&nbsp;&nbsp;[model setCampoExt10:[self getCampo10WithModel:model];<br />
}<br />
</code><br />
Problema resolvido.</p>
<p>Provavelmente deve existir alguma opção no SQLite3 para permitir multiplos acessos e queries em uma mesma conexão, porém as 3 da manhã, esse tipo de pesquisa se torna inviável <img src='http://www.geekvault.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2012/08/problema-com-ios-e-fmdb-out-of-memory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vetores dinâmicos em C, depois do C99</title>
		<link>http://www.geekvault.org/2012/08/vetores-dinamicos-em-c-depois-do-c99/</link>
		<comments>http://www.geekvault.org/2012/08/vetores-dinamicos-em-c-depois-do-c99/#comments</comments>
		<pubDate>Thu, 23 Aug 2012 03:13:47 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[ANSI C]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[C99]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[dinâmico]]></category>
		<category><![CDATA[malloc]]></category>
		<category><![CDATA[padrões]]></category>
		<category><![CDATA[vetores]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=611</guid>
		<description><![CDATA[Então, eu programao em C, programo a tanto tempo que até não me lembro quando comecei. E, como bom programador de C, eu tenho alguns vícios e algumas coisas que sempre levei por verdade. Vícios: Sempre estruturar um bloco na ordem: declarações-&#62;código, nunca colocar uma declaração depois de iniciar um código. Sempre tomar cuidado com [...]]]></description>
				<content:encoded><![CDATA[<p>Então, eu programao em C, programo a tanto tempo que até não me lembro quando comecei. E, como bom programador de C, eu tenho alguns vícios e algumas coisas que sempre levei por verdade.<br />
Vícios:</p>
<ul>
<li>Sempre estruturar um bloco na ordem: declarações-&gt;código, nunca colocar uma declaração depois de iniciar um código.</li>
<li>Sempre tomar cuidado com o tamanho do que vai na Stack.</li>
</ul>
<p>E por verdade, sempre levei que o seguinte código não funciona:</p>
<pre>#include &lt;stdio.h&gt;
int main(int argc, char *argv[]){
  int qtd;
  scanf("%d",&amp;qtd);
  int vet[qtd];
  int i;
  for(i=0;i&lt;qtd;i++) vet[i]=i;
  return 0;
}</pre>
<p>Pois bem, esse código quebrava tudo que eu tomava por verdade, estou declarando uma variável depois de inicializar um código e, estou tentando alocar um vetor de tamanho desconhecido em tempo de compilação, na memória stack, não deveria funcionar certo?<span id="more-611"></span></p>
<p>Mas funciona!</p>
<p>Eis que veio o C99 e atualizou o padrão do C, agora (desde 1999), <strong>É</strong> possível criar um vetor de tamanho desconhecido em tempo de compilação. Enquanto alguns compiladores já faziam isso, mas não era padrão, após 1999, essa funcionalidade virou padrão do C. Que ótimo, quer dizer que agora eu posso criar vetores de tamanho <em>n</em>, sem precisar me preocupar com malloc() e cia?</p>
<p>Não exatamente, apesar de funcionar, a memória <strong>ainda</strong> é alocada na stack, ou seja, é muito fácil de estourar o tamanho da stack e, além disso, uma vez criado o vetor, ai sim o tamanho dele fica imutável. Então não, você <strong>não</strong> se livrou de malloc() e cia.</p>
<p>Pessoalmente, eu não considero isso uma boa prática, principalmente pois você não sabe o que o usuário vai pedir, vejo sua utilidade e simplicidade, mas, provavelmente, não vou adotar.</p>
<p>Obs: Para ver o padrão C99, veja esse <a href="http://www.open-std.org/JTC1/SC22/WG14/www/docs/C99RationaleV5.10.pdf">PDF</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2012/08/vetores-dinamicos-em-c-depois-do-c99/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como efetuar um reduce em LVM</title>
		<link>http://www.geekvault.org/2012/08/como-efetuar-um-reduce-em-lvm/</link>
		<comments>http://www.geekvault.org/2012/08/como-efetuar-um-reduce-em-lvm/#comments</comments>
		<pubDate>Fri, 17 Aug 2012 20:02:35 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[e2fsck]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[lvextend]]></category>
		<category><![CDATA[LVM]]></category>
		<category><![CDATA[lvreduce]]></category>
		<category><![CDATA[resize]]></category>
		<category><![CDATA[resize2fs]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=609</guid>
		<description><![CDATA[Ok, quem conhece LVM sabe de sua praticidade, quem não conhece pode ir aqui para ver o quão prático ele pode ser. O LVM nos traz vários benefícios, um deles é justamente aumentar e reduzir um volume, com um sistema em LVM podemos por exemplo adicionar um HD em algum volume lógico e adicionar espaço [...]]]></description>
				<content:encoded><![CDATA[<p>Ok, quem conhece LVM sabe de sua praticidade, quem não conhece pode ir <a href="http://www.geekvault.org/2009/10/lvm-no-linux-o-que-e-e-como-utilizar/">aqui</a> para ver o quão prático ele pode ser. O LVM nos traz vários benefícios, um deles é justamente aumentar e reduzir um volume, com um sistema em LVM podemos por exemplo adicionar um HD em algum volume lógico e adicionar espaço (um stripping), e também podemos fazer o oposto, diminuir para, por exemplo, colocar em algum outro volume lógico.<br />
Enquanto adicionar é fácil, remover para colocar em outro local pode ser um pouco complicado, ou até mesmo desafiador, já que TEMOS dados nos volumes, como fazer isso SEM perdê-los? É sobre isso que é essa dica.<span id="more-609"></span>Vamos supor que tenhamos que passar 2G do volume lógico que armazena a partição /usr/local para o volume lógico responsável pelo /tmp, como fazer?</p>
<p>Não é nenhum dragão de sete cabeças, basta seguir os seguintes passos <strong>nessa mesma ordem</strong>:</p>
<ol>
<li>Desmontar as partições.</li>
<li>Verificá-las com e2fsk -f.</li>
<li>Efetuar o resize2fs na partição que se deseja diminuir.</li>
<li>Efetuar o lvreduce no volume lógico que se deseja diminuir.</li>
<li>Efetuar o lvextend no volume lógico que se deseja aumentar.</li>
<li>Efetuar o resize2fs na partição que se deseja aumentar.</li>
<li>Efetuar, novamente, o  e2fsck -f em ambas as partições.</li>
<li>Montá-las e utilizá-las normalmente.</li>
</ol>
<p>Importante frisar que a ordem dos passos, principalmente a 3 e 4, <strong>não</strong> podem ser alteradas, caso contrário você poderá render o seu sistema inoperante na partição a ser diminuída!</p>
<p>Nada melhor do que mostrar com um exemplo certo? Vamos então redimensionar a partição /usr/local de 27Gb para 25Gb, e aumentar a /tmp com o diferença:</p>
<ol>
<li>Verificando o tamanho e desmontando as partições<br />
<code><br />
[root@localhost ~]# df -h /usr/local/ /tmp/<br />
Filesystem Size Used Avail Use% Mounted on<br />
/dev/mapper/sys-local<br />
27G 173M 25G 1% /usr/local<br />
/dev/mapper/sys-tmp 3.9G 69M 3.7G 2% /tmp<br />
[root@localhost ~]# umount /usr/local /tmp<br />
</code></li>
<li>Verificação com o e2fsk -f<br />
<code><br />
[root@localhost ~]# e2fsck -f /dev/sys/local<br />
e2fsck 1.39 (29-May-2006)<br />
Pass 1: Checking inodes, blocks, and sizes<br />
Pass 2: Checking directory structure<br />
Pass 3: Checking directory connectivity<br />
Pass 4: Checking reference counts<br />
Pass 5: Checking group summary information<br />
/dev/sys/local: 42/7077888 files (2.4% non-contiguous), 265736/7077888 blocks<br />
[root@localhost ~]# e2fsck -f /dev/sys/tmp<br />
e2fsck 1.39 (29-May-2006)<br />
Pass 1: Checking inodes, blocks, and sizes<br />
Pass 2: Checking directory structure<br />
Pass 3: Checking directory connectivity<br />
Pass 4: Checking reference counts<br />
Pass 5: Checking group summary information<br />
/dev/sys/tmp: 14/1048576 files (7.1% non-contiguous), 50276/1048576 blocks<br />
</code></li>
<li>Efetuando o resize2fs na partição a ser diminuida<br />
<code><br />
[root@localhost ~]# resize2fs /dev/sys/local 25G<br />
resize2fs 1.39 (29-May-2006)<br />
Resizing the filesystem on /dev/sys/local to 6553600 (4k) blocks.<br />
The filesystem on /dev/sys/local is now 6553600 blocks long.<br />
</code></li>
<li>Efetuando o lvreduce na partição a ser diminuida<br />
<code><br />
[root@localhost ~]# lvreduce /dev/sys/local -L -2G<br />
/dev/hdc: open failed: No medium found<br />
WARNING: Reducing active logical volume to 25.88 GB<br />
THIS MAY DESTROY YOUR DATA (filesystem etc.)<br />
Do you really want to reduce local? [y/n]: y<br />
Reducing logical volume local to 25.88 GB<br />
Logical volume local successfully resized<br />
</code></li>
<li>Efetuando o lvextend no volume lógico a ser aumentado<br />
<code><br />
[root@localhost ~]# lvextend /dev/sys/tmp -L +2G<br />
/dev/hdc: open failed: No medium found<br />
Extending logical volume tmp to 6.00 GB<br />
Logical volume tmp successfully resized<br />
</code></li>
<li>Efetuando o resize2f na partição a ser extendida<br />
<code><br />
[root@localhost ~]# resize2fs /dev/sys/tmp 6G<br />
resize2fs 1.39 (29-May-2006)<br />
Resizing the filesystem on /dev/sys/tmp to 1572864 (4k) blocks.<br />
The filesystem on /dev/sys/tmp is now 1572864 blocks long.<br />
</code></li>
<li>Efetuando o e2fsk -f nas partições, novamente<br />
<code><br />
[root@localhost ~]# e2fsck -f /dev/sys/local<br />
e2fsck 1.39 (29-May-2006)<br />
Pass 1: Checking inodes, blocks, and sizes<br />
Pass 2: Checking directory structure<br />
Pass 3: Checking directory connectivity<br />
Pass 4: Checking reference counts<br />
Pass 5: Checking group summary information<br />
/dev/sys/local: 42/6553600 files (2.4% non-contiguous), 249320/6553600 blocks<br />
[root@localhost ~]# e2fsck -f /dev/sys/tmp<br />
e2fsck 1.39 (29-May-2006)<br />
Pass 1: Checking inodes, blocks, and sizes<br />
Pass 2: Checking directory structure<br />
Pass 3: Checking directory connectivity<br />
Pass 4: Checking reference counts<br />
Pass 5: Checking group summary information<br />
/dev/sys/tmp: 14/1572864 files (7.1% non-contiguous), 66692/1572864 blocks<br />
</code></li>
<li>Montando e correndo para o abraço<code><br />
[root@localhost ~]# mount /usr/local/<br />
[root@localhost ~]# mount /tmp<br />
[root@localhost ~]# df -h /usr/local /tmp<br />
Filesystem Size Used Avail Use% Mounted on<br />
/dev/mapper/sys-local<br />
25G 173M 23G 1% /usr/local<br />
/dev/mapper/sys-tmp 5.9G 69M 5.5G 2% /tmp<br />
[root@localhost ~]# touch /tmp/a<br />
[root@localhost ~]# ls /tmp/<br />
a hsperfdata_daemon lost+found<br />
[root@localhost ~]# ls /usr/local/<br />
bin etc games include lib lib64 libexec lost+found sbin share src<br />
</code></li>
</ol>
<p>Nnovamente, atenção na ordem, se diminuir o volume lógico ANTES de diminuir a partição, você <strong>pode</strong> perder tudo nesse partição. Caso isso aconteça, a única solução que encontrei até hoje foi:</p>
<ol>
<li>Antes de efetuar o resize2fs, ele irá pedir para rodar o e2fsck -f, que irá falhar, esse é o indício de que algo aconteceu errado.</li>
<li>Então efetue o inverso, um lvextend e comece novamente.</li>
</ol>
<p>Vamos mostrar na prática:</p>
<p><code><br />
[root@localhost ~]# umount /tmp/<br />
[root@localhost ~]# lvreduce /dev/sys/tmp -L -2G<br />
/dev/hdc: open failed: No medium found<br />
WARNING: Reducing active logical volume to 4.00 GB<br />
THIS MAY DESTROY YOUR DATA (filesystem etc.)<br />
Do you really want to reduce tmp? [y/n]: y<br />
Reducing logical volume tmp to 4.00 GB<br />
Logical volume tmp successfully resized<br />
[root@localhost ~]# resize2fs /dev/sys/tmp 4G<br />
resize2fs 1.39 (29-May-2006)<br />
Please run 'e2fsck -f /dev/sys/tmp' first.<br />
[root@localhost ~]# e2fsck -f /dev/sys/tmp<br />
e2fsck 1.39 (29-May-2006)<br />
The filesystem size (according to the superblock) is 1572864 blocks<br />
The physical size of the device is 1048576 blocks<br />
Either the superblock or the partition table is likely to be corrupt!<br />
Abort? yes<br />
</code><br />
Ok, aqui vimos que algo muito feio aconteceu, vamos tentar voltar:<br />
<code><br />
[root@localhost ~]# lvextend /dev/sys/tmp -L +2G<br />
/dev/hdc: open failed: No medium found<br />
Extending logical volume tmp to 6.00 GB<br />
Logical volume tmp successfully resized<br />
[root@localhost ~]# e2fsck -f /dev/sys/tmp<br />
e2fsck 1.39 (29-May-2006)<br />
Pass 1: Checking inodes, blocks, and sizes<br />
Pass 2: Checking directory structure<br />
Pass 3: Checking directory connectivity<br />
Pass 4: Checking reference counts<br />
Pass 5: Checking group summary information<br />
/dev/sys/tmp: 15/1572864 files (6.7% non-contiguous), 66692/1572864 blocks<br />
[root@localhost ~]# mount /tmp/<br />
[root@localhost ~]# df -h /tmp<br />
Filesystem Size Used Avail Use% Mounted on<br />
/dev/mapper/sys-tmp 5.9G 69M 5.5G 2% /tmp<br />
[root@localhost ~]# touch /tmp/a<br />
[root@localhost ~]# ls /tmp/<br />
a hsperfdata_daemon lost+found<br />
</code><br />
E tudo volta ao normal, agora volte e faça na ordem certa!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2012/08/como-efetuar-um-reduce-em-lvm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Atualizando para o Mountain Lion, os detalhes que me deixaram fulo</title>
		<link>http://www.geekvault.org/2012/08/atualizando-para-o-mountain-lion-os-detalhes-que-me-deixaram-fulo/</link>
		<comments>http://www.geekvault.org/2012/08/atualizando-para-o-mountain-lion-os-detalhes-que-me-deixaram-fulo/#comments</comments>
		<pubDate>Thu, 16 Aug 2012 22:47:27 +0000</pubDate>
		<dc:creator>Zarnick</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Pensamentos]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[ml]]></category>
		<category><![CDATA[mountain lion]]></category>
		<category><![CDATA[rants]]></category>

		<guid isPermaLink="false">http://www.geekvault.org/?p=603</guid>
		<description><![CDATA[Já faz um tempo que atualizei meu Mac 13&#8243; para o Mountain Lion e, no geral, estou gostando muito. Porém alguns detalhes me deixaram doido para arrumar e deixar como estava, hoje acredito que arrumei o último detalhe de todos eles. Se for ver bem, nem é tanta coisa assim: Instalação X11 MacFUSE macports Como [...]]]></description>
				<content:encoded><![CDATA[<p>Já faz um tempo que atualizei meu Mac 13&#8243; para o Mountain Lion e, no geral, estou gostando muito. Porém alguns detalhes me deixaram doido para arrumar e deixar como estava, hoje acredito que arrumei o último detalhe de todos eles.<br />
Se for ver bem, nem é tanta coisa assim:</p>
<ul>
<li>Instalação</li>
<li>X11</li>
<li>MacFUSE</li>
<li>macports</li>
<li>Como utilizar direito o Notification Center com o Mail</li>
<li>Drag n&#8217; drop no trackpad</li>
</ul>
<p>Mais para frente eu faço um review completo, mas por enquanto vamos ao que aconteceu e como resolvi:</p>
<h2><span id="more-603"></span>Instalação</h2>
<p>O problema da instalação, posso falar que foi uma parte minha culpa, outra parte a dificuldade de resolver o problema pela Apple, basicamente, o que aconteceu foi que o meu HD tinha alguns erros de I/O e não instalava o Mountain Lion nem por reza brava, assim como o Disk Utility não conseguia reparar e, essa é a pior parte, eu não conseguia sair da instalação e voltar para o Lion!</p>
<p>Isso me fez perder mas boas 8 horas tentando reparar, verificar permissões e o raio que o parta no HD para, no final, formatar e restaurar do Backup via TM, uma vez restaurado (havia feito um backup segundos antes de iniciar a instalação), consegui instalar normalmente, mas só ai foram mais umas 5 horas (4 para restaurar e 1 para instalar).</p>
<p>Ok, minha culpa não ter verificado o HD antes (até por que, ele era praticamente novo, quem ia imaginar?), mas pow Apple, não poder sair da instalação é fogo ein?</p>
<h2>X11</h2>
<p>Uma vez instalado, logo fui testar se continuava funcionando tudo, uma das coisas que costumo utilizar, <strong>muito</strong> é o SSH, e o SSH com suporte a X para subir uma ou outra interface gráfica dos servidores externo, e foi ai que fiquei pasmo, não tinha mais X11. Depois de procurar (o que poucos fazem), encontrei que a Apple realmente <strong>retirou</strong> o X11 do Mountain Lion, e trocou pelo XQuartz. Ok, acontece, mas o que me deixou fulo foi outro fato relacionado a isso, uma coisa é não suportar, ou até mesmo, toda santa vez que for utilizar, avisar para utilizar o XQuartz no lugar, mas não, a Apple simplesmente retirou, não avisou ninguém e deixou quieto exceto por uma pequena nota no site <a href="http://support.apple.com/kb/HT5293">dela</a>. Achei meio sacanagem, sabe-se lá o que mais eles retiraram de vez.</p>
<h2>MacFUSE</h2>
<p>Ta ai outra coisa que uso, e uso muito que, simplesmente não funcionava mais. Ok, eu sabia que não iria funcionar, pesquisei antes, mas também me falaram que bastava reinstalar&#8230;e quem diz que reinstalava? Depois de muito tenta e retentar, a solução foi&#8230;veja o próximo item.</p>
<h2>macports</h2>
<p>Então chegamos no <a href="http://www.macports.org/">macports</a>, quem não conhece, <strong>deve</strong> conhecer, é o ports do BSD portado para Mac, funciona perfeitamente e, muitas vezes (*cough* *cough* GIMP) funciona melhor que o pacote feito para o Mac. Enfim, cheguei no macports por causa do MacFUSE, sempre funcionou pelo macports e resolvi reinstalar. Tive tanto problema de bibliotecas e todo o resto, que resolvi fazer o impensável (utilizo macports desde que tenho mac&#8230;), retirar <strong>tudo</strong> do macports e reinstalá-lo, não é que funcionou? Inclusive o MacFUSE.</p>
<p>Sei que esses dois não são coisas do Mountain Lion, mas me deixou fulo.</p>
<h2>Como utilizar direito o Notification Center com o Mail</h2>
<p>Para esse ainda não encontrei uma solução, a única coisa que eu realmente gostaria, era de poder selecionar as pastas de dentro do Mail para aparecer no Notification Center, no chance, apenas o Inbox, um pouco de customização cai bem não? E não acredito que seja complexo fazer uma coisa dessas&#8230;thanks Apple, for not letting me do the way I want!</p>
<h2>Drag n&#8217; drop no trackpad</h2>
<p>Esse para mim, foi o mais sem noção, sabe quando você tem o MacBook ou um Magic Trackpad externo e da um duplo clique com um dedo para ativar o drag? Então, não tinha mais essa opção. COMO ASSIM??? Pelo menos foi o que eu pensava, eu procurei, procurei, e procurei mais um pouco, mas pelo visto não havia procurado direito, <a href="https://discussions.apple.com/thread/3193685?start=0&amp;tstart=0">esse post do suporte da Apple</a> me fez ver onde estava escondida essa opção, dentro de Universal Acces! Ai você me fala, mas isso vem desde o Lion, como você usava antes? Pois bem, no Snow Leopard ficava nas opções do trackpad, no Lion vinha ativado por default, no Mountain Lion não!</p>
<p>Essa mania da Apple de tentar deixar tudo que nem o iOS me deixa P*** da vida, não faz sentido, uma coisa é um celular/tablet, outra coisa é um computador&#8230;vamos ver quantas mais coisas vão retirar ou mudar no próximo lançamento!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekvault.org/2012/08/atualizando-para-o-mountain-lion-os-detalhes-que-me-deixaram-fulo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.018 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2013-05-23 01:32:11 -->
