Archive for Linux
November 23, 2009 a las 3:04 pm por Edwin Plauchu · Archivado en FreeBSD, Linux, Solaris
Las causas comunes como obtendremos esto son:
* Tratando de escribir a un puntero NULL
char *foo = NULL;
strcpy(foo, "bang!");
* Usando un puntero no inicializado
char *foo;
strcpy(foo, "bang!");
* Accesar mas alla de los limites de un arreglo
int bar[20];
bar[27] = 6;
* Tratando de almacenar algo sobre memoria de solo lectura
char *foo = "My string";
strcpy(foo, "bang!");
* Y por ultimo utilizando de manera tonta free y malloc
char bar[80];
free(bar);
o
char *foo = malloc(27);
free(foo);
free(foo);
November 18, 2009 a las 5:06 pm por Edwin Plauchu · Archivado en Ubuntu, FreeBSD, Linux
Yo fui un usuario de Slackware
Y solia compilarme todas las fuentes de lo que requeria… y estas siempre usaban el configure.
Aqui ya te puedes dar cuenta como fregados se puede generar una aplicacion con su configure.. para que la puedas distribuir..
PDF de las Autotools
Mejores Practicas al usar autotools
November 17, 2009 a las 8:26 pm por Edwin Plauchu · Archivado en Linux
Usa avisplit que viene en el paquete de transcode de ubuntu con un comando como
$avisplit -i archivo_a_cortar.avi -s Tamaño_en_megas
Pero si quieres usar algo del entorno gráfico usa avidemux (aunque a mi me desincroniza el
audio).
November 17, 2009 a las 8:25 pm por Edwin Plauchu · Archivado en Linux
ffmpeg -i goemon.avi -target pal-vcd goemon.mpg
August 10, 2009 a las 4:27 pm por Edwin Plauchu · Archivado en Programacion, FreeBSD, Linux, Solaris
Me pidieron un programita hecho en C residente en memoria. Un demonio pues!…
Aqui les dejo el codigo base del daemon unix tradicional.
El daemon lo hice para un IBM AIX 5.3 sobre arquitectura power pc.
Y poco despues lo compile en linux, y no hubo nada de problema.. codigo 2000% porciento guapo y portable.
/**********************************
* UNIX Daemon Server Programming *
* Written by Edwin Plauchu *
* mailto:pianodaemon@gmail.com *
**********************************/
#include stdio.h
#include stdlib.h
#include fcntl.h
#include signal.h
#include unistd.h
#include string.h
#define RUNNING_DIR "/tmp"
#define LOCK_FILE "cacherd.lock"
#define LOG_FILE "cacherd.log"
void log_message(filename,message)
char *filename;
char *message;
{
FILE *logfile;
logfile=fopen(filename,"a");
if(!logfile) return;
fprintf(logfile,"%sn",message);
fclose(logfile);
}
void signal_handler(sig)
int sig;
{
switch(sig) {
case SIGHUP:
log_message(LOG_FILE,"Senal de hangup cachada");
break;
case SIGTERM:
log_message(LOG_FILE,"Senal de Terminacion cachada");
exit(0);
break;
}
}
void daemonize(){
int i,lfp;
char str[10];
// Primero obtenemos el indentificador de Proceso
if( getppid() == 1 ) return;
// Ahora generamos un proceso hijo y obtenemos su PID
// mediante la variable i
i=fork();
// Comprobamos que el proceso hijo este lanzado de manera correcta
// Verificando los posibles ERRORES de lanzamiento
// En caso de existir un error de lanzamiento en el proceso hijo
// procedemos a la finalizacion del proceso padre
if (i<0) { exit(1); } // fork error, el proceso hijo no pudo ser creado
if (i>0) { exit(0); } /* Padre existe */
// Proceso hijo (Demonio) continua
setsid(); // Crea una sesión y define el ID de grupo del proceso
/* Cerrar todos los descriptores de archivo
OJO: Esto evita que el hijo use los mismos decriptores de fichero que el padre*/
for (i=getdtablesize();i>=0;–i) close(i);
i=open(”/dev/null”,O_RDWR); dup(i); dup(i); /* handle standart I/O */
umask(027); /* Establece los permisos que le seran dados a los nuevos archivos a crear */
chdir(RUNNING_DIR); /* Cambia el directorio de ejecucion */
/* Abre el archivo de bloqueo en modo lectura/escritura, pero
si el archivo no existiece, lo crea con el permiso 640 */
lfp=open(LOCK_FILE,O_RDWR|O_CREAT,0640);
if (lfp<0) { exit(1); } /* No puede ser abierto */
if (lockf(lfp,F_TLOCK,0)<0) exit(0); /* No puede ser bloqueado el fichero para este proceso*/
/* Primera instancia continua */
sprintf(str,"%dn",getpid());
// Escribimos el PID al fichero de bloqueo
write(lfp,str,strlen(str));
signal(SIGCHLD,SIG_IGN); /* Ignora hijo */
signal(SIGTSTP,SIG_IGN); /* Ignora Senales tty */
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGHUP,signal_handler); /* Cacha Senal hangup (kill -1 PID)*/
signal(SIGTERM,signal_handler); /* Cacha Senal de Terminacion (kill -15 PID)*/
}
int main(){ daemonize(); while(1) sleep(1); }
July 8, 2009 a las 9:27 am por Edwin Plauchu · Archivado en Microsoft, FreeBSD, Linux
Navegando hace unos instantes, encontré este “humor gráfico” en el cual podemos apreciar los distintos puntos de vista de los diferentes sistemas operativos, unos contra otros, como por ejemplo; como ve un “maquero” a un “linuxero” y viceversa. Espero que les guste.

