segunda-feira, 22 de novembro de 2010

Prototype maker 2.0

There is no patter alignment anymore .. !

# Create the prototypes for all functions
# on a given C source file
use strict;
use warnings;

my @ctypes = qw(
    void
    unsigned 
    signed 
    long 
    short 
    int 
    float 
    double 
    struct 
    char
    static
    const
);

my @contents = <>;

for my $line (0 .. $#contents) {
    my $lref = \$contents[$line];
    my $prot = '';
    for my $type (@ctypes) {
        if ($$lref =~ /^$type/) {
             while ($contents[$line] !~ /\{/) { # seek for {
                $prot .= "$contents[$line++] ";
            }
            chop $prot;            # the last space
            $prot =~ s/\n//go;     # remove LFs 
            $prot =~ s/\w*,/, /go; # remove argument intentifiers
            $prot =~ s/\w*\)/)/go; # remove the last argument 
            $prot .= ';';           # append a semicolon 
            print $prot, "\n";
            next;
        }
    }
}

sábado, 20 de novembro de 2010

Perl script to generate basic prototypes..

Typedefs are not supported and you need to code your
functions with follow patter:
type
function_indetifier (list_of_parameters)
{ ... hereafter makes no difference

usage: cat souce.c | perl prot.pl > prots.txt
then copy and paste where you want...




# Create the prototypes for all functions
# on a given C source file
use strict;
use warnings;

my @ctypes = qw(
    unsigned 
    signed 
    long 
    short 
    int 
    float 
    double 
    struct 
    char
    static
    const
);

my @contents = <>;

for my $line (0 .. $#contents) {
    my $lref = \$contents[$line];
    my $prot = '';
    for (@ctypes) {
        if ($$lref =~ /^$_/) {    
            my $func = $contents[++$line];
            $func =~ s/\w*,/,/g;
            $func =~ s/\w*\)/)/g;
            $prot = "$$lref $func;";
            $prot =~ s/\n//g;
            print "$prot\n";
            next;
        }
    }
}
           
test: http://ideone.com/5tE0F
note: I will coment that hash implementation soon..

quarta-feira, 10 de novembro de 2010

Mini web server in perl (really small han?)

use strict;
use warnings;
use LWP;
use HTTP::Daemon;

# the parameters are 
# the user/group user to restrict permissions, the port (default 80)
# the local addres (default locahost)
# respectivaly
my ($userg, $port, $laddres) = @ARGV;
$userg or die 'You need to suply a nonroot user/group as first parameter'; 
my ($user, $group) = split ('/', $userg);

$port = 80 unless $port;
$laddres = 'localhost' unless $laddres;

my $server = new HTTP::Daemon (
    LocalAddr => $laddres,
    LocalPort => $port,
    Listen => 5,
    Reuse => 1,
) || die $!;

$> = getpwnam $user || die $!; 
$) = getgrnam $group || die $!; 


while (my $con = $server->accept()) {
    my $pid = fork();
    if (!$pid) { 
        my $req = $con->get_request();
        print $req->as_string();
        my $file = $req->url();
        $file =~ s/^.//g;    
        $con->send_file_response($file);
    } elsif ($pid) { next;  
    } else { print STDERR "fork: $!\n" };
}


domingo, 31 de outubro de 2010

Binary Tree made simple

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct bt {
    void *data;
    char *key;
    struct bt *right, *left;
};

/* prototypes */
int add_btnode (struct bt **, char *, void *);
void init_bt (struct bt **);
struct bt *search_btnode (struct bt *, char *);
void print_inorder (struct bt *);

int
main (void)
{
    struct bt *root, *p;
    init_bt (&root);
    add_btnode (&root, "Daniel", "C");
    add_btnode (&root, "Bia", "asm");
    add_btnode (&root, "Nelson", "Php");
    p = search_btnode (root, "Bia");
    printf ("Bia is an %s hacker\n", (char *)p->data);
    puts ("\n\nIN ORDER");
    print_inorder (root);
     
    return 0;
}

void
init_bt (struct bt **r)
{
    *r = NULL;
}

int
add_btnode (struct bt **root, char *k, void *dat)
{
    if (!*root) {
        *root = malloc (sizeof (struct bt));
        if (!*root) exit (EXIT_FAILURE);
        (*root)->key = k;
        (*root)->data = dat;
        (*root)->right = (*root)->left = NULL;
        return 0;
    }    
    if (strcmp (k, (*root)->key) > 0)
        add_btnode (&(*root)->right, k, dat);
    else if (strcmp (k, (*root)->key) < 0)
        add_btnode (&(*root)->left, k, dat);
    return -1;
} 

struct bt *
search_btnode (struct bt *root, char *k)
{
    int rval;
    if (!root) return NULL;
    rval = strcmp (k, root->key);
    while (root && rval) {
        if (rval > 0) root = root->right;
        else root = root->left;
        rval = strcmp (k, root->key);
    }
    return root;
}

void
print_inorder (struct bt *root)
{
    if (!root) return;    
        
    print_inorder (root->left);
    printf ("%s => %s\n", root->key, (char *)root->data);
    print_inorder (root->right);
}


Tested at: http://ideone.com/vL1N0

quinta-feira, 28 de outubro de 2010

Testing Linked List against multiple data types

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct instance {
    int a, b;
    float f;
    char str[8];
    int (*p) (const char *);
};

int
main (void)
{
    llist mylist;
    node *bufnode;
    struct search_result sr;
    int i = -1;
    char string[] = "Hello World";
    float myf = 2.5;
    struct instance strc = {1, 2, 3.4, "Five", puts};
    struct instance otherstrc;

    init_llist (&mylist);

    bufnode = init_node ("struct", (char *)&strc, sizeof (struct instance));
    add_node (&mylist, bufnode);

    bufnode = init_node ("int", (char *)&i, sizeof (int));
    add_node (&mylist, bufnode);

    bufnode = init_node ("string", string, strlen ("Hello World") + 1); 
    add_node (&mylist, bufnode);

    bufnode = init_node ("float", (char *)&myf, sizeof (float));
    add_node (&mylist, bufnode);

    sr = search_node (&mylist, "struct");
    memcpy (&otherstrc, sr.n->data, sizeof (struct instance));
    printf ("otherstrc: %d %d %f %s\n", 
        otherstrc.a, otherstrc.b, otherstrc.f , otherstrc.str);
    otherstrc.p("Nice?");
    del_node (&mylist, sr.n, sr.prior);

    sr = search_node (&mylist, "int");
    printf ("%d\n", *(int *)sr.n->data);
    del_node (&mylist, sr.n, sr.prior);

    sr = search_node (&mylist, "float");
    printf ("%f\n", *(float *)sr.n->data);
    del_node (&mylist, sr.n, sr.prior);

    sr = search_node (&mylist, "string");
    printf ("%s\n", sr.n->data);
    del_node (&mylist, sr.n, sr.prior);

    if (! mylist.first)
        printf ("empty\n");
    return 0;
}


Tested here: http://ideone.com/lTlp9

quarta-feira, 27 de outubro de 2010

How to read an unknown lenght line to a string in C

/*===========================*
 *    Reading dinamically    *
 *===========================*/
#include <stdio.h>
#include <stdlib.h>

#define DATALEN BUFSIZ 

struct block {
    char data[DATALEN];
    struct block *next;
};

struct block *
alloc_block (void)
{
    struct block *new = malloc (sizeof (struct block));
    if (!new) {
        perror ("malloc");
        exit (EXIT_FAILURE);
    }
    return new;
}

