Experimente o ambiente de desenvolvimento integrado GNOME-BUILDER

Toda ajuda é bem vinda para desenvolver os seus programas? Ou você é do tipo que prefere um editor básico (como o Vim), para escrever o seu código?
O GNOME-BUILDER ainda está em fase de desenvolvimento e pode não ser a IDE de programação mais adequada para muitos usuários.
Mas tenho certeza de que ele vale a tentativa, em função de algumas de suas excelentes características — a leveza, por exemplo.
Neste texto, quero apresentar esta IDE e mostrar como instalar no seu sistema.
Se você gostar (ou não), sinta-se à vontade para comentar posteriormente sobre o aplicativo.

O que é o GNOME BUILDER

O Builder é uma nova IDE (Integrated Development Environment ou ambiente de desenvolvimento integrado), voltada para o ambiente desktop GNOME.
Não há impedimento para rodar o aplicativo no KDE ou em qualquer outro lugar, claro. Mas ele é voltado para o desenvolvimento de softwares para GNOME.
Não tem a intenção de ser uma IDE genérica, portanto, mas específica para desenvolvedores de aplicações GNOME.

Se você gosta do GNOME e tem a intenção de desenvolver para este desktop environment, o projeto é para você.

As linguagens de programação padrão, por enquanto, são C, C++, Python e Vala.
gnome builder IDE
O ambiente também tem integração ao GIT e várias licenças padrão para você escolher antes de começar o seu projeto.
Chama a atenção também a presença de um simulador do GNOME, que permite testar seu trabalho em versões diferentes da que se encontra instalada em seu sistema.

Como instalar o GNOME BUILDER

Se você tem o desejo de usar a versão mais atual do programa, deveria considerar baixar o código fonte, compilar e instalar o aplicativo.
Neste caso, baixe a versão mais nova deste site: https://download.gnome.org/sources/gnome-builder/.
Usuários Debian (eu testei no Stretch) ou Ubuntu, podem fazer a instalação normal, a partir dos repositórios:

apt install gnome-builder

A IDE também está disponível nos repositórios das versões mais recentes do Fedora e do openSUSE.
opensuse cli zypper info gnome-builder
Para instalar no Fedora, use o dnf:

dnf install gnome-builder

No openSUSE, use o zypper:

zypper install gnome-builder

Referências

https://download.gnome.org/sources/gnome-builder/.
https://wiki.gnome.org/Apps/Builder.

Como se prevenir de fork bombs no Linux, usando nproc e ulimit

fork bombs são códigos maliciosos, executados no sistema, que causam a negação do serviço ou denial of service.
Sua efeito é devastador, por consumir rapidamente os recursos de armazenamento na memória e/ou de processamento de informações, causando uma crescente deterioração do sistema.
fork bomb diagram
O resultado de uma fork bomb é, quase sempre, um desktop ou servidor totalmente inoperante — neste caso, tudo o que resta a fazer é reiniciar a máquina, sob o risco de perder dados importantes e corromper arquivos fundamentais do sistema.
Veja o vídeo, ao final do artigo, demonstrativo da execução de uma fork bomb no meu sistema.
As fork bombs não são defeitos ou falhas na arquitetura do seu sistema operacional. Na verdade, cabe ao administrador configurar o sistema para que os processos não consumam todos os seus recursos.
Neste artigo, vamos demonstrar como é possível, com alguns procedimentos simples, limitar os recursos disponíveis aos usuários, que podem prevenir o uso malicioso do sistema.

Estabeleça limites para seus usuários com nproc

Uma fork bomb funciona criando uma quantidade exponencial e infindável de processos (muito rapidamente), com o objetivo de saturar o espaço disponível para outros processos — o que inclui os do próprio sistema operacional.

Uma fork bomb mata o seu sistema por inanição de recursos

