___________________ / __ ___ ___ __ \ Artigo sobre C (2a Parte) \ \_\ \ | | / /_/ / Escrito por dec0d3r > _ \ | | / ___/ http://rootspage.host.sk /__/ \__\|_|/__/ apresenta... Rootspage - AnJiNh0' , r0ot e dec0d3r. "Onde tudo pode acontecer..." Este e outros textos podem ser obtidos em http://rootspage.host.sk Leitura para newbies e programadores com aptidao em C . q=P Melhor visualizado em Wordpad(win) ou Vim(linux). 1 - Introducao 2 - Analisando opcoes na linha de comando 3 - Criando processos filhos 4 - open() && close() 5 - Duplincando um File Descriptor 6 - Criando numeros aleatorios 7 - mem*() 8 - Obtendo e Setando ID's 9 - Referencia 10 - Finalizando 1 - [Introducao] Bem, talvez nao tenha sido esclarecido coerentemente na 1a parte deste artigo, mas o mesmo trata-se de explicar algumas funcoes uteis e ate desconhecidas por alguns newbies e nao priorizar uma introducao a linguagem C. Sendo, chegamos a 2a e talvez a ultima parte deste artigo sobre tais funcoes, onde no decorrer do mesmo exemplificarei estas funcoes como visto na primeira parte do artigo. OK, let's go !! 2 - [Analisando opcoes na linha de comando] Certo, quem nunca quis codar um programa onde na linha de comando poderia-se escolher uma ou mais opcoes que o mesmo programa fornecesse, nao entendeu !? Pois bem, vou explicar, o comando "ls" por exemplo nos fornece varias opcoes, entre elas "-l", "-a", "-s" certo, logo ficaria assim: "ls -l", "ls -a" ou "ls -s". Sendo o maximo que voce conseguiu obter foi 'if(strcmp(argv[1],"-h")) help();', entao seus problemas acabaram, pois estou aqui para descrever uma funcao q fara tudo isso para voce sem dificuldades, eu lhe apresento getopt(). Mas antes de tudo, voce deve saber o que eh uma opcao e um parametro: ./prog -h 127.0.0.1 -p 25 \ \ \ \__________ - parametro(25) \ \ \___ - opcao(-p) \ \____ - parametro(127.0.0.1) \__ - opcao(-h) Agora que voce ja consegue diferencia-los, vamos continuar... Descricao: --------- Analisar as opcoes na linha de comando, se tal opcao necessitar do parametro, a mesma precisa vir acompanhada de ':'(dois pontos) na funcao. Para cada opcao valida sera setado o parametro 'optarg' (opcao com ':'). Caso haja uma opcao inesperada, a funcao retornara a opcao '?'. A opcao especial '--' indica que nao ha mais opcoes no decorrer da linha de comando e diz a funcao p/ parar de verificar por mais opcoes. Prototipo: --------- #include int getopt(int argc, char * const *argv, const char *options); - int argc: Basta colocar argc - char * const *argv: Basta colocar argv - const char *options: Opcoes OBS: Seguidas de ':' caso necessite do parametro. Valor retornado: --------------- A funcao retorna a opcao encotrada ou -1 caso nao haja mais opcoes. Exemplo: ------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //exemplo apenas demonstrativo, incompleto. #include /* getopt() */ main(int argc, char **argv) /* nao esqueca de declarar argc e argv. */ { int i; char *entrada, *saida; while((i=getopt(argc, argv, "e:s:h")) != -1) /* 'h' nao usa parametro */ { switch(i) /* diferenciando as opcoes */ { case 'e': entrada = optarg; // aqui esta o parametro break; // `optarg' p/ opcao 'e' case 'n': saida = optarg; // aqui esta o parametro break; // `optarg' p/ a opcao 'n' case 'h': help(); exit(1); case '?': /* opcao padrao, caso ocorra algum erro */ puts("Unknown option !"); help(); exit(1); } } return 0; } =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3 - [Criando processos filhos] O Linux nos permite criar varios processos inferiores(filhos) atraves de um unico processo superior(pai), tipo, eh como se voce tivesse um programa que executasse varios outros programas ou acoes que interligam-se ao processo pai. Dae existe a funcao fork(), alem disto falarei sobre wait(), que serao explicados logo abaixo. A funcao wait() foi apenas explicada superficialmente neste topico, caso queira saber mais sobre a mesma faca 'man wait' no console. Sendo o intuito deste topico eh fork(), pois creio que voce usara fork() na maioria de seus programas como processos concorrentes, isto eh, sem a necessidade de main() esperar o termino do processo filho. Descricao: --------- fork() - Criar processos filhos a partir de um processo pai, ou seja, para criacao de processos multiplos. O processo filho tera um PID exclusivo. wait() - Forca o processo pai esperar a parada ou termino do processo filho. Prototipo: --------- #include #include pid_t fork(void); // fork() int wait(int *status) // wait() - int *status: Valor retornado: --------------- fork() - A funcao sempre retorna -1 caso falhe e 0 na obtencao de sucesso. wait() - Retorna o pid do processo filho ou -1 caso ocorra um erro. Exemplo: ------- // Exemplo retirado do txt "prog_basica.txt" por nash leon. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include #include #include /* fork() */ #include #include /* wait() */ main(){ pid_t pid; int rv; switch(pid=fork()) { case -1: perror("fork"); exit(1); case 0: printf("FILHO: Eu sou o processo filho!\n"); printf("FILHO: Meu PID eh %d\n", getpid()); printf("FILHO: O PID do meu pai eh %d\n", getppid()); printf("FILHO: Digite o meu status de saida(numero pequeno): "); scanf(" %d", &rv); printf("FILHO: Vou sair com meu pai!\n\n"); exit(rv); default: printf("PAI: Eu sou o processo pai!\n"); printf("PAI: Meu PID eh %d\n", getpid()); printf("PAI: O PID do meu filho eh %d\n", pid); printf("PAI: Eu estou agora esperando pelo meu filho para sair...\n\n"); wait(&rv); /* esperando... */ printf("PAI: Status de saida do meu filho eh: %d\n",WEXITSTATUS(rv)); printf("PAI: Estamos saindo daqui!\n\n"); } return 0; } =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Compile o exemplo acima e execute-o. Abra outro console e quando ele pedir para voce digitar o status para saida, no outro console voce digita 'ps aux', vejamos: + Num Console: $ ./fork1 PAI: Eu sou o processo pai! PAI: Meu PID eh 204 PAI: O PID do meu filho eh 205 PAI: Eu estou agora esperando pelo meu filho para sair... FILHO: Eu sou o processo filho! FILHO: Meu PID eh 205 FILHO: O PID do meu pai eh 204 FILHO: Digite o meu status de saida(numero pequeno): + No outro Console: $ ps aux ... nashleon 204 0.0 3.4 1028 356 tty3 S 10:53 0:00 ./fork1 nashleon 205 0.0 3.6 1032 376 tty3 S 10:53 0:00 ./fork1 nashleon 206 0.0 9.5 2612 972 tty4 R 10:54 0:00 ps aux Note que realmente eh criado um processo filho(205). 4 - [open() && close()] Creio eu que todos ja conhecam as funcoes fopen() && fclose(), estas usadas para a abertura e fechamento de arquivos, porem agora vou comentar duas outras funcoes, open() && close(), sua diferenca eh que estas trabalham com FD(file descriptor) enquanto as outras trabalham com um ponteiro de arquivo. Descricao: --------- open() - esta funcao abre/cria um arquivo num determinado modo/permissao. close() - esta funcao fecha um arquivo associado a um FD(file descriptor). >>> Modos: Estes sao o principais modos: O_RDONLY - O arquivo eh aberto para leitura. O_WRONLY - O arquivo eh aberto para escrita. O_RDWR - O arquivo eh aberto para leitura e escrita. E estes sao usados com os modos principas seguidos de '|'. ex: O_RDWR|O_APPEND - abre para leitura, e escrita na ultima linha. ex: O_CREAT|O_WRONLY|O_TRUNC - cria um novo arquivo. O_CREAT - Se o arquivo nao existir, o mesmo sera criado(com o uso deste modo deve-se setar as permissoes). O_TRUNC - Se o arquivo existe, o mesmo sera zerado(0 bytes). O_EXCL - Se O_CREAT tiver sido especificado e o arquivo ja existir ocorrera um erro e open() falhara. O_APPEND - Sera adicionado a ultima linha do arquivo. O_NOFOLLOW - Se o arquivo eh um symbolic link, a funcao falha. O_DIRECTORY - Se o arquivo eh um diretorio, a funcao falha. O_BINARY - O arquivo eh aberto em modo binario. Existem outros modos, porem estes sao os mais uteis. q=] Qualquer coisa de um "$ man open" >>> Permissoes: Estas sao as permissoes que podem ser dadas a arquivos criados por open(), sendo, as mesmas sempre serao setadas com o uso de O_CREAT. S_IRWXU - [00700] o user tem permissao de leitura, escrita e execucao. S_IRUSR (S_IREAD) - [00400] o user tem permissao de leitura. S_IWUSR (S_IWRITE) - [00200] o user tem permissao de escrita. S_IXUSR (S_IEXEC) - [00100] o user tem permissao de execucao. S_IRWXG - [00070] o group tem permissao de leitura, escrita e execucao. S_IRGRP - [00040] o group tem permissao de leitura. S_IWGRP - [00020] o group tem permissao de escrita. S_IXGRP - [00010] o group tem permissao de execucao. S_IRWXO - [00007] outros users tem permissao de leitura, escrita e execucao. S_IROTH - [00004] outros users tem permissao de leitura. S_IWOTH - [00002] outros users tem permissao de escrita. S_IXOTH - [00001] outros users tem permissao de execucao. Prototipo: --------- #include #include #include int open(char *filename, int flag, int perms) - char *filename: Nome do arquivo. - int flag: Modos. - int perms: permissoes(sempre usar com O_CREAT). int close(int FD) - int FD: FD(file descriptor) a ser fechado. Valor retornado: --------------- open() - A funcao retorna o valor do FD(file descriptor) em sucesso ou -1 caso falhe. close() - Retorna 0(zero) se o arquivo foi fechado, ou nao-zero caso o FD seja invalido ou ja esteja fechado. Exemplo: ------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include #include /* headers de open() && close() */ #include #include #include main() { int fd; /* isto eh um FD(file descriptor) */ char *file="rtp.txt"; char *text="testando a funcao open()...\n" "para o txt do decodi lindon!!\n"; /* abre-se o arquivo para leitura e escrita, editando-o na ultima linha e caso o mesmo non exista este eh criado. as permissoes dadas foram "wrx". */ if((fd=open(file, O_RDWR|O_APPEND|O_CREAT, S_IRWXU))==-1) {perror("ARQUIVO"); exit(1);} write(fd,text,strlen(text)); /* escreve-se no arquivo! */ printf("->arquivo escrito com sucesso!!\n"); close(fd); /* fecha-se o mesmo. */ return 0x0; } =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 5 - [Duplincando um File Descriptor] OW! Vamos agora aprender duas funcoes responsaveis pela criacao de uma copia de FD(File Descriptor) antigo. Estou falando de dup() && dup2(), a diferenca das mesmas, veremos no decorrer deste topico. q=] Descricao: --------- dup() && dup2() criam uma copia de um file descriptor antigo. Tanto o velho FD como o novo FD dividem seus fechamentos, suas posicoes apontadas no arquivo e seus flags, isto eh, se num FD a posicao no arquivo eh mudada, com lseek() por exemplo, no outro ocorrera a mesma mudanca. Entenda estas funcoes como se fossem um pipe('|'). dup() - Esta funcao apenas duplica um velho FD, onde ambos dividem o mesmo arquivo e apontador para o arquivo. dup() usa low-bit do velho FD para o novo FD. dup2() - Esta funcao cria uma copia do FD antigo, fechando o novo FD primeiro se necessario, onde ambos dividem o mesmo arquivo e apontador para o arquivo. Prototipo: --------- #include int dup(int oldfd); int dup2(int oldfd, int newfd); - int oldfd: Velho FD. - int newfd: Novo FD. Valor retornado: --------------- dup() - Retorna o novo FD, ou -1 caso ocorra algum erro. dup2() - Retorna o novo FD, ou -1 caso ocorra algum erro. Exemplo: ------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include #include #include #include #include #include #include /* header de dup() && dup2() */ /* representacao dos fd's dos dispositivos em hexa. */ #define STDIN 0 #define STDOUT 1 #define STDERR 2 main() { int fd; // file descriptor(FD) char *log="erro.txt"; if((fd=open(log,O_RDWR|O_CREAT,S_IRWXU))==-1) {perror("arquivo"); exit(1);} close(STDERR); // fecha-se stderr padrao.(saida de erro padrao) dup2(fd,STDERR); /* duplica-se o novo fd como stderr, assim qualquer string de erro non sera imprimido e sim logado em "erro.txt". */ printf("executando shell...\n"); sleep(1); system("/bin/bash"); /* executa-se a shell, e onde ocorrer algum erro(stderr), sera escrito no arquivo "erro.txt". */ close(fd); // fecha-se o fd. return 0x0; } =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 6 - [Criando numeros aleatorios] Bem, existem inumeras funcoes para criacao de numeros pseudo-aleatorios, porem nos prenderemos a apenas duas delas, estas sao rand() e srand(). Descricao: --------- rand() - A funcao retorna um numero pseudo-aleatorio entre 0(zero) e RAND_MAX(definido em `stdlib.h'). Por padrao, rand() sempre gera uma sequencia de numeros a cada vez que o programa eh corrido. Caso necessite produzir uma sequencia diferente em varias corridas, voce deve posicionar(seed) rand() pela chamada de srand() antes da primeira chamada para rand() e fazer o certo uso na diferenciacao do argumento de srand() cada vez. Para obter um numero aleatorio entre '0 e N', deve-se usar rand()%(N+1). Numeros baixos para N sao muito menos aleatorios do que numeros altos, sendo use a funcao random() para tal. srand() - A funcao seta a posicao(seed) para uma nova sequencia de numeros pseudo-aleatorios no retorno de rand(). Estas sequencias estao suscetiveis a repeticao pela chamada de srand() com a mesmo valor da posicao(seed). Se a posicao(seed) nao eh fornecida, a funcao seta automaticamente a posicao(seed) com valor 1. Prototipo: --------- #include int rand(void); void srand(unsigned int seed); - unsigned int seed: Posicao(seed). Valor retornado: --------------- rand() - Retorna o numero pseudo-aleatorio. srand() - Nao ha retorno de funcao. Exemplo: ------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include #include /* rand() && srand() */ #include /* time() */ main() { int i; for(;;) { sleep(1); srand((unsigned int) time(0)); // A cada segundo SEED muda. printf("%d", rand() % 60+(i++)); } // Numero pseudo-aleatorio entre exit(0); } // '0 e 60' inicialmente. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 7 - [mem*()] Ja! Isso mesmo, ja estamos nos aproximando do final deste artigo, porem nao acabou ainda, neste topico veremos seis funcoes interessantes que mexem com a area de memoria de um buffer, sendo elas: memset(), memcpy(), memmove() e memccpy(), memchr(), memcmp(). Eh, sao funcoes lindonas neh. q;) Descricao: --------- memset() - A funcao enche a area de memoria de um buffer com n bytes de um byte constante. memcpy() - A funcao copia n bytes da area de memoria de um buffer_origem para outro buffer_destino, porem as areas de memoria nao pode ser sobrepostas. memmove() - A funcao copia n bytes da area de memoria de um buffer_origem para outro buffer_destino, porem as areas de memoria podem ser sobrepostas. memccpy() - A funcao copia n bytes da area de memoria de um buffer_origem para outro buffer_destino, parando quando um determinado caractere setado eh encontrado. memchr() - A funcao procura em n bytes da area de memoria de um buffer um determinado caractere setado, parando quando o mesmo eh encontrado. memcmp() - A funcao compara n bytes das regioes de memoria entre dois buffers. Prototipo: --------- #include void *memset(void *s, int c, size_t n); - void *s: Buffer. - int c: Byte constante. - size_t n: Numero de bytes a serem preenchidos. void *memcpy(void *dest, const void *src, size_t n); - void *dest: Buffer de destino. - const void *src: Buffer de origem. - size_t n: Numeros de bytes a serem copiados. void *memmove(void *dest, const void *src, size_t n); - void *dest: Buffer de destino. - const void *src: Buffer de origem. - size_t n: Numero de bytes a serem copiados. void *memccpy(void *dest, const void *src, int c, size_t n); - void *dest: Buffer de destino. - const void *src: Buffer de origem. - int c: Caractere a ser encontrado. - size_t n: Numero de bytes a serem copiados. void *memchr(const void *s, int c, size_t n); - const void *s: Buffer. - int c: Caractere a ser encontrado. - size_t n: Numeros de bytes a serem verificados. int memcmp(const void *s1, const void *s2, size_t n); - const void *s1: Buffer_1. - const void *s2: Buffer_2. - size_t n: Numero de bytes a serem comparados. Valor retornado: --------------- memset() - Retorna o apontador para buffer. memcpy() - Retorna o apontador para buffer_destino. memmove() - Retorna o apontador para buffer_destino. memccpy() - Retorna um apontador para o proximo caractere depois do caractere determinado no buffer_destino. memchr() - A funcao retorna para o primeiro caractere encontrado ou NULL caso nao o encontre. memcmp() - Retorna zero (buffer_1 == buffer_2) retorna positivo (buffer_1 > buffer_2) retorna negativo (buffer_1 < buffer_2). Exemplo: ------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include #include #include #include #define SIZE 100 #define CONST 0x41 /* caractere 'A" */ #define PONTO '.' #define BUFF "RTP onde td pode acontecer. q:P\n" main() { int a; char *buffer1; char *buffer2; char *buffer3; buffer1=(char *)malloc(SIZE); buffer2=(char *)malloc(SIZE); buffer3=(char *)malloc(SIZE); memset(buffer1,0x0,(SIZE)); /*zerando buffer1.*/ memset(buffer2,0x0,(SIZE)); /*zerando buffer2.*/ memset(buffer3,CONST,(70)); /*preenche buffer3 com 70 'A's.*/ memcpy(buffer1, BUFF, strlen(BUFF)); /*copia-se BUFF para buffer1.*/ printf("\nbuffer1: %s",buffer1); printf("buffer3: %s\n",buffer3); if(memchr(buffer1, PONTO, strlen(buffer1))) /*verifica sem existe '.' .*/ { /*copia-se buffer1 p/ buffer2 ate encontrar um '.' em buffer1.*/ printf("\nusando memccpy() em buffer1->buffer2:\n"); memccpy(buffer2, buffer1, PONTO, strlen(buffer1)); printf("buffer2: %s\n",buffer2); } printf("\nusando memmove() em buffer2->buffer3:\n"); memmove(buffer3,buffer2,strlen(buffer2)); printf("buffer2: %s\n",buffer2); printf("new-buffer3: %s\n",buffer3); printf("\ncomparando buffer2 e buffer3:\t"); a = memcmp(buffer2,buffer3,strlen(buffer2)); /*comparando*/ if(a==0) printf("buffer2 = buffer3\n"); if(a> 0) printf("buffer2 > buffer3 !!\n"); if(a< 0) printf("buffer2 < buffer3 !!\n"); sleep(1); return 0x0; } =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 8 - [Obtendo e Setando ID's] YES! Mais algumas funcoes interessantes, porem creio que muitos newbies ja as conhecam, eh, falaremos sobre como obter(GET) e setar(SET) identificacoes de users e groups. Complicou neh, entao vamos facilitar, estou falando de obter e setar UID, GID, EUID e EGID, agora voce entendeu neh! Sao funcoes importantes no trabalho com o sistema, sendo, vamos deixar de lero-lero e continuemos. Descricao: --------- Primeiramente veremos como obter(GET) UID, GID, EUID e EGID, porem temos que ter em mente o que sao cada um destes ID's: UID: Real user ID. EUID: Efetivo user ID. GID: Real group ID. EGID: Efetivo group ID. Estas funcoes get*() sempre terminam em sucesso. getuid() - Obtem o UID do processo corrente. geteuid() - Obtem o EUID do processo corrente. getgid() - Obtem o GID do processo corrente. getegid() - Obtem o EGID do processo corrente. Atencao, voce deve setar os mesmos de acordo com seus privilegios, sendo, nao adianta usar `setuid(0)' pensando que obtera privilegios de root no decorrer do processo. q;) setuid() - Seta o UID do processo corrente. seteuid() - Seta o EUID do processo corrente. setreuid() - Seta o UID e/ou EUID do processo corrente, se UID ou EUID forem -1 o mesmo nao sofrera alteracao. Sendo `seteuid(EUID)' eh o mesmo que `setreuid(-1, EUID)'. setgid() - Seta o GID do processo corrente. setegid() - Seta o EGID do processo corrente. setregid() - Seta o GID e/ou EGID do processo corrente, se GID ou EGID forem -1 o mesmo nao sofrera alteracao. Sendo `setegid(EGID)' eh o mesmo que `setregid(-1, EGID)'. Prototipo: --------- #include #include uid_t getuid(void); uid_t geteuid(void); gid_t getgid(void); gid_t getegid(void); int setuid(uid_t uid) - uid_t uid: UID a ser setado. int seteuid(uid_t euid); - uid_t euid: EUID a ser setado. int setreuid(uid_t ruid, uid_t euid); - uid_t ruid: UID a ser setado. - uid_t euid: EUID a ser setado. int setgid(gid_t gid) - gid_t gid: GID a ser setado. int setegid(gid_t egid); - gid_t egid: EGID a ser setado. int setregid(gid_t rgid, gid_t egid); - gid_t rgid: GID a ser setado. - gid_t egid: EGID a ser setado. Valor retornado: --------------- getuid() - Retorna UID do processo corrente. geteuid() - Retorna EUID do processo corrente. getgid() - Retorna GID do processo corrente. getegid() - Retorna EGID do processo corrente. setuid() - Retorna 0(zero) em sucesso e -1 caso haja erro. seteuid() - Retorna 0(zero) em sucesso e -1 caso haja erro. setreuid() - Retorna 0(zero) em sucesso e -1 caso haja erro. setgid() - Retorna 0(zero) em sucesso e -1 caso haja erro. setegid() - Retorna 0(zero) em sucesso e -1 caso haja erro. setregid() - Retorna 0(zero) em sucesso e -1 caso haja erro. Exemplo: ------- + Primeiramente compile como root: # gcc -o id id.c + Depois sete o suid-bit root: # chmod +s id + E como um user_normal execute-o: $ ./id =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include #include #include /* headers destas funcoes. */ #include #include #define ZERO 0 #define ERR -1 #define COMM "/bin/ping 127.0.0.1" main() { int a,b,c,d; a=getuid(); // obtem-se o uid. b=getgid(); // obtem-se o gid. c=geteuid(); // obtem-se o euid. d=getegid(); // obtem-se o egid. printf("meu uid atual eh: %d\n", a); printf("meu gid atual eh: %d\n", b); printf("meu euid atual eh: %d\n", c); printf("meu egid atual eh: %d\n", d); printf("vamos altera-los!!\n\n"); /* seta-se o uid,euid,gid e egid com 0. */ if((setreuid(ZERO, ZERO)) == ERR) {perror("uid e euid"); exit(1);} if((setregid(ZERO, ZERO)) == ERR) {perror("gid e egid"); exit(1);} sleep(1); printf("agora meu uid eh: %d\n", getuid()); printf("agora meu gid eh: %d\n", getgid()); printf("agora meu euid eh: %d\n", geteuid()); printf("agora meu egid eh: %d\n", getegid()); printf("executando ping!!\n"); sleep(1); system(COMM); /* executa-se o ping como root. */ printf("\nretornando aos id's de origem...\n\n"); /* seta-os novamente para user q executou o programa. */ setuid(a); setgid(b); seteuid(c); setegid(d); printf("pronto.. saindo!!\n"); return ZERO; } =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 9 - [Referencia] Bem, as funcoes que aqui estao foram pesquisadas nos devidos locais: Manpages - " $ man ". q;) Programming in C - Libc Reference - RHIDE 1.4v 10 - [Finalizando] FODZ! Eh caro newbies, chegamos ao termino deste curto txt, porem nao desanime, procure por mais txts em portugues sobre funcoes que lhes propiciarao um bom source, mais textos virao e com um aumento continuo na qualidade. Eu nao sou nem um super-programador, disto eu tenho plena certeza, como voces apenas sei o basico da linguagem C, estou longe de programar muitas coisas que desejo, como tambem nao tenho base para tais. Esta linguagem eh muito extensa e complexa para aprendermos em pouco tempo, sendo, a cada programa criado mais logica voce obtera e assim alcancara seus objetivos. Alguns exemplos foram tirados de fontes que achei pela net, sendo espero que as entendam com maxima clareza. Em sua aprendizagem nao tome por base outros, pois cada um aprende de acordo com seus objetivos quando codam. AH! para quem nao sabe, RHIDE eh um IDE para Windows que instalei em minha maquina. Fico aqui e desejo boa sorte em sua aprendizagem. q;) Agradeco a todos meus amigos nesta jornada dificil e plausivel, anjinho, r0ot, nachu feion, sleitu, klogd, esqui, bludi, fantinha, a galera do #dnh, #c/c++, #int80h, #feanor, entre outros que nao recordo-me neste momento e principalmente a grande UNSEKURITY SCENE. q:) " RTP, onde tudo pode acontecer..." decodi. ograma criado mais logica voce obtera e assim alcancara seus objetivos. Alguns exemplos foram tirados de fontes que achei pela net, sendo espero que as entendam com maxima clareza. Em sua aprendizagem nao tome por base outros, pois cada um aprende de acordo com seus objetivos quando codam. AH! para quem nao sabe, RHIDE eh um IDE para Windows que instalei em minha maquina. Fico aqui e desejo boa sorte em sua aprendizagem. q;) Agradeco a todos meus amigos nesta jornada dificil e plausivel, anjinho, r0ot, nachu feion, sleitu, klogd, esqui, bludi, fantinha, a galera do #dnh, #c/c++, #int80h, #feanor, entre outros que nao recordo-me neste momento e principalmente a grande UNSEKURITY SCENE. q:) " RTP, onde tudo pode acontecer..." decodi.