int
readfrom (char **str, FILE *stream, int finalchar)
{
    struct block *first;
    struct block *ptr;
    struct block *prev;
    struct block *tmp;
    int ch, indx = 0, nblocks = 1, strindx;

    first = ptr = alloc_block();
    ptr->next = NULL;
    /* read and alloc string as a linked list */
    while ((ch = getc(stream)) != finalchar) {
        if (indx == DATALEN) {
            tmp = alloc_block ();
            indx = 0; 
            nblocks++;
            tmp->next = NULL;
            ptr->next = tmp;
            ptr = tmp;
        } else if (indx > DATALEN) {
            fprintf (stderr, "readline error: Index error\n");
            exit (EXIT_FAILURE);
        }
        ptr->data[indx++] = ch;
    }
    ptr->data[indx] = '\0';
    *str = malloc ( (nblocks - 1) * DATALEN + indx );    
    /* run in list freeing it */
    for 
    (ptr = first, strindx = 0; 
     ptr != NULL; 
     prev = ptr, ptr = ptr->next, free (prev)) 
    {
        for 
        (indx = 0; 
         indx < DATALEN && ptr->data[indx] != '\0'; 
         indx++, strindx++) 
        {
            (*str)[strindx] = ptr->data[indx]; 
        }
    }
    (*str)[strindx] = '\0';
    return strindx;
}

        
int
main (void)
{
    char *str;
    int len;
    len = readfrom (&str, stdin, '\n');
    printf ("Your string with len %d is `%s'\n", len, str);
    return 0;
}

sexta-feira, 22 de outubro de 2010

Layout update

Today I update the blog layout, select a cool space backgroud
and etc. Thanks Google :-)

quinta-feira, 21 de outubro de 2010

The 3 simple sort algorithms

/*    Bubble Sort    */
void
bsort (int ar[], int len)
{
    int control = 1, i, tmp;
    while (control--) {
        for (i = 0; i < len - 1; i++) 
            if (ar[i] > ar[i + 1]) {
                tmp = ar[i], ar[i] = ar[i + 1], ar[i + 1] = tmp;
                control = 1;
            }
    }
}

/*    Inserction Sort    */
void
isort (int ar[], int len)
{
    int i, j, tmp;
    for (i = 1; i < len; i++, ar[j + 1] = tmp) 
        for (j = i -1, tmp = ar[i]; j >= 0 && ar[j] > tmp; j--)
            ar[j + 1] = ar[j];
}

/*    Selection Sort    */
void
ssort (int ar[], int len)
{
    int i, j, lesser, tmp, at;
    for (i = 0; i < len - 1; 
         tmp = ar[i], ar[i] = lesser, ar[at] = tmp, i++)
        for (j = i + 1, lesser = ar[i], at = i; j < len; j++) 
            if (lesser > ar[j]) 
                lesser = ar[j], at = j;
}
tested at http://codepad.org/3Co4Qipn

quarta-feira, 13 de outubro de 2010

gkos Linked List API

The linked list api that I talked about some weeks ago.

I will try to keep it simple, but this was not optimized.


There are 2 files: llapi.h, libllapi.c.

The first you will include in your application as:
#include "llapi.h"
The secont you will use to make an archive.
Do as follow:
gcc -c libllapi.c
ar -rcs libllapi.a libllapi.o


Before to use your list you need to declare and
initialize it.
llist mylist;
init_llist (&mylist);

Ok, now you have a ready to use list, but, what you
may put inside it? The answer is nodes, of course.
Nodes are declared as an struct containing three members:
  • a key for you search it latter
  • a data field with BUFSIZ bytes
  • a pointer to next node
So you need a node buffer, and maybe a data buffer
node *nodebuf;
char data[BUFSIZ];

note: The data buffer need to have BUFSIZ length because the init_node() will try to copy BUFSIZ bytes to node data member. If data buffer has less than BUFSIZ bytes you will recieve a segment fault error at run time, since init_node() will try to dereference an array beyond its boundaries.

You can initialize a node as
nodebuf = init_node ("KeyName", data);
Or you can initialize it by hand. Then, with an initialized
node you can add it in list with:
add_node (&mylist, nodebuf);
After that your node is added in your list. The bufnode will
be set to null, so you can't touch list through it. The maximum number
of nodes is demilited by your avaible memory. The nodes are allocated
inside init_node function. If there is no memory avaible the programm
will exit with a failure status and an error message.

 Since this you may want to free some space, to do this you will need
to delete some nodes. You can delete a node with del_node () function
but you need to know what to delete before to delete. The search_node ()
function is what you want.
struct search_result sr = search_node (&mylist, "keyname");
search_result struct is declared as follow:
struct search_result {
    node *n; 
    node *prior;
};
n points to node that you searched. It will be NULL if your node was not found.
prior is an implementation detail. If the node was found and it's not the first
item in list, prior will point the prior node of n.


Now that you found (or not) your node, sr.n points to it. You can delete it
with the follow statement:
int rval = del_node (&mylist, sr.n, sr.prior); 
The integer rval will hold the return status of del_node () function.
Note that I don't check if my "keyname" was found. The del_node () function
will return BAD_CALL if you call it with 2nd and 3rd arguments as NULL
and will stat if you are trying to delete the first node. The sr.prior member
is used to linking stuff, but you don't need to botter with it, just recieve
from search_node () and pass as it is to del_node () everything is stated
by del_node ().


Here is the two files and an example!

/*
    Copyright 2010 Daniel Hilst Selli    
    
    This file is part of gkos Linked List API.

    gkos Linked List API is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    gkos Linked List API is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser Public License for more details.

    You should have received a copy of the GNU Lesser Public License
    along with gkos Linked List API.  If not, see <http://www.gnu.org/licenses/>.

    Daniel Hilst aka gkos <danielhilst@gmail.com>    
*/

/****************** 
 *    llapi.h     *
 ******************/
#ifndef LLAPI_H
#define LLAPI_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define KEY_SIZ 8
#define EMPTY 0
#define HAS_ONE 1
#define HAS_MORE_THAN_ONE 2
#define ERROR -1
#define BADCALL (ERROR -1)
#define KEY_FOUND_AT_FIRST (struct search_result) {l->first, NULL} 
#define KEY_FOUND            (struct search_result) {np, prior} 
#define KEY_NOT_FOUND            (struct search_result) {NULL, NULL} 

/* data */
typedef struct node {
    struct node *next; 
    char key[KEY_SIZ + 1]; /* +1 to the nil terminator char */
    char *data[BUFSIZ];
} node;

typedef struct llist {
    node *first; /* first item in list */
    node *last;  /* last item in list */
} llist;

struct search_result {
    node *n;
    node *prior;
};


/* prototypes */
void                     add_node     (llist *, node *);
int                     del_node     (llist *, node *, node *);
node                     *init_node     (char *k, char *);
void                     init_llist     (llist *);
struct search_result     search_node    (llist *, char *);

#endif // LLAPI_H



/*
    Copyright 2010 Daniel Hilst Selli    
    
    This file is part of gkos Linked List API.

    gkos Linked List API is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    gkos Linked List API is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser Public License for more details.

    You should have received a copy of the GNU Lesser Public License
    along with gkos Linked List API.  If not, see <http://www.gnu.org/licenses/>.

    Daniel Hilst aka gkos <danielhilst@gmail.com>    
*/
/********************** 
 *     libllapi.c     * 
 **********************/
#include "llapi.h"
#define PRIVATE static

/* internal prototypes */
PRIVATE node *alloc_node (void);
PRIVATE int isempty (llist *);


/* interface */