May 28, 2009 a las 6:17 pm por Edwin Plauchu · Archivado en Programacion, Linux, Varios
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
#include "unistd.h"
int main(){
//Aqui se define STDIN como el elemento 0 del arreglo pfds
//Aqui se define STDOUT como el elemento 1 del arreglo pfds
//Aqui se define STDERR como el elemento 2 del arreglo pfds
int pfds[2];
// Establecemos un buffer de 30 bytes
char buf[30];
//Creamos la tuberia
if (pipe(pfds) == -1) {
perror("pipe");
exit(1);
}
printf("Escribiendo sobre el file descriptor de STDOUT");
write(pfds[1], "Edwin", 5);
printf("Lellendo sobre el file descriptor de STDIN");
read(pfds[0], buf, 5);
printf("Valor transportado en nuestra tuberia: \"%s\"n", buf);
}

Basicamente, una llamada a pipe() retorno un par de file descriptors.
May 28, 2009 a las 12:06 pm por Edwin Plauchu · Archivado en Programacion, Linux
Aqui les dejo otra explicacion mas de la administracion de la memoria virtual en linux…
Antes deberas leer esto si no sabes que ondas con lo que pongo aqui
Cada no es representado por pg_data_t, el cual es un tipo definido para la estructura pglist_data. Cuando se asigna una pagina, Linux usa una politica de asignar memoria del nodo mas cercano a la CPU. A razon de que el proceso corre sobre la misma CPU,
es mas razonable que la memoria del actual nodo(o banco de memoria) sea la que se use. La estructura es declara como sigue en
:
typedef struct pglist_data {
zone_t node_zones[MAX_NR_ZONES];
zonelist_t node_zonelists[GFP_ZONEMASK+1];
int nr_zones;
struct page *node_mem_map;
unsigned long *valid_addr_bitmap;
struct bootmem_data *bdata;
unsigned long node_start_paddr;
unsigned long node_start_mapnr;
unsigned long node_size;
int node_id;
struct pglist_data *node_next;
} pg_data_t;
Bien, ahora describiremos cada uno de los nodos de esta estructura:
node_zones : La zonas para este nodo son ZONE HIGHMEM, ZONE NORMAL, ZONE DMA.
node_zonelists : Este es el orden de las zonas asignadas proveniente de build_zonelists() en mm/page alloc.c , este orden se establece cuando se llamo a free_area_init_core(). Una asignacion fallida en ZONE HIGHMEM puede mandar de regreso a ZONE NORMAL o de regreso a ZONE DMA.
nr_zones : Este es el numero de zonas sobre este nodo, entre uno y tres. No todos los nodos llegaran a tener 3.
node_mem_map Esta es la primera pagina del arreglo de structuras page que representan cada cuadro fisico en el nodo. Es sera acomodado en algun lugar dentro del global mem_map_array.
valid_addr_bitmap : Este es un mapa de bits que describe huecos en el nodo de memoria. En realidad este solo es usado para SPARC.
node_size : Numero total de paginas en esta zona.
node_id : Esta es la ID del nodo (NID).
node_next : Puntero a el siguiente nodo sobre una lista terminada en NULL.
bdata : Este es solo del interes del asignado de memoria de arranque ( boot memory ), hablaremos de el despues.
node_start_paddr : Esta es la principal direccion fisica del nodo.
node_start_mapnr : Este otorga el offset de la pagina dentro del mapa global de memoria (mem_map). Este es calculado en free_area_init_core() , el cual calcula el numero de paginas entre mem_ map y el mem_map local para este nodo llamado lmem_map.
Todos los nodos en el sistema son mantenidos sobre una lista llamada pgdat_list. Los nodos son albergados sobre una lista, como estos van siendo inicializados por la funcion init_bootmem_core().
En los nucleos de linux mas recientes a 2.2, un macro for_each_pgdat(), el cual es trivialmente definido como un loop for, es puesto para mejorar la legilbilidad del codigo.
May 26, 2009 a las 5:24 pm por Edwin Plauchu · Archivado en Programacion, Linux
Aqui les muestro como compilo un programita para ejemplificar el uso de hilos
[j4nusx@localhost ~]$ gcc hilos.c -lpthread -Wall -o hilos
[j4nusx@localhost ~]$ ./hilos
En Funcion main: Creando el Hilo 0
En Funcion main: Creando el Hilo 1
En Funcion main: Creando el Hilo 2
En Funcion main: Creando el Hilo 3
En Funcion main: Creando el Hilo 4
Hola esto se ejecuta en el hilo #0!
Hola esto se ejecuta en el hilo #1!
Hola esto se ejecuta en el hilo #2!
Hola esto se ejecuta en el hilo #3!
Hola esto se ejecuta en el hilo #4!
Aqui el codigo fuente
#include "pthread.h"
#include "stdio.h"
#include "stdlib.h"
#define NUM_THREADS 5
// La funcion que es utilizada en un Hilo
// debera de retornar un puntero sin tipo
void *ImprimeSaludo(void *threadid){
long tid;
// Aqui se castea lo que le fue pasado
// al hilo como atributos
tid = (long)threadid;
printf("Hola esto se ejecuta en el hilo #%ld!n", tid);
pthread_exit(NULL);
}
// --- Aqui finaliza la funcion que
// sera llamada en el hilo
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t < NUM_THREADS; t++){
printf("En Funcion main: Creando el Hilo %ldn", t);
rc = pthread_create(&threads[t], NULL, ImprimeSaludo, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %dn", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
La función que nos permite crear un un nuevo hilo de ejcución es pthread_create() que admite cuatro parámetros:
pthread_t * es un puntero a un identificador de thread. La función nos devolverá este valor relleno, de forma que luego podamos referenciar al hilo para “hacerle cosas”, como matarlo, esperar por él,etc.
pthread_attr_t * son los atributos de creación del hilo. Hay varios atributos posibles, como por ejemplo la prioridad. Un hilo de mayor prioridad se ejecutará con preferencia (tendrá más rodajas de tiempo) que otros hilos de menor prioridad. Se puede pasar NULL, con lo que el hilo se creará con sus atributos por defecto y para nuestro ejemplo es suficiente. Si queremos un programa que cree y destruya hilos continuamente, no vale NULL, ya que con esta opción dejaremos memoria sin liberar cada vez que termine un hilo.
void *(*)(void *) es un tipo la mar de raro. Aunque asuste, no es más que el tipo de una función que admite un puntero void * y que devuelve void *. Eso quiere decir que a este parámetro le podemos pasar el nombre de una función que cumpla lo que acabamos de decir. Esta función es la que se ejecutará como un hilo aparte. El hilo terminará cuando la función termine o cuando llame a la función pthread_exit() (o que alguien lo mate desde otra parte del código). Es bastante habitual hacer que esta función se meta en un bucle infinito y quede suspendida en un semáforo o a la espera de una señal para hacer lo que tenga que hacer y volver a quedar dormida.
void * es el parámetro que se le pasará a la función anterior cuando se ejecute en el hilo aparte. De esta manera nuestro programa principal puede pasar un único parámetro (que puede ser cualquier cosa, como una estructura compleja) a la función que se ejecutará en el hilo. La función del hilo sólo tendrá que hacer el “cast” adecuado.
La función pthread_create() devuelve 0 si todo ha ido bien. Un valor distinto de 0 si ha habido algún problema y no se ha creado el thread.
Si deseas saber mas a detalle el asunto de los hilos en linux, te recomiendo la siguente liga
May 26, 2009 a las 3:34 pm por Edwin Plauchu · Archivado en Programacion, Linux
Linux esta disponible para una gran gama de computadores, y a causa de esto, los desarrolladores encontraron una manera independiente a la arquitectura para describir lo que es la memoria.
CONCEPTOS QUE PREVALECEN EN LA ADMINISTRACION DE MEMORIA VIRTUAL (VM)
NUMA: Forma no uniforme de acceso a la memoria.

En Maquina grandes la memoria puede ser agrupada en bancos de memoria, cada uno de estos bancos puede ser asignado a un CPU o a un DMA.
Cada banco de memoria es llamado NODO.
Un nodo en linux es representado por la estructura “pglist_data“, aun si la arquitectura es UMA.
UMA: Acceso Uniforme a memoria.
La Estructura “pglist_data” es siempre referenciada mediante su tipo “pg_data_t“.
Cada NODO en el sistema es albergado sobre una lista terminada en NULO, cuyo nombre es “pgdat_list” y cada nodo es linkeado al siguiente con el campo pg_data_t->node_next.
Para arquitecturas UMA (Las pcs de escritorio son de este tipo de arquitectura), solo existe una estructura estatica “pg_data_t” llamada “contig_page_data” que es usada.
Cada banco de memoria o NODO, es dividido en bloques llamados zonas. Las zonas representan rangos dentro de la memoria.
La Zona es definida por la estructura “zone_struct“, pero es siempre referenciada mediante el tipo de dato definido “zone_t“.
Las zonas pueden ser de 3 tipos:
- DMA
- NORMAL
- HIGHMEM
ZONA_DMA: Memoria en rangos bajos de memoria fisica, requerida por los dispositivos ISA.
ZONA_NORMAL: Ubicada en la posicion alta del espacio lineal de direcciones.
ZONA_HIGHMEM: Memoria restante en el sistema y no es directamente mapeada por el kernel.
La memoria del sistema es agrupada en lotes llamados “page frames“, Cada “page frame” es representado por la estructura “page” y todas las estructuras son mantenidas en un arreglo global llamado “mem_map“, el cual es usualmente almacenado al inicio de la ZONA_NORMAL o del area reservada para la imagen del kernel cargada en maquinas de poca memoria.