Configure o arquivo /etc/security/limits.conf para que este imponha limites aos usuários e processos.
Abra o arquivo, com privilégios administrativos e altere a quantidade de processos que usuários e grupos de usuários podem abrir simultaneamente.
Por exemplo, para estabelecer a quantidade máxima de processos do usuário ‘salsicha’ para 300, adicione o seguinte código:

salsicha hard nproc 300

Para limitar a quantidade de processos dos usuários pertencentes ao grupo ‘scoobydoo’ em 50, use o seguinte exemplo:

@scoobydoo hard nproc 50

Com esta configuração, o usuário ‘salsicha’ ou qualquer outro pertencente ao grupo ‘scoobydoo’ ficará impedido de derrubar o sistema com uma fork bomb.
Se tentarem, o sistema ficará indisponível apenas para eles — os usuários e grupos em questão.
Outros usuários no sistema não serão afetados.
É necessário reiniciar o sistema, depois de alterar o arquivo de configuração.

Como limitar a quantidade de processos em uma sessão com ulimit

Um método mais imediato de limitar o número de processos por sessão consiste no uso do comando ulimit.

ulimit -u
841

Conforme o resultado acima, o meu usuário está limitado a abrir até 841 processos simultaneamente.
Tome cuidado ao reduzir o número de processos. Um valor muito baixo pode simplesmente inviabilizar o uso.
Para reduzir o número máximo de processos abertos simultâneos para esta sessão para 30, faça assim:

ulimit -u 30

Se você tentar rodar uma fork bomb agora, ela irá ser executada, mas irá emitir um monte de mensagens:
-bash: fork: retry: recurso temporariamente indisponível
-bash: fork: retry: Não há processos filhos
Isto significa que seu sistema não permitiu que a bomba abrisse mais processos além do limite.
No final, a bomba é finalizada pelo sistema. Veja a imagem:

$ :(){ :|:& };:
Fork Bomb
:(){ :|:& };:

Leve em conta que cada sistema é único.
Se você usa um desktop KDE ou Gnome, precisa imaginar que eles tendem a abrir uma grande quantidade de processos para poder funcionar.

Demonstração real de uma fork bomb em execução

No vídeo abaixo, fica demonstrada execução de uma fork bomb sob controle do ulimit — pouco tempo depois de começar a agir, ela é neutralizada pelo sistema.

Eu usei uma máquina virtual, rodando o Debian 8.1 Jessie, para realizar a demonstração.
Se quiser saber como por no ar a sua própria máquina virtual, leia o artigo Como pôr no ar uma máquina virtual Debian, em 5 minutos.

Achou interessante? Compartilhe! 🙂

O que é uma fork bomb?

Neste post, vou mostrar como funcionam as fork bombs, como fazer uma e como se prevenir deste tipo de código malicioso.
Além das diversas definições, sempre há uma história por ser contada e é por onde vou começar.
Ao final do texto, há alguns links para outros sites onde o assunto também é abordado, caso você queira se aprofundar mais no assunto.
Pernalonga e Elmer Fudd
Se o seu interesse é prevenção, leia Como prevenir a execução de uma fork bomb no seu sistema.

Qual a definição de fork bomb?

Uma definição simples para fork bomb é a de que se trata de um código que tenha a função e a capacidade de se replicar indefinidamente.
Vírus e vermes não valem para esta definição.
À medida em que o código vai auto replicando, consome cada vez mais recursos de memória, de processamento etc.
Como os recursos do sistema não são inesgotáveis, o resultado é que ele entra em colapso.
Há relatos de que códigos deste tipo foram executados por estudantes, na Universidade de Washington, em um Burroughs 5500, em 1969 — o programa fazia 2 cópias de si mesmo, a cada vez em que era executado até que o sistema fosse derrubado.
A esta rápida reprodução do código deve-se o apelido de “trabalho de coelho” (rabbit job) ou wabbit, em alusão ao personagem da Looney Tunes, Elmer Fudd, que trocava o R pelo L (veja link ao final do texto) — a piada só tem graça em inglês.

Como criar uma fork bomb no Ubuntu