void
add_node (llist *l, node *n)
{
    int rval = isempty (l);
    if (rval == EMPTY) {
        l->first = l->last = n;
    } else if (rval == HAS_ONE) {
        l->first->next = n;
        l->last = n;    
    } else if (rval == HAS_MORE_THAN_ONE) {
        l->last->next = n;
        l->last = n;
    } else {
        perror ("isempty");
        exit (EXIT_FAILURE);
    }
    n = NULL; /* so peopple can't touch list directly */
}

int
del_node (llist *l, node *n, node *prior)
{
    int rval = isempty (l);
    if (rval == HAS_ONE) {
        init_llist (l); /* set list as empty again */
        free (n);
    } else if (rval == HAS_MORE_THAN_ONE) {
        if (n == l->first) {
            l->first = l->first->next;
            free (n); /* or free (l->first) */        
        } else if (n == l->last) {
            l->last = prior;
            l->last->next = NULL;
            free (n); /* or free the ex last */
        } else {
            prior->next = prior->next->next; /* link over n */
            free (n);
        }
    } else if (rval == EMPTY) { /* the list is empty */ 
        return BADCALL;
    } else {
        return ERROR;
    }
    return 0;
}

void
init_llist (llist *l)
{
    l->first = l->last = NULL;    
}

node * 
init_node (char *k, char *data)
{
    /* alloc new node */
    node *new = alloc_node ();
    /* set next */
    new->next = NULL;
    /* set key */
    strncpy (new->key, k, KEY_SIZ); 
    new->key[KEY_SIZ] = '\0';
    /* set data */
    memcpy (new->data, data, BUFSIZ);
    /* return the new initalized node */
    return new;
}


struct search_result
search_node (llist *l, char *k)
{
    struct node *np, *prior;
    if (strlen (k) > KEY_SIZ) {
        k[KEY_SIZ] = '\0';
    }
    if (strcmp (l->first->key, k) == 0) {
        return (struct search_result) KEY_FOUND_AT_FIRST; /* (struct search_result) {l->first, NULL} */
    } else {
        for (np = l->first->next, prior = l->first; np != NULL; np = np->next) {
            if (strcmp (np->key, k) == 0) {
                return KEY_FOUND; /* (struct search_result) {np, prior} */ 
            }
            prior = prior->next;
        }
        return KEY_NOT_FOUND; /* (struct search_result) {NULL, NULL} */
    }
    
}


/* internals */ 

PRIVATE int 
isempty (llist *l)
{
    if (l->first == NULL && l->last == NULL)
        return EMPTY;
    else if (l->first == l->last)
        return HAS_ONE;
    else if (l->first->next != NULL)
        return HAS_MORE_THAN_ONE; 
    else 
        return ERROR;
}

PRIVATE node *
alloc_node (void)
{
    node *new = malloc (sizeof (node));
    if (new == NULL) {
        perror ("malloc");
        exit (EXIT_FAILURE);
    }
    return new;
}



#include <stdio.h>
#include "llapi.h"

int
main (void)
{
    int i;
    llist mylist;
    node *bufnode;
    char databuffer[BUFSIZ];
    memcpy (databuffer, "Daniel Hilst", strlen ("Daniel Hilst") + 1);
    struct search_result sr;
    init_llist (&mylist);

    bufnode = init_node ("name", databuffer);    
    add_node (&mylist, bufnode);

    bufnode = init_node ("myname", databuffer);    
    add_node (&mylist, bufnode);

    bufnode = init_node ("thename", databuffer);    
    add_node (&mylist, bufnode);
    
    bufnode = init_node ("onwname", databuffer);    
    add_node (&mylist, bufnode);

    sr = search_node (&mylist, "thename");
    printf ("%s => %s\n", sr.n->key, sr.n->data);
    del_node (&mylist, sr.n, sr.prior);

    sr = search_node (&mylist, "myname");
    printf ("%s => %s\n", sr.n->key, sr.n->data);
    del_node (&mylist, sr.n, sr.prior);

    sr = search_node (&mylist, "onwname");
    printf ("%s => %s\n", sr.n->key, sr.n->data);
    del_node (&mylist, sr.n, sr.prior);

    sr = search_node (&mylist, "name");    
    printf ("%s => %s\n", sr.n->key, sr.n->data);
    del_node (&mylist, sr.n, sr.prior);
    return 0;
}


This would print:
thename => Daniel Hilst
myname => Daniel Hilst
onwname => Daniel Hilst
name => Daniel Hilst



*edit
I create a git repository to this. It's easier to update stuff with git... 
there you'll find an updated README.
http://github.com/gkos/gko-s-Linked-List



cheers! :-)

terça-feira, 12 de outubro de 2010

optimizing example

/*
 * #include <stdio.h>
 * 
 * int
 * main (void)
 * {
 *     int i;    
 *     for (i = 0; i < 10; i++)
 *         printf ("%d ", i);
 *     return 0;
 * }
 */
    .file    "ex.c"
    .section    .rodata
.LC0:
    .string    "%d "
    .text
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $32, %esp
    movl    $0, 28(%esp)
    jmp    .L2
.L3:
    movl    $.LC0, %eax
    movl    28(%esp), %edx
    movl    %edx, 4(%esp)
    movl    %eax, (%esp)
    call    printf
    addl    $1, 28(%esp)
.L2:
    cmpl    $9, 28(%esp)
    jle    .L3
    movl    $0, %eax
    leave
    ret
    .size    main, .-main
    .ident    "GCC: (GNU) 4.5.1"
    .section    .note.GNU-stack,"",@progbits

.file    "ex.c"
    .section    .rodata
.LC0:
    .string    "%d "
    .text
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $32, %esp
    movl    $0, 4(%esp)
    jmp    .L2
.L3:
    movl    $.LC0, %eax
    movl    %eax, (%esp)
    call    printf
    incl    4(%esp)
.L2:
    cmpl    $9, 4(%esp)
    jle    .L3
    movl    $0, %eax
    leave
    ret
    .size    main, .-main
    .ident    "GCC: (GNU) 4.5.1"
    .section    .note.GNU-stack,"",@progbits
The first file has as comment the c program that generates it.
The second one is the same, but with some modifications that I made..
reducing the number of instructions and replacing an add
with an inc intruction. Assembly world is really fun!!

Oh yes.. I extend SH to get a poorly gas syntaxhighlighter (:
I guess this is my first real work with free community!!
here is the post announcement: http://alexgorbatchev.com/forums/viewtopic.php?f=2&t=77 and
here is the project page http://github.com/gkos/gas-brush
I'm felling really happy with this!! Maybe tomorrow I speak about downseq project (:

Cheers!

domingo, 10 de outubro de 2010

another hello world in gas, this time calling puts from libc

# another hello world example
# you can compile this like:
# $ as -o hw.o mainhw.s 
# $ gcc -o hw hw.o -lc
# $ ./hw
#
    .file "mainhw.s"
    .section .rodata 
.Lstr:                       # the address of our string
    .asciz "Hello, World"

    .text
    .type main, @function
    .globl main
main:
    pushl %ebp              # prologue of every function
    movl %esp, %ebp         # still prologue.. 
    pushl $.Lstr            # pass arguments on stack
    call puts               # puts(.Lstr)
    movl $0, %eax           # the 0 of return 0
    leave                   # epilogue of every function
    ret                     # return 
    .size main, . - main    

sábado, 9 de outubro de 2010

gas copy string n ;-)

#
# void
# mycpynstr (char *dst, char *src, int n)
# {
#     while (n--)
#         *dst++ = *src++;
# }
#
    .file    "cpystr.c"
    .text
