Monday, May 5, 2014

Unix terminal driver simulation program

The following program is a simulation of UNIX terminal driver canonical mode only minimal functions are implemented

#include
#include
#include

/*
 * 
 */

struct cblock
{
    struct cblock * next;
    char data[8];
    int start;
    int end;
};
typedef struct cblock * Cblock;

struct clist
{
    Cblock first;
    Cblock last;
    int count;
};
typedef struct clist * Clist;


Clist freelist;
Clist inputClist;
Clist cookedClist;
Clist outputClist;

void intializeClist(Clist);
void initializeCblock(Cblock);
void initalizeFreelist();
void addToClist(Clist list,Cblock block);
void writeToHardware();

void intializeClist(Clist list)
{
    list->first=NULL;
    list->last=NULL;
    list->count=0;
}

void initializeCblock(Cblock block)
{
    block->start=-1;
    block->end=-1;
    block->next=NULL;
}

void initalizeallClist()
{
    Cblock temp;
    int i;
    freelist = (Clist)malloc(sizeof (struct clist));
    inputClist = (Clist)malloc(sizeof (struct clist));
    outputClist = (Clist)malloc(sizeof (struct clist));
    cookedClist = (Clist)malloc(sizeof (struct clist));
    intializeClist(inputClist);
    intializeClist(cookedClist);
    intializeClist(outputClist);
    intializeClist(freelist);
    for(i=0;i<50 font="" i="">
    {
        temp=(Cblock)malloc(sizeof (struct cblock));
        initializeCblock(temp);
        addToClist(freelist,temp);
    }

}

void addToClist(Clist list,Cblock block)
{
    if(list->first==NULL)
    {
        list->first=block;
    }
    if(list->last!=NULL)
    {
        list->last->next=block;
    }
    list->last=block;
    list->count++;
}

Cblock getBlockFromList(Clist list)
{
    Cblock temp;
    if(list->first==NULL)
    {
        return NULL;
    }
    temp=list->first;
    list->first=list->first->next;
    if(list->first==NULL)
        list->last=NULL;
    list->count--;
    return temp;
}

Cblock getBlockFromFreeList()
{
    Cblock temp;
    temp = getBlockFromList(freelist);
    if(temp==NULL)
        return temp;
    initializeCblock(temp);
    return temp;
}

void addCharToCLIST(Clist list,char c)
{
    Cblock temp;
    if(list->first==NULL)
    {
        temp=getBlockFromFreeList();
        if(temp!=NULL)
        addToClist(list,temp);
    }
   
    if(list->last->end==7)
    {
        temp=getBlockFromFreeList();
        if(temp!=NULL)
        addToClist(list,temp);
    }
    if(list->last->start==-1)
        list->last->start++;
    list->last->end++;
    list->last->data[list->last->end]=c;
    
}

char getCharFromList(Clist list)
{
    char temp;
    int pos;
    Cblock block;
    if(list->first==NULL)
    {
        printf("\nList Empty\n");
        return '\0';
    }
    pos=list->first->start;
    list->first->start++;
    if(pos<0 pos="">=8)
        printf("error");
    temp=list->first->data[pos];
    if(list->first->start==8)
    {
        block=getBlockFromList(list);
        addToClist(freelist,block);
    }
    return temp;
}

void terminal_write(char userspace[],int start,int count)
{
    
    int last,pos,i,j;
    pos=start;
    char c;
    last = start+count-1;
    while(pos<=last)
    {
        //if(outputClist->count>4)
        //{
        //    writeToHardware();
        //}
        for(i=0;i<8 font="" i="">
        {
           c=userspace[pos++];
           if(c=='\t')
           {
               for(j=0;j<5 font="" j="">
               addCharToCLIST(outputClist,' ');
           }
           else
               addCharToCLIST(outputClist,c);
        }
    }
    writeToHardware();
    
}

void writeToHardware()
{
    char c;
    int pos=0;
    char string[100];
    while(outputClist->first!=NULL)
    {
        c=getCharFromList(outputClist);
        if(c=='\0')
            continue;
        string[pos++]=c;
    }
    string[pos++]='\0';
    write(1,string,pos);
}

void terminal_read(char userspace[],int start,int count)
{
    int i,j;
    char data[2];
    char c;
    int outcount=0;
    if(cookedClist->first==NULL)
    {
        for(i=0;i
        {
            read(0,data,1);
            if(data[0]=='\n')
                break;
            addCharToCLIST(inputClist,data[0]);
        }
        while(inputClist->first!=NULL)
        {
            c=getCharFromList(inputClist);
              if(c=='\t')
           {
               for(j=0;j<5 font="" j="">
               addCharToCLIST(cookedClist,' ');
           }
              else
                  if(c=='\n')
                  {
                      break;
                  }
           else
               addCharToCLIST(cookedClist,c);
        }
    }
    while(cookedClist->first!=NULL&&outcount
    {
        c=getCharFromList(cookedClist);
        userspace[outcount++]=c;
    }
}

int main(int argc, char** argv) {

    char userspace[6]={'a','b','\t','c','d','e'};
    char userspace2[6];
    
    initalizeallClist();
    
    terminal_write(userspace,0,6);
    terminal_write(userspace,0,6);
    terminal_read(userspace2,0,5);
    userspace2[5]='\0';
    printf("\n%s",userspace2);
    return 0;
}