Você não precisa ser super usuário para criar e rodar uma fork bomb na maioria das vezes. Normalmente, cabe ao administrador do sistema regular como cada usuário irá usar os recursos.
error iconO código abaixo é um dos mais conhecidos e torna o seu sistema cada vez mais lento, a ponto de parar de responder completamente.
Este código e todos os outros, neste artigo, podem quebrar o seu sistema. Seja responsável!

:(){ :|: & };:

O seu funcionamento é o seguinte:

  • :() — cria/define uma função chamada :
  • {:|: &} — roda a função : e direciona sua saída para a função : e a executa nos bastidores
  • ; — este caractere funciona como separador, na linha de comandos. Equivale a && e permite iniciar uma outra instrução
  • : — executa a função definida no início

É possível desarmar esta bomba com o comando kill, no Linux — mas você provavelmente vai precisar ser muito rápido para fazer isto antes que seu sistema morra por inanição de recursos.
Uma outra forma, mais compreensível, de obter o mesmo resultado nefasto é assim:

bomba()
 {
bomba | bomba &
 }; bomba

No código, acima, fica mais claro ver a função executar-se a si mesma.
Se você gostaria de ver um exemplo não malicioso de execução de uma fork bomb, o código abaixo é seguro para você experimentar:

fork_bomb(){ echo "FORK BOMB"; };
fork_bomb

No terminal, ele pode ser interrompido com Ctrl+C.

Como criar uma fork bomb no Windows

Você pode criar um arquivo .bat, com o seguinte conteúdo:

:bomba
start %0
goto bomba

Ou rodar este código:

%0|%0

As fork bombs funcionam como esquemas de negação de serviço (denial of service) — elas devoram os recursos do sistema.

Como criar uma fork bomb em Perl, Python e em C

Exemplo em Perl:

perl -e "fork while fork" &

Em Python:

import os
  while(1):
      os.fork()

E, por último, uma fork bomb em linguagem C:

#include
int main()
 {
   while(1)
      fork();
 }

Referências

Como se prevenir de uma fork bomb.
Comandos fatais para Linux.
Cyberciti — Understanding fork bomb.
Linuxconfig — How to crash your system with a fork bomb.
Hortelino Troca-Letras (Elmer Fudd) — http://pt.wikipedia.org/wiki/Elmer_Fudd.
The hackers jargon — http://catb.org/~esr/jargon/html/W/wabbit.html.

Um introdução à Programação Orientada a Objetos em C++ (parte III)

« Leia a parte II

Funções membro

É ótimo saber que já conseguimos declarar algumas variáveis. A questão, agora, é como fazer um bom uso delas? A resposta está nas funções. No C++ classes podem ter funções membro – que são declaradas de modo similar às variáveis membro. Vamos usar um exemplo para dar uma idéia melhor do seu funcionamento.
Imagine um quadrado. Primeiro temos que modelar os dados com base nos atributos de um quadrado. Ele tem comprimento, largura e, claro, área. Acreditamos que você já saiba encontrar a área de um quadrado, multiplicando o comprimento pela largura. Esta tarefa pode ser feita por uma função membro:

c++, programação orientada a objetos
Clique na imagem para ampliar.

Este exemplo deve oferecer o resultado “10”. A classe quadrado é muito similar à classe casa, vista anteriormente.
Em seguida, vamos declarar a função area(), que vai retornar um valor int. Você a declara exatamente como a declararia fora de uma classe. Neste caso, fazemos com que area() retorne o resultado da multiplicação do comprimento pela largura e terminamos a classe. A seguir, iniciamos a função main(), que se explica por si mesma.

Definição das funções por fora da definição de classe

Se você tiver uma “penca” de funções para inserir em uma classe, o seu código, obviamente, poderá ficar bagunçado e difícil de entender. Para evitar que isto ocorra, usamos algo chamado operador de resolução do escopo.
Digamos que o que queremos é declarar a função area() fora da nossa definição original da função. Em primeiro lugar, gostaríamos de declarar a classe quadrado, e dentro dela a função area(), como mostrado acima. No entanto, não é interessante inserir o código de função neste ponto, de forma que a definição da classe ficaria assim:

class quadrado
{
public:
	int comprimento, largura;
	int area();
};

Para definir a area() da função membro do lado de fora da definição de classe, faríamos isto aqui:

int quadrado::area()
{
	return comprimento*largura;
}

Este código deverá produzir o mesmo resultado.

Público ou privado?

A velha dicotomia também encontra um lugar para ser discutida aqui. Quando o assunto é a definição de funções membro, você deve aprender a diferença entre membros públicos ou privados de uma classe.
Os membros declarados públicos podem ser acessados de qualquer função de dentro do programa. Podemos explicar isto através de um exemplo. Vamos supor que tenhamos declarado a classe quadrado tal como ela estava anteriormente e tivéssemos tentado acessar a variável comprimento de dentro da função main(), que não é uma função membro da classe:

Clique, para abrir a imagem em outra janela.
Clique, para abrir a imagem em outra janela.

O compilador não terá problemas para entender isto e irá dar o valor 2, como resultado. contudo, se mudarmos a classe quadrado para que se parecesse tal como abaixo, com todos os membros privativos:

class quadrado
{
private:
	int comprimento, largura;
	int area();
};

Se tentarmos rodar o código da função main(), acima, o compilador irá gerar um erro. Membros privados só podem ser acessados dentro de suas funções membro.

Construtores de classe

Temos este método para declarar o valor de cada variável membro de uma classe, abaixo – que me parece um tanto contraprodutivo:

main()
{
   quadrado meu_quadrado;
   meu_quadrado.comprimento=2
   meu_quadrado.largura=3
}

Para cada membro de meu_quadrado, temos que declarar separadamente o seu valor inicial. É claro que não é somente tedioso, mas também é fácil errar ao “pular”, sem perceber, a inicialização de cada membro. E isto vai ficando pior à medida em que as classes vão ficando mais complexas.
Uma maneira de contornar o problema é usar um construtor de classes &emdash; que consiste em uma função inicializada aonde quer que a classe seja usada:

Clique na imagem para ampliar
Clique na imagem para ampliar

Aqui, o resultado previsível é 10.
Primeiro declaramos o construtor de classes, dando-lhe o mesmo nome que a própria classe já tinha. Daí em diante, esta função vai executar-se a cada vez que a classe for usada. A declaramos de forma que ela tenha 2 valores, ambos do tipo int.
A próxima mudança vem na função main(). A cada vez que se declara um objeto como sendo do tipo quadrado, adicionamos uma definição de função. Neste caso, demos às variáveis comprimento1 e comprimento2 os valores de 5 e 2. O construtor então pega estas duas variáveis e atribui seus valores às variáveis membro comprimento e largura.

Arrays e Classes

Claro que você pode usar arrays com classes – o que abre a possibilidade para declarar muito mais variáveis em um período de tempo menor. Vamos ver um exemplo:

Clique, para abrir a imagem em nova janela.
Clique, para abrir a imagem em nova janela.

Não há nada complicado neste nosso último exemplo. Analise-o cuidadosamente 😉
Até a próxima!

Fontes: An Introduction to Object-Oriented Programming in C++
OOP in Wikipedia
Leia mais artigos de programação.

Uma introdução à Programação Orientada a Objetos em C++ (parte II)

« Leia a parte I

O que você precisa ter e para quem estamos escrevendo

Vai contra os nossos princípios obrigar as pessoas a comprar software ou hardware novo apenas para aprender coisas novas. Por isto, todo o artigo é baseado em softwares livres que podem ser baixados legalmente e gratuitamente da Internet.
Desta forma, todos os exemplos usados aqui podem ser compilados com o GNU C++. Este programa pode ser baixado livremente da Internet. No caso de você estar usando o Linux, como eu, você provavelmente já terá tudo do que precisa instalado na sua máquina.