.globl mycpynstr
    .type    cpynstr, @function
mycpynstr:
    pushl    %ebp
    movl    %esp, %ebp
    jmp    .L2             # goto (.L2)

#   *dst++ = *src++ at line 6
.L3:
    movl    12(%ebp), %eax #     move src to %eax  
    movzbl    (%eax), %edx #     %dl = (char *) %eax # (src) 
    movl    8(%ebp), %eax  #     move dst to %eax
    movb    %dl, (%eax)    #     *dst = *src
    addl    $1, 8(%ebp)    #     src++ 
    addl    $1, 12(%ebp)   #     dst++ 

# while (n--) at line 5
.L2:
    cmpl    $0, 16(%ebp)   #   if (n != 0) 
    setne    %al           #     %al = 1
    subl    $1, 16(%ebp)   #   n--
    testb    %al, %al      #   if (%al)    
    jne    .L3             #     goto (.L3)
    popl    %ebp           #   else
    ret                    #     return

    .size    mycpynstr, .-mycpynstr
    .ident    "GCC: (GNU) 4.5.1"
    .section    .note.GNU-stack,"",@progbits
I made this with `gcc -S cpystr.c' where cpystr.c contains the mycpynfunction
defined as in first eight lines in this file. Then I open the file cpystr.s
created by gcc and add the coments. Nothing more was changed.
The comments tell in C language what is happening. But I not sure if
every comment is exactly right... its just how I understand the code. The
comments start with `#' character and extends to the end of line.
Cheers :-)

sexta-feira, 8 de outubro de 2010

gas hello wolrd

.text
.global _start
_start:
    movl $4, %eax
    movl $1, %ebx
    movl $str, %ecx
    movl $len, %edx
    int  $0x80

    movl $1, %eax
    xor  %ebx, %ebx
    int  $0x80

.data

str:
    .ascii "Hello World" 
    .set len, . - str

quarta-feira, 6 de outubro de 2010

Java looks handy

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.*;
import javax.swing.*;

class GHelloWorld extends JFrame
  implements ActionListener{
 Container cp;
 JLabel lb;
 JButton bt;
 
 public GHelloWorld( ) {
  cp =  this.getContentPane( ); 
  cp.setLayout(new FlowLayout( )); 
  lb = new JLabel("Hello World");
  cp.add(lb);
  bt = new JButton ("Hi, there!");
  bt.addActionListener(this);
  cp.add(bt);
 }
 
 public void actionPerformed(ActionEvent e) {
  System.out.println("Hello World");
  System.exit(0);
 } 

 static public void main (String[ ] args) {
  GHelloWorld cf = new  GHelloWorld( );
  cf.setTitle("Hello World");
  cf.setSize(400,300);
  cf.setVisible(true);
 }
} 

A gui hello world example.. I really like the ideia
of code once and distribute it for every one on
almost all systems. I read
(3 days reading) and like it. I need more time to get used with gui API and
a little bit of pratice. I do not intend to become a java programer, I love C, C is everything!!
But java is really handy, really really handy. (:
I want to translante this to java
Yes I do this in python.. First in shell, than python.. and now I want it in java with gui and
friendly manage.

quinta-feira, 16 de setembro de 2010

Selection Sort in PASCAL

PROGRAM Selection_Sort;

CONST len = 12;

TYPE intarray = ARRAY[1..len] OF INTEGER;
 
FUNCTION ssort (A: intarray): intarray;
VAR
 at, i, j, smaller, tmp: integer;
 newarray: intarray;
BEGIN
  { copy array }
  FOR i:=1 TO len DO
   newarray[i] := A[i];

  { sort }
  FOR i:=1 TO len-1 DO
  BEGIN
   smaller := newarray[i];
   at   := i;
   FOR j:=i+1 TO len DO
   BEGIN
    IF newarray[j] < smaller THEN
    BEGIN
     smaller := newarray[j];
     at  := j;
    END
   END; { FOR j:=i+1 }

   IF newarray[i] > smaller THEN
   BEGIN { swap } 
    tmp := newarray[i];
    newarray[i] := smaller;
    newarray[at] := tmp;
   END
  END; { FOR i:= 0 }
  ssort := newarray;
END;

{ MAIN }
VAR
 a1, a2: intarray;
 buf, i: integer;

BEGIN
 { read array }
 FOR i:=1 TO len DO
 BEGIN
  writeln ('Enter a number');
  readln (buf);
  a1[i] := buf; 
 END;

 { print a1 }
 FOR i:=1 TO len DO
 BEGIN
  write(a1[i], ' ');
 END;
 writeln;

 { sort }
 a2 := ssort (a1);

 { print sorted a2}
 FOR i:=1 TO len DO
 BEGIN
  write(a2[i], ' ');
 END;
 writeln;
END.

segunda-feira, 30 de agosto de 2010

compiling the kernel

#!/bin/bash

# This script will download, check, compile and install modules of a chosen kernel
# at a setted directory. You must suply your password for root needed
# actions
 
# set variables
VERSION='2.6.35.4' # what is the kernel version
UNPACKDIR=/usr/src/ # where to unpack
EXTENSION=tar.bz2 # the kernel extension
RC=1 # this will be incremented at every compile
TARGET=/home/geckos/projects/goot # where to copy kernel
T_ROOT=${TARGET}/root # where to install modules
# stop here

SRC=linux-${VERSION}
SRCDIR=${UNPACKDIR}${SRC}
SRCFILE="${SRC}.${EXTENSION}"
CHECKSUM="${SRCFILE}.sign"
LINUX_URL="ftp://ftp.kernel.org/pub/linux/kernel/v2.6"
MAKEOPTION="menuconfig"

for ARG in $@; do
 case $ARG in
 makeopt=*) 
  MAKEOPTION=`echo $ARG | cut -f2 -d=`
 ;;
 unpack)
  sudo rm ${SRCDIR} -r
 ;;
 download)
  rm ${SRCFILE} ${CHECKSUM}
 ;;
 esac
done
  
# check source
chk_src () {
 echo "Checking source ..."
 if [ ! -d "${SRCDIR}" ]; then
  if [ ! -r "${SRCFILE}" ]; then
   wget -c "${LINUX_URL}/${SRCFILE}" || return 1
  fi
  if [ ! -r "${CHECKSUM}" ]; then
   wget -c "${LINUX_URL}/${CHECKSUM}" || return 1

  fi
  gpg2 --keyserver wwwkeys.pgp.net --recv-keys 0x517D0F0E 
  gpg2 --verify ${CHECKSUM} ${SRCFILE} || return 1 
  sudo tar vxf ${SRCFILE} -C ${UNPACKDIR} && return 0 || return 1
 fi
 echo "DONE"
 return 0
}

# build kernel
build () {
 echo "Starting build ..."
 # to install modules at target
 export INSTALL_MOD_PATH=${T_ROOT}
 { sudo make -C ${SRCDIR} mrproper ; } &&
 { sudo make -C ${SRCDIR} ${MAKEOPTION}; } &&
 { sudo make -C ${SRCDIR}; } &&
 { sudo make -C ${SRCDIR} modules_install; } || return 1;
 echo "DONE"
}

# copy files
cpy_files () {
 echo "Copying files..."
 cp ${SRCDIR}/arch/x86/boot/bzImage ${TARGET}vmlinuz-${VERSION} -v;
 cp ${SRCDIR}/.config ${TARGET}config-${VERSION} -v;
 echo "DONE"
}

# increment the RC of this file at every execution 
inc_rc () {
 N=`sed -n 's|^RC=\([0-9]\{1,2\}\)$|\1|p' $0`
 let N++
 sed -e "s|^RC=.*$|RC=$N|" -i $0
}

# main
echo "Start.."
{
 chk_src &&
 build &&
 cpy_files &&
 inc_rc
} &&
echo "Finish" || echo "Fails"

quinta-feira, 26 de agosto de 2010

I like pencil

I bought a new pencil today. Lost the last one so
I have no choise. Also I install slackware 13
(long time ago) at a flash drive and yesterday I
build a boot cd for it based on slackware 13 disk 1
cd. I mix the initrd of flash drive installation
with the slack cd, keeping only the kernels and
isolinux directories on new cd. The final iso gets
only 16mb and with root=/dev/disk parameters can boot a
lot stuff. :-)

terça-feira, 17 de agosto de 2010

I want the POSIX guide book :-P

I want this

Linked list API

Well, working on a general linked list API.
... note: I guess this will be never released, because I'm so lazzyyy! :-(

sexta-feira, 13 de agosto de 2010

segunda-feira, 19 de julho de 2010

The university is pissing me off!

I need a job.. All I can find is web developer.. PHP, SQL, Oracle etc..
I want a cool job...
I want to understand firmware, assembly, kernel, microcontrolers...
I don't want to create a new facebook/twitter/orkut... (angry)

terça-feira, 6 de abril de 2010

hash implementation

some hash

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HSH_EMPTY "__EMPTY__"
#define HSH_MAX_SIZE 3 
#define HSH_FOUND 0
#define HSH_FOUND_FIRST 1
#define HSH_NOT_FOUND -1
#define HSH_NOT_INIT -2

typedef struct hash_node {
 struct hash_node *n;
 char *k;
 char *v;
} hash_type;

extern void     hash_delete  (hash_type **, char *); 
extern char    *hash_get   (hash_type **, char *);
extern void     hash_pairs     (hash_type **, void (*func)(hash_type *));
extern void     hash_set   (hash_type **, char *, char *);
















void
print_pair (hash_type *p)
{
 printf ("%s -> %s\n", p->k, p->v);
}

hash_type *me[HSH_MAX_SIZE];

int
main (void)
{ 
 hash_set (me, "nome", "Daniel");
 hash_set (me, "sobrenome", "Hilst");
 hash_delete (me, "nome");
 printf ("%s %s\n", hash_get (me, "nome"), hash_get (me, "sobrenome"));
 return 0;
}


















struct hash_found {
 signed int s;
 hash_type *p;
};

static hash_type   *hash_alloc  (void);
static unsigned    hash_index  (char *);
static struct hash_found  hash_lookup (hash_type **, char *, unsigned); 

void
hash_delete (hash_type *h[], char *k)
{ 
 unsigned i = hash_index (k);
 struct hash_found f = hash_lookup (h, k, i);
 hash_type *p, *prev;
 if (f.s == HSH_FOUND) {
  prev = f.p;
  p = f.p->n;
  prev->n = prev->n->n;
  free (p->k);
  free (p->v);
  free (p);
 }
 else if (f.s == HSH_FOUND_FIRST) {
   p = h[i];
  h[i] = h[i]->n;
  free (p->k);
  free (p->v);
  free (p);
 }  
}

char *
hash_get (hash_type *h[], char *k)
{ 
 unsigned i = hash_index (k);
 struct hash_found f = hash_lookup (h, k, i);
 if (f.s == HSH_FOUND) {
  return f.p->n->v;
 }
 else if (f.s == HSH_FOUND_FIRST) { 
  return f.p->v;
 }
 return HSH_EMPTY;
}

void
hash_pairs (hash_type *h[], void (*func)(hash_type *))
{ 
 unsigned i = 0;
 hash_type *p = h[i];
 for (; i < HSH_MAX_SIZE;) {
  for(; p != NULL; p = p->n)
   func (p);
  p = h[++i];
 }
}

void
hash_set (hash_type *h[], char *k, char *v)
{ 
 unsigned i = hash_index (k);
 struct hash_found f = hash_lookup (h, k, i);
 hash_type *p, *prev;
 
 if (f.s == HSH_FOUND) {
  p = f.p->n;
  free (p->v);
  p->v = strdup (v); 
 }
 else if (f.s == HSH_FOUND_FIRST) {
  p = f.p;
  free (p->v);
  p->v = strdup (v);
 }
 else if (f.s == HSH_NOT_INIT) {
  p = h[ i ] = hash_alloc ();
  p->k = strdup (k);
  p->v = strdup (v);
  p->n = NULL;
 }
 else { // if (f.s == HSH_NOT_FOUND) {
  prev = f.p;
  p = prev->n = hash_alloc ();
  p->k = strdup (k);
  p->v = strdup (v); 
 }
}









static hash_type *
hash_alloc (void)
{
 hash_type *new = (hash_type *) malloc (sizeof (hash_type));
 if (new == NULL) {
  fprintf (stderr, "malloc error\n");
  exit (EXIT_FAILURE);
 }
 return new;
}

static unsigned
hash_index (char *k)
{ 
 unsigned i;
 for (i = 0; *k != '\0'; k++)
  i += *k;  
 return i % HSH_MAX_SIZE;
}

static struct hash_found 
hash_lookup (hash_type **h, char *k, unsigned i) /* hash, key, index */ 
{ 
 hash_type *p, *prev;
 p = h[ i ];
 if (p == NULL) 
  return (struct hash_found) {HSH_NOT_INIT, NULL};
 else if (strcmp (p->k, k) == 0)
  return (struct hash_found) {HSH_FOUND_FIRST, p};

 prev = p;
 p = p->n;
 for (; p != NULL; p = p->n) {
  if (strcmp (p->k, k) == 0)
   return (struct hash_found) {HSH_FOUND, prev};
  prev = p;
 } 
 return (struct hash_found) {HSH_NOT_FOUND, prev};
}

use:
hash_type *MONHASH[HSH_MAX_SIZE]; // the HSH_MAX_SIZE is mandatory here, if this ins't global
you need to initializate every element of it to NULL;

hash_set (MONHASH, "KEY", "VALUE"); // install a key or change it
hash_get (MONHASH, "KEY"); // returns "VALUE" or "__EMPTY__" if doesn't found it
hash_delete (MONHASH, "KEY"); // delete the pair "KEY" "VALUE" and free its memory
hash_pairs (MONHASH, FUNC); for each pair in hash execute the function FUNC passing the pair to it via MONHASH, entry; (e.g) void f (hash_type *h) { puts (h->k) };. Then hash_pairs (MONHASH, f);



What else... math makes me fell sad..

domingo, 21 de março de 2010

terça-feira, 2 de março de 2010

Finances control n00b program

I have nothing to do.. so I make a program to take note of my money
It's poor... but fun...
sample output:

~:$./gkmoney 
no arguments
Current balance: 216
dep 17000  sell a hello world for 17k
wit 1500 purchase a old beatle
wit 3 beatle crash .. I went back by bus
end

Tue Mar  2 21:53:18 2010    +     17000 -> 17216 sell a hello world for 17k
Tue Mar  2 21:53:34 2010    -      1500 -> 15716 purchase a old beatle 
Tue Mar  2 21:53:55 2010    -         3 -> 15713 beatle crash .. I went back by bus
Current Balance: 15713


source code

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