Galera do Ubuntu

Algumas distros não vêm com o g++ instalado por padrão. Quem usa uma distro baseada no Debian, pode instalar rapidamente com o seguinte comando:

sudo apt-get install g++

😉 (dependendo da sua conexão, não dará tempo nem de ir buscar um cafezinho… )
Um bom editor de textos será muito útil. No Ubuntu, bem como em muitas outras distros Linux, é muito comum já vir instalado o nano, que é modo texto e tem realçe de sintaxe (syntax highlighting). Qualquer outro pode ser usado, contudo.

Tipos de dados

Se você já conhece, de alguma forma, a linguagem C++, já deve ter usado alguns tipos básicos de variáveis: int, float, double, bool etc – são chamados de tipos simples de dados. Vamos usar um exemplo inicial: digamos que desejamos representar uma casa. Vamos começar por examinar os diversos atributos de uma casa: número de quartos, o nome da rua, seu número (endereço), se tem ou não um jardim etc. Em C++, podemos representar a casa assim:

int      numero, quartos;
bool     jardim;

Isto já funciona bem para este exemplo, em particular, mas vamos supor que queremos representar várias casas. Vamos supor, ainda, que precisamos fazer o programa mais complexo do que ele está. E se usássemos nosso próprio tipo de dado para representar a casa em C++? Podemos fazê-lo com o uso de classes:

Classuda!

Até o momento, estamos usando nomes de objetos em português, para facilitar um pouco as coisas – desta forma fica fácil separarmos as palavras-chave da linguagem de programação dos nomes das variáveis. Mas isto irá mudar mais para frente.
Continuando com o nosso exemplo de casa, vejamos como é possível modelar uma casa usando uma classe em C++, tal como você pode ver no código abaixo:

class casa
{
public:
	int num, quartos; 
	bool quintal;
};

main()
{
	casa minha_casa;
	minha_casa.num=40; 
	minha_casa.quartos=8;
	minha_casa.quintal=1;
	return 0;
}

Vamos dar uma olhada no que este código faz.
Primeiro, declaramos uma nova classe e a chamamos “casa”.
Depois abrimos o processo de definição da classe, com as chaves ‘{‘. Em seguida, declaramos que todos os membros – tipos de dados pertencentes à classe, que seguem são públicos (falaremos mais disto depois).
Então, declaramos duas variáveis do tipo básico ‘int’ (inteiro). A próxima instrução declara que o membro “quintal” é do tipo bool (booleano – ou 1 ou 0).
Finalizamos a classe ao fechar as chaves ‘}’ e adicionando um ponto-e-vírgula ‘;’ ao final.
Em resumo, o que fizemos foi declarar um novo tipo de dados ou classe, chamada “casa”, que poderemos usar dentro do nosso programa.
Para fazer uso da classe casa, iniciamos a função main(), que é onde a execução do nosso programa começa e termina.
A primeira coisa feita foi declarar a variável minha_casa como sendo do tipo casa, que é a classe que definimos lá no início do programa. Agora, esta variável ganha novas dimensões.
A variável casa tem mais atributos do que apenas int ou float. De nossa classe de definição, demos à classe casa três variáveis: número, quartos e quintal. A variável recém declarada, minha_casa, tem todos estes atributos.
Na segunda linha da nossa função main(), definimos o número membro do objeto minha_casa para 40.
Da mesma maneira, definimos os valores dos outros três membros de dados de minha_casa, antes de fechar a função com o valor de retorno 0.
Neste ponto, você pode estar se perguntando o que pode haver de tão especial com estas três classes? Não seria mais simples usar o método não-orientado a objetos?
Nesta situação, em particular, o método de programação estruturada seria mais simples – principalmente por que estamos falando de um programa muito pequeno que faz muito pouca coisa. A situação muda de figura, contudo, se estivermos escrevendo um programa bem maior e mais complexo. Neste caso, as classes são mais do que apenas úteis, mas essenciais.

Continuação »