int
main (int argc, char ** argv)
{
  FILE * bf;
  FILE * lf;
  int balance, val, indx, n;
  char buf[BUFSIZ];
  char command[5], * time_str, comment[255];
  time_t time_now;

  if (argc < 2) {
    printf ("no arguments\n");
    bf = fopen ("/home/geckos/.bl.txt", "r+");
    lf = fopen ("/home/geckos/.ml.txt", "a+");
  }
  else {
    bf = fopen (argv[1], "r+");
    lf = fopen (argv[2], "a+");
  }

  if (bf == NULL
      || lf == NULL) {
    perror ("fopen");
    exit (1);
  }
  
  if (fscanf (bf, "%d\n", &balance) == EOF) {
    perror ("fscanf");
    exit (1);
  }
  printf ("Current balance: %d\n", balance);
  
  while (1) {
    for (indx = 0; indx < BUFSIZ; indx++) {
      char ch;
      n = read (0, &ch, 1);
      if (n == -1) {
        perror ("read");
        exit (1);
      }
      if (ch == '\n')
        break;
      buf[indx] = ch;
    }
    buf[indx] = '\0';
    /* %[^-] = %s + white spaces */
    n = sscanf (buf, "%s %d %[^-]", command, &val, comment); 
    time_now = time (NULL);
    time_str = ctime (&time_now);
    time_str[strlen (time_str) - 1] = '\0'; /* chop LF */
    if (n == 2)
      memcpy (comment, "...", 4);
    
    if (strcmp (command, "dep") == 0) {
      balance += val;
      fprintf (lf, "%s\t+%10d -> %10d\t%s\n", time_str, val, balance, comment);
    }
    else if (strcmp (command, "wit") == 0) {
      balance -= val;
      fprintf (lf, "%s\t-%10d -> %10d\t%s\n", time_str, val, balance, comment);
    }
    else if (strcmp (command, "end") == 0)
      break;
  }    
  fseek (bf, 0, SEEK_SET);
  fprintf (bf, "%d", balance);
  fclose (bf);
  fseek (lf, 0, SEEK_SET);
  while (fgets (buf, BUFSIZ, lf))
    printf ("%s", buf);
  fclose (lf);
  printf ("Current Balance: %d\n", balance);
  return 0;
}

segunda-feira, 1 de fevereiro de 2010

Fake kernel ..

This is the implementations of this and I know,
it's realy bad coded ..

files:
common.c -> common functions
scheduler.c -> scheduler functions
process.c -> process functions
filequeue.c -> queue functions
fakek.h -> where all stuff is declared
main.c -> the main program
Makefile -> the make file :P

/*
 * file: common.c
 */
#include <dirent.h>
#include <stdlib.h>
#include <string.h>

void *
xmalloc (size_t size)
{
  void * pool = malloc (size);
  if (pool == NULL)
 err (1, "xmalloc");
  return pool;
}

DIR *
xopendir (const char * dirname)
{
  DIR * dp = opendir (dirname);
  if (dp == NULL)
 err (1, "xopendir");
  return dp;
}

int 
xopen (const char * filename, int state, mode_t mode)
{
  int fd = open (filename, state, mode);
  if (fd == -1)
 err (1, "xopen\n");
  return fd;
}

char * 
create_filepath (const char * dir, const char * file)
{
  char * path = (char *) xmalloc ((size_t) strlen (dir) + strlen (file) +1);
  memset (path, 0, strlen (dir) + strlen (file) +1);
  strncpy (path, dir, strlen (dir));
  strncat (path, file, strlen (file));
  return path;
}

void xrename (const char * old, const char * new)
{
  int rval = rename (old, new);
  if (rval == -1)
 err (1, "xrename");
}


/*
 * file scheduler.c
 */
#include "fakek.h"


queue_type QBuffer;
const char * userdir = "./fstack/User/";
const char * sysdir = "./fstack/System/";
const char * rdir = "./fstack/Running/";  

/* Save function to queue process */
void 
Sched_writebuf (unsigned int pid, unsigned int state, unsigned int fork,
    unsigned int stopline, unsigned int spendtime,
    unsigned int priority, char * filename)
{
  /* Write here */
  QBuffer.proc.pid = pid;
  QBuffer.proc.state = state;
  QBuffer.proc.fork = fork;
  QBuffer.proc.stopline = stopline;
  QBuffer.proc.spendtime = spendtime;
  QBuffer.proc.priority = priority;
  //  QBuffer.proc.filename = (char *) xmalloc (strlen (filename) + 1);
  /* This will be freed with q_read() */
  strncpy (QBuffer.proc.filename, filename, strlen (filename));
  QBuffer.proc.filename [strlen (filename)] = '\0';
  /* Send to Queue, the q_write increments QSize */
  q_write (& QBuffer);
}
  

/* 
 * return a regular file entry 
 * consecutive calls return consecutive file entries 
 * it uses Scheddir poiter, that must be a non-NULL pointer
 * otherwise the behavior is undefined 
 */
struct dirent *
Sched_getrfile (DIR * dirp)
{
  struct dirent * entry_ptr;
  while (entry_ptr = readdir (dirp))
 if (entry_ptr->d_type & DT_REG)
   return entry_ptr;
  /* There is no regular files in this diretory */ 
  return NULL;
}


/* This is the scheduler itself */ 
void *
Scheduler_thread (void * unused)
{
  struct timespec time = { 0, 1000 };
  struct dirent * entry_ptr;
  int sys_switch;
  char * snew, * sold;
  DIR * tmpdir_ptr;
  /* While forever */
  while (1) {
 /* Search first for System process after User process */ 
 sys_switch = 0;
 while (1) {
   pthread_mutex_lock (&mutex);
   printf ("SCHEDULER LOOP START\n");
   /* open system dir */
   tmpdir_ptr = xopendir (sysdir);
   entry_ptr = Sched_getrfile (tmpdir_ptr);
   closedir (tmpdir_ptr);
   if (entry_ptr != NULL) {
  /* We got one system process */
  sys_switch++;
  pthread_mutex_unlock (&mutex);
  break;
   }
   /* open user dir */
   tmpdir_ptr = xopendir (userdir);
   entry_ptr = Sched_getrfile (tmpdir_ptr);
   closedir (tmpdir_ptr);
   if (entry_ptr != NULL) {
  /* We got one user process */
  pthread_mutex_unlock (&mutex);
  break;
   }
   /* There is no more process */
   sleep (1);
   printf ("SCHEDULER LOOP /* NO NEW PROCESS */\n");
   pthread_mutex_unlock (&mutex);
   /* Wait 1000 nanoseconds to search again */
   nanosleep (&time, NULL);
 } 
 pthread_mutex_lock (&mutex);
 sleep (1);
 printf ("\E[31mNew process arise: %s\n\E[0m", entry_ptr->d_name);
 sleep (1);
 if (sys_switch) {
   sold = create_filepath (sysdir, entry_ptr->d_name);
   snew = create_filepath (rdir, entry_ptr->d_name);
   printf ("\E[31mmoving %s -> %s\n\E[0m", sold, snew);
   sleep (1);
   rename (sold, snew);
   free (sold);
   free (snew);
   printf ("\E[31mScheduling system proc Pid:%d\n\E[0m", 10 + PidCounter);
   sleep (1);
   /* pid, state, fork, stopline, spendtime, priority, filename */
   Sched_writebuf (10 + PidCounter, 0, 0, 1, 0, 4, entry_ptr->d_name);
   PidCounter++;
   printf ("\E[31mQueueSize = %d\n\E[0m", QSize);
   sleep (1);
 }
 else {
   sold = create_filepath (userdir, entry_ptr->d_name);
   snew = create_filepath (rdir, entry_ptr->d_name);
   sleep (1);
   printf ("\E[31mmoving %s -> %s\n\E[0m", sold, snew);
   rename (sold, snew);
   free (sold);
   free (snew);
   sleep (1);
   printf ("\E[32mScheduling it Pid:%d\n\E[0m", 10 + PidCounter);
   /* pid, state, fork, stopline, spendtime, priority, filename */
   Sched_writebuf (10 + PidCounter, 0, 0, 1, 0, 1, entry_ptr->d_name);
   PidCounter++;
   sleep (1);
   printf ("\E[32mQueueSize = %d\n\E[0m", QSize);
 }
 sleep (1);
 printf ("SCHEDULER LOOP FINISH\n");
 pthread_mutex_unlock (&mutex);         
 nanosleep (&time, NULL);
  }
}

/*
 * file: process.c
 */
#define MAXPIDNUM 99
#define THREADMAXNANOTIME 1000
#include "fakek.h"

queue_type PBuffer;
pthread_mutex_t Proc_readbuf_mutex = PTHREAD_MUTEX_INITIALIZER;
unsigned int MaxTime;
unsigned int Elapsed = 0;
static char pid_array[MAXPIDNUM + 1];
const char * fdir = "./fstack/Finished/";


void * 
Timer_thread (void * unused)
{ 
  struct timespec ttime = {
 0, THREADMAXNANOTIME
  };
  int oldcancelstate;
  while (Elapsed < MaxTime) {
 nanosleep (&ttime, NULL);
 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldcancelstate);
 Elapsed++;
 pthread_setcancelstate (oldcancelstate, NULL);
  }
}

char
Proc_setline (int fd, unsigned int stopline)
{
  char ch = 0;
  signed int nbytes;
  unsigned int currentline = 1;
  while (currentline != stopline) {
 nbytes = read (fd, &ch, 1);
 if (nbytes == 0)
   return EOF;
 else if (nbytes == -1)
   err (1, "Proc_setline");
  
 if (ch == '\n')
   currentline++;
  }
}

char
Proc_readline (int fd)
{
  int rval;
  char line[7];
  if (PBuffer.proc.state != 0) 
 /* The process is waiting for other process */
 if (pid_array[PBuffer.proc.state] != 0) 
   /* that not occored yet */
   return 1;
  lseek (fd, 0, SEEK_SET);
  rval = Proc_setline (fd, PBuffer.proc.stopline);
  if (rval == EOF)
 return EOF;
  read (fd, line, 7);
  line[7] = '\0';
  printf ("\E[33m\tExecuting line %d (%s) from file %s\n\E[0m", 
    PBuffer.proc.stopline, line, PBuffer.proc.filename);
  if (strcmp (line, "wait") > 0) {
 /* wait found */
 int pid_to_wait;
 sscanf (line, "wait %d", &pid_to_wait);
 PBuffer.proc.state = pid_to_wait;
 /* This will be 0 again when the process
    `pid_to_wait' ends */
 pid_array[pid_to_wait] = PBuffer.proc.pid;
 PBuffer.proc.stopline++;
 return 1;
  } 
  else if (strcmp (line, "fork 00") == 0) {
 /* fork found */
 PBuffer.proc.stopline++;
 return 2;
  }
 PBuffer.proc.stopline++;
  return 0;
}
 
  
void *
Process_thread (void * unused)
{
  struct timespec process_time = { 0, 1000 };
  pthread_t timer_thread_id;
  int fd; 
  char rval, * old, * new;

 START_PROCESS: while (1) { 

 /* While Queue is empty, Wait */

 while (QSize == 0) 
   nanosleep (&process_time, NULL);

 pthread_mutex_lock (&mutex); 
 printf ("\tPROCESS LOOP START\n");
 sleep (1);
 /* Read a process from queue */
 q_read (&PBuffer);
 printf ("\E[35m\tTaked a process from queue pid:%d | filename %s\n\E[0m", 
   PBuffer.proc.pid, PBuffer.proc.filename);
 printf ("\E[34m\t QueueSize = %d\n", QSize);
 sleep (1);
 /* Start Timer according wiht priority */
 MaxTime = PBuffer.proc.priority;
 char * filename = create_filepath (rdir, PBuffer.proc.filename);
 printf ("\E[33m\topening file %s\n\E[0m", filename);
 fd = xopen (filename, O_RDONLY, 0);
 free (filename); 
 printf ("\E[35m\tStarting timer\n\E[0m");
 pthread_create (&timer_thread_id, NULL, &Timer_thread, NULL);
 /* Until EOF */
 while ((rval = Proc_readline(fd)) != EOF) {
   if (rval == 1) {
  /*
   * This process was set to wait for other process 
   * reshedule it util the wait process ends
   */
  pthread_cancel (timer_thread_id);
  pthread_join (timer_thread_id, NULL);
  close (fd);
  Elapsed = 0;
  printf ("\E[32m\tWaiting for pid:%d\n\E[0m", PBuffer.proc.state);
  Sched_writebuf (PBuffer.proc.pid, PBuffer.proc.state, PBuffer.proc.fork,
      PBuffer.proc.stopline, Elapsed * 1000, PBuffer.proc.priority, 
      PBuffer.proc.filename);
  printf ("\tPROCESS FINISH\n");
  sleep (1);
  pthread_mutex_unlock (&mutex);
  nanosleep (&process_time, NULL);
  goto START_PROCESS;
   }
   else if (rval == 2) {
  /* fork found */
  char * wholefname, * fname, pidchar[2], buf[100];
  int newfiled, nbytes;
  fname = create_filepath ("F", (PBuffer.proc.filename+1));
  wholefname = create_filepath (rdir, fname);
  /* Copy the file */
  printf ("\E[32m\tCopying file %s%s -> %s\n\E[0m", 
    rdir, PBuffer.proc.filename, wholefname);
  newfiled = xopen (wholefname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  lseek (fd, 1, SEEK_CUR);
  while ((nbytes = read (fd, buf, 100)) > 0)
   write (newfiled, buf, nbytes);
  if (nbytes == -1)
    errx (1, "read error");
  /* End of copy file */
  printf ("\E[32m\tFork found making a copy of process. Pid: %d\n\E[0m",
    PidCounter + 10);
  Sched_writebuf (PidCounter + 10, PBuffer.proc.state, 2, 1, 
      0, PBuffer.proc.priority, fname);
  free (fname);
  free (wholefname);
  PidCounter++;
  PBuffer.proc.fork = 1; /* this is the original one */
   }
   /* if Time Out, reschedule */
   else if (Elapsed == MaxTime) {
  pthread_join (timer_thread_id, NULL);
  printf ("\E[31m\tTime exceded at priority %d, rescheduling pid:%d %s\n\E[0m", 
    PBuffer.proc.priority, PBuffer.proc.pid, PBuffer.proc.filename);
  Sched_writebuf (PBuffer.proc.pid, PBuffer.proc.state, PBuffer.proc.fork,
      PBuffer.proc.stopline, Elapsed * 1000 + PBuffer.proc.spendtime
      , PBuffer.proc.priority, PBuffer.proc.filename);
  close (fd);
  Elapsed = 0;
  printf ("\tPROCESS FINISH\n");
  sleep (1);
  pthread_mutex_unlock (&mutex);
  nanosleep (&process_time, NULL);
  goto START_PROCESS;
   }
 }
 /* The curret process ends */
 close (fd);
 printf ("\E[31m\tEOF %s\n\E[0m", PBuffer.proc.filename);
 /* if was some other waiting for it .. release */
 if (pid_array[PBuffer.proc.pid] != 0) {
   printf ("\E[32m\tReleazing process pid:%d\n\E[0m", pid_array[PBuffer.proc.pid]);
   pid_array[PBuffer.proc.pid] = 0;
 }
 printf ("\E[31m\tTime expense %d nanoseconds at prioriry %d\n", 
   PBuffer.proc.spendtime + (1000 * Elapsed), PBuffer.proc.priority);
 pthread_cancel (timer_thread_id);
 pthread_join (timer_thread_id, NULL);
 Elapsed = 0;
 new = create_filepath (fdir, PBuffer.proc.filename);
 old = create_filepath (rdir, PBuffer.proc.filename);
 sleep (1);
 printf ("\E[32m\tmoving %s -> %s\n\E[0m", old, new);
 xrename (old, new);
 free (old);
 free (new);
 sleep (1);
 printf ("\tPROCESS LOOP FINISH\n");
 pthread_mutex_unlock (&mutex);
 nanosleep (&process_time, NULL);
  } 
}

/*
 * file: filequeue.c
 */
#include <err.h>
#include <stdlib.h>
#include <string.h>

#include "fakek.h"

/* Init Global variables */
queue_type * GFirst = NULL;
queue_type * GLast = NULL;
unsigned int QSize = 0;
unsigned int PidCounter = 0;

void *
q_write (queue_type * buf)
{
  queue_type * new = (queue_type *) malloc (sizeof (queue_type));
  if (new == NULL)
 errx (2, "q_write (malloc fail)");
  /* Set data */
  memcpy (new, buf, sizeof (queue_type));
  new->next = NULL;
  /* Set Globals */
  if (QSize == 0)
 GFirst = GLast = new;
  else {
 GLast->next = new;
 GLast = new;
  }
  QSize++;
}

void *
q_read (queue_type * buf)
{
  if (QSize < 1)
 errx (1, "Queue is empty, wrong q_read call");
  /* Save data */
  memcpy (buf, GFirst, sizeof (queue_type));
  /* Set Globals */
  queue_type * tmp = GFirst;
  GFirst = GFirst->next;
  /* Free the read data */
  free (tmp);
  /* Set the queue size need be last thing to do
  to avoid race conditions */
  QSize--;
}

void *
q_destroy (void)
{
  unsigned int released_items = 0;
  queue_type * tmp;
  while ((tmp = GFirst) != NULL) {
 GFirst = GFirst->next;
 free (tmp);
 released_items++;
  }
  GLast = NULL;
  QSize = 0;
  return (void *) released_items;
}

/*
 * file: fakek.h
 */
#ifndef FAKEK_H
#define FAKEK_H

#include <dirent.h>
#include <err.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>


/*
 * Defined in filequeue.c
 */
typedef struct proc_strc {
  unsigned int pid;
  unsigned int state;
  unsigned int fork;
  unsigned int stopline;
  unsigned int spendtime;
  unsigned int priority;
  char filename[5];
} proc_type;

typedef struct queue_strc {
  proc_type proc;
  struct queue_strc * next;
} queue_type;

/* Global First and Last processs in Queue */
extern queue_type * GFirst;
extern queue_type * GLast;
/* Queue Size */
extern unsigned int QSize;

/* pid counter */
extern unsigned int PidCounter;

/* Fifo like functions */
extern void * q_write (queue_type *);
extern void * q_read (queue_type *);
extern void * q_destroy (void);


/*
 * Defined in common.c
 */
extern DIR * xopendir (const char *);
extern void * xmalloc (size_t);
extern int xopen (const char *, int, mode_t);
extern char * create_filepath (const char *, const char *);

/* 
 * Defined in scheduler.c
 */
extern const char * userdir;
extern const char * sysdir;
extern const char * rdir;
extern queue_type QBuffer;
extern void Sched_writebuf (unsigned int, unsigned int, unsigned int,
       unsigned int, unsigned int, unsigned int, char *);
extern struct dirent * Sched_getrfile (DIR *);
extern void * Scheduler_thread (void *);

/*
 * Defined int process.c 
 */
extern const char * fdir;
extern queue_type PBuffer;
extern unsigned int MaxTime;
extern unsigned int Elapsed;
extern void * Timer_thread (void *);
extern char Proc_setline (int, unsigned int);
extern char Proc_readline (int fd);
extern void * Process_thread (void *);
#endif 

/*
 * Defined in main 
 */
extern pthread_mutex_t mutex;


/*
 * file: main.c
 */
#include "fakek.h"
#include <pthread.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int
main (void)
{
  pthread_t Scheduler_id, Process_id;
  pthread_create (&Process_id, NULL, &Process_thread, NULL);  
  pthread_create (&Scheduler_id, NULL, &Scheduler_thread, NULL);
  pthread_join (Scheduler_id, NULL);
  pthread_join (Process_id, NULL);
  
  return 0;
}

fakek: main.c common.o filequeue.o process.o scheduler.o fakek.h
 gcc $(CFLAGS) -o fakek main.c common.o filequeue.o process.o scheduler.o fakek.h -lpthread
 mkdir -p ./fstack/System ./fstack/User ./fstack/Running ./fstack/Finished

common.o: common.c fakek.h
 gcc $(CFLAGS) -c common.c

filequeue.o: filequeue.c fakek.h
 gcc $(CFLAGS) -c filequeue.c

process.o: process.c fakek.h
 gcc $(CFLAGS) -c process.c

scheduler.o: scheduler.c fakek.h
 gcc $(CFLAGS) -c scheduler.c

clean:
 rm -vf common.o fakek filequeue.o process.o scheduler.o 
thats it

stack implementation - Hello World

This is not the right way to do the things..
But.. it works.. doesn't?

first a header/source file

/* 
 * file: table.h
 */
#ifndef TABLE_H
#define TABLE_H

#ifdef DATATYPE
#ifdef BTMAXSIZE

#include <stdlib.h>
#include <err.h>

struct book_strc {
  DATATYPE data;
  struct book_strc * prev;
} book_stack;


/* Book table */
static struct book_strc * book_table[BTMAXSIZE];
/* Number of stacks in table */
static unsigned int tablen = 0;


void *
xmalloc (size_t siz)
{
  register void * pool = malloc (siz);
  if (!pool)
 err (1, "xmalloc");
  return pool;
}


void
bspush (unsigned int tentry, DATATYPE val)
{
  struct book_strc * new = (struct book_strc *) xmalloc (sizeof (struct book_strc));
  new->data = val;
  new->prev = book_table[tentry];  
  tablen++;
  book_table[tentry] = new;
}

void
bspop (unsigned int tentry, DATATYPE * val)
{
  * val = book_table[tentry]->data;
  struct book_strc * tmp = book_table[tentry];
  book_table[tentry] = book_table[tentry]->prev;
  free (tmp);
  tablen--;
}

#endif
#endif
#endif

and a main program using it ..
#include <stdio.h>
#include <stdlib.h>

#define BTMAXSIZE 100
#define DATATYPE char*
#include "table.h"

int
main (void)
{
  char str1[] = "Hello";
  char str2[] = "World";
  char * str3, * str4;

  bspush (0, str1); 
  bspush (1, str2);
  bspop (1, &str4);
  bspop (0, &str3);
  printf ("%s %s\n", str3, str4);
  return 0;
}
output:
Hello World

Usage:
You declare 2 macros
BTMAXSIZE -> this is the max size of the array of stacks
DATATYPE -> this is the data type of stack objects
then you include the file table.h
this file implement a array of stacks that hold objects of same data type
The design idea is a book table where the stacks are
you can put a book at top of stack by passing the stack number and the object like
bspush (0, 100);
and then retrieve the same item by calling bspop with the number of same stack
and a address of same type object to put the result.. like:
bspop (0, &i);

New purchase - The Minix Book vol 3


good book