18
ESCOLA POLITÉCNICA DA UNIVERSIDADE DE SÃO PAULO Departamento de Engenharia de Computação e Sistemas Digitais PCS2042 – Sistemas Operacionais Projeto 1 Familiarização com o Minix Grupo 2 Bruno Umeda Grisi Carolina Dorta Davi Assahira Professor: Jorge Kinoshita

programa C minix

Embed Size (px)

DESCRIPTION

programa imprime data e nome do arquivo

Citation preview

Page 1: programa C minix

ESCOLA POLITÉCNICA DA UNIVERSIDADE DE SÃO PAULO

Departamento de Engenharia de Computação e Sistemas Digitais

PCS2042 – Sistemas Operacionais

Projeto 1 Familiarização com o Minix

Grupo 2 Bruno Umeda Grisi Carolina Dorta Davi Assahira Professor: Jorge Kinoshita

Page 2: programa C minix

Índice

1. OBJETIVO .................................................................................................................................. 3

2. APLICATIVO NA LINGUAGEM C .................................................................................... 3

2.1. DESCRIÇÃO ................................................................................................................................ 3

2.2. CHAMADAS AO SISTEMA ............................................................................................................ 3 2.2.1. Definição ................................................................................................................................ 3

2.2.2. Funcionamento ....................................................................................................................... 3

2.2.3. Stat(path, buf) ......................................................................................................................... 3

2.3. DESENVOLVIMENTO DO PROGRAMA ......................................................................................... 4 2.4. PROGRAMA.................................................................................................................................. 5 2.5. SIMULAÇÃO ................................................................................................................................ 7

3. MODIFICAÇÃO DA STAT(PATH, BUF) ........................................................................ 8

3.1. DESCRIÇÃO ................................................................................................................................ 8

3.2. DESENVOLVIMENTO DO PROGRAMA ......................................................................................... 8 3.3. PROGRAMA.................................................................................................................................. 8 3.4. SIMULAÇÃO ................................................................................................................................ 9

4. MATERIAL COMPLEMENTAR ......................................................................................... 10

4.1. ANEXO A – CÓDIGO FONTE DO PROGRAMA APLICATIVO..................................................... 10 4.2. ANEXO B – CÓDIGO FONTE DA SYSTEM CALL MODIFICADA ............................................... 17

5. BIBLIOGRAFIA ..................................................................................................................... 18

Page 3: programa C minix

1. Objetivo Este primeiro projeto objetiva conhecer a estrutura e o funcionamento

do sistema operacional Minix, desenvolvendo programas na linguagem de programação C que utilizam as chamadas ao sistema.

Outro objetivo dessa atividade é compartilhar com os demais alunos da turma o que foi pesquisado e aprendido, ao mesmo tempo em que se aprofunda com as apresentações expostas.

Dessa forma, é possível consolidar a teoria da disciplina, aplicando exercícios práticos elaborados que estendem o estudo e o interesse ao aprendizado.

2. Aplicativo na Linguagem C

2.1. Descrição Foi proposto o desenvolvimento de um programa a ser executado no

Minix capaz de imprimir os nomes e as datas dos arquivos localizados no diretório corrente.

2.2. Chamadas ao sistema

2.2.1. Definição

Chamada ao sistema ou system call é uma solicitação feita por qualquer programa arbitrário ao sistema operacional para a execução de tarefas que esse programa não possui as permissões necessárias para executar em seu fluxo de operação.

2.2.2. Funcionamento

A princípio, o sistema, no modo usuário, ao encontrar uma system call no programa do usuário em execução, armazena na pilha as informações necessárias para o retorno ao programa. Em seguida, inicia-se o procedimento da biblioteca, armazenando o código da system call em um registrador. Depois, executa-se uma instrução TRAP para passar do modo usuário (privilégios restritos) ao modo núcleo (privilégios maiores) que possibilita o processo de identificação da chamada ao sistema pelo código do núcleo e de despacho para o tratamento de sua execução propriamente dita. Terminado esse tratamento, o controle retorna ao procedimento da biblioteca no espaço do usuário na instrução seguinte à instrução TRAP. Por fim, retorna-se ao programa do usuário que limpa a pilha, liberando-o para continuar sua execução.

2.2.3. Stat(path, buf)

A função dessa system call é obter informações sobre o arquivo definido por path e escrevê-lo na área apontada pelo argumento buf. O argumento path aponta ao parthname que nomeia o arquivo. Nesta system call, não é necessário que o arquivo nomeado possua as permissões de leitura, escrita e execução. O argumento buf é um ponteiro para a estrutura

Page 4: programa C minix

de dados stat, conforme definida no código fonte do Minix, em que é armazenada a informação referente ao arquivo. Após executada a system call, o sistema apresenta essa informação gravada correspondente ao arquivo nomeado.

A estrutura de dados stat apresenta os seguintes atributos:

dev_t st_dev; /* dispositivo residido pelo inode */

ino_t st_ino; /* número inode */

mode_t st_mode; /* modo do arquivo */

nlink_t st_nlink; /* número de links para o arquivo */

uid_t st_uid; /* id do usuário proprietário do arquivo */

gid_t st_gid; /* id do grupo proprietário do arquivo */

dev_t st_rdev; /* tipo de dispositivo, para inode que é dispositivo */

off_t st_size; /* tamanho total do arquivo */

time_t st_atime; /* tempo do ultimo acesso */

time_t st_mtime; /* tempo da última modificação de data */

time_t st_ctime; /* tempo da última mudança de estado do arquivo */

Da mesma forma como em muitas chamadas ao sistema, a system call stat utiliza o icode que contém todas as informações referentes a um arquivo para obter uma referência ao arquivo no SO.

2.3. Desenvolvimento do Programa Foi proposto o desenvolvimento de um programa capaz de imprimir os

nomes e as datas dos arquivos localizados no diretório corrente.

O desenvolvimento do programa pedido só foi possível após a realização de um estudo do código fonte do Minix e, especialmente, das chamadas ao sistema que seriam utilizadas no programa.

Percebemos que, embora haja restrições de acesso configuradas pelo próprio SO, é necessária bastante cautela na manipulação do código, uma vez que é possível alterar processos importantes do sistema.

Page 5: programa C minix

2.4. Programa O programa foi feito da seguinte forma:

Primeiramente, há uma estrutura eachfile, que contém as informações nome e data/hora do arquivo. Ela é construída depois do acesso ao inode para a obtenção das informações do arquivo.

Deve-se lembrar que, quando, nesse texto, citamos “arquivo”, na verdade, estamos citando uma estrutura que pode ser um arquivo em si ou então um diretório, que nada mais é que um arquivo que contém referências entre nomes (nomes de seus arquivos) e inodes.

Na teoria de sistemas operacionais, um inode (ou index node, ou ainda nó-i) é uma estrutura de dados constituinte de um sistema de arquivos (SA) que segue a semântica Unix. O inode armazena informações sobre arquivos, tais como o usuário de acesso, permissões e a localização do mesmo (p.ex., blocos alocados num volume de disco).

Sendo assim, o fluxo do programa se resume em:

1. Ler o nome do diretório

Para ler o nome do diretorio foi utilizada a função ParseParameters, que obtém o diretório atual - caso não haja parâmetros – ou então algum diretório referenciado no comando e copia seu nome para dirname

2. Contar quantos arquivos há nesse diretório

Para isso utilizamos a função GetQuantityOfFiles, que possui uma estrutura DIR (uma estrutura de diretório) e faz uso de rotinas de diretório tais como:

a. Opendir(): Abre o diretório e retorna um ponteiro para a stream desse diretório. Esta rotina retorna um ponteiro nulo se o diretório não puder ser aberto ou se não foi possível alocar memoria suficiente para a struct DIR.

b. Readdir(): Lê uma entrada do diretório e como uma apontador para a estrutura contendo o campo d_name, um vetor de caracteres contendo o número da entrada, que termina com um valor nulo. Esta função retorna null se não há mais entradas ou se ocorreu um erro.

c. Closedir(): Fecha o diretório. Esta função retorna 0 caso haja sucesso, -1 se houver erro.

Além disso, há nesta função a struct dirent *entry. Uma struct dirent é uma estrutura de dados definida em dirent.h, uma referencia que está localizada no cabeçalho da biblioteca C do Minix. Lá há operações que facilitam a manipulação de diretórios. Nessa estrutura há as seguintes propriedades:

a. off_t d_off - não existente em todas as implementações

b. unsigned short d_namlen - comprimento do nome em d_name

c. unsigned short d_reclen

d. ino_t d_ino - numero serial do arquivo

Page 6: programa C minix

e. char d_name[] - nome do arquivo (não excede o tamanho NAME_MAX)

3. Reservar um espaço em memória que corresponda ao tamanho de uma estrutura eachfile multiplicado pela quantidade de arquivos encontrados;

Isso feito através de malloc. Foi implementado da seguinte forma:

files = malloc(GetQuantityOfFiles(directory_name) * sizeof(struct eachfile))

A função GetQuantityOfFiles(directory_name) é a explicada no item anterior.

4. Obter as informações dos arquivos do diretório e colocá-las em uma coleção de estruturas eachfile;

Isto foi feito a partir da função GetFiles. Esta função recebe o nome do diretório e estruturas eachfile para serem construídas

com os parâmetros dos arquivos do diretório. Ela também possui uma estrutura DIR e uma estrutura dirent para a manipulação de diretórios e seus conteúdos. Ela também faz uso das rotinas de diretório opendir(), readdir() e closedir() para ler os arquivos e colocar seus nomes e data/hora nas estruturas eachfile. Para setar as estruturas eachfile esta função faz uso de outra, a MakeOneFile.

A função MakeOneFile constrói o caminho do arquivo a partir da função ConstructPath e utiliza esse caminho na system call stat(). Quando stat() recebe este caminho como parâmetro, é capaz de consultar o inode correspondente para obtenção de informações do arquivo. Caso tenha sido possível realizar a system call stat(), sabemos que o arquivo é válido e podemos setar a estrutura eachfile. Isso é feito a partir de dois comandos:

a. strcpy(file->name, entry->d_name)

Este comando copia para o “name” de eachfile a informação d_name da estrutura dirent “entry”.

b. file->datetime = stbuf.st_mtime

Este comando copia para o “datetime” de eachfile a informação st_mtime que foi obtida no inode, que corresponde à data da última modificação do arquivo

5. Ordenar esses arquivos por data/hora;

Isso foi feito a partir da função OrderFiles, que ordena as estruturas eachtime no vetor de acordo com o parâmetro datetime.

6. Imprimir as informações.

Isto foi feito a partir da função PrintFiles, que simplesmente imprime as informações “name” e “datetime” dos arquivos do diretório na tela. A única peculiaridade desta função é o uso de ctime() da biblioteca time.h, que

Page 7: programa C minix

formata uma data/hora em “Www Mmm dd hh:mm:ss yyyy”, onde Www é referente ao dia da semana da data em questão.

O código fonte do programa desenvolvido encontra-se no Anexo A.

2.5. Simulação A simulação do programa pode ser visualizada nas figuras a seguir.

Comando ls – l:

Programa implementado:

Page 8: programa C minix

3. Modificação da Stat(path, buf)

3.1. Descrição Este exercício consiste na alteração de uma chamada ao sistema que

foi utilizada no programa anterior de forma a imprimir uma mensagem toda vez que ela for chamada.

3.2. Desenvolvimento do Programa A dificuldade neste exercício é fazer o sistema reconhecer as

modificações realizadas no código executado pela system call, já que o SO apresenta um mecanismo que mantém a imagem atual no sistema mesmo após alterado o seu código.

Acessamos o diretório que contém o código fonte que executa a system call stat(), localizado no seguinte path /usr/src/servers/fs. E modificamos o código com o auxílio do editor de texto elle a fim de ser impressa uma mensagem toda vez que a system call for executada.

Em seguida, compilamos os servers do Minix (path: /usr/src/servers) por meio dos comandos make image e make install.

É preciso criar uma nova imagem de boot para combinar os arquivos bin do Minix e habilitar a mudança realizada, executando os comandos make hdboot e make install no path /usr/src/tools. Ao término desta última operação, o sistema apresentará o nome da imagem de boot criada. Como precisaremos deste nome mais para frente, anote-o.

Agora, fazemos um shutdown no Minix que disponibilizará a seleção de uma nova imagem. Utilizando o nome da imagem anotado, associa-se a imagem criada ao sistema: d0p0s0> image=/boot/image/nome_da_imagem. Por fim, executa-se um boot e o sistema reconhecerá as mudanças feitas na system call.

3.3. Programa O implementação do programa é bem simples. Resume-se apenas a

uma linha de código:

printf(“Mensagem a ser impressa a cada chamada.\n”);

O código fonte do programa desenvolvido encontra-se no Anexo B.

Page 9: programa C minix

3.4. Simulação A simulação do programa pode ser visualizada na figura a seguir.

Page 10: programa C minix

4. Material Complementar

4.1. Anexo A – Código Fonte do Programa Aplicativo #include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <dirent.h>

#include <time.h>

#include <sys/stat.h>

#include <sys/types.h>

void MakeOneFile(char *directory_name, struct dirent *entry, struct eachfile *file);

void ConstructPath(char *directory_name, char *file_name, char *path);

int GetQuantityOfFiles(char *directory_name);

int GetFiles(char *directory_name, struct eachfile *files);

void OrderFiles(int quantity, struct eachfile *files);

void ParseParameters(int argc, char *argv[], char *directory_name);

void PrintFiles(int quantity, struct eachfile *files);

/*estrutura que será utilizada para a manipulaçao dos dados dos arquivos.

contém um nome e uma data/hora, que será a data/hora da ultima modificaçao realizada*/

struct eachfile

{

char name[255];

time_t datetime;

};

/*

MakeOneFile

Retorno: nao há

Parametros: o nome do diretorio, uma estrutura dirent para o arquivo e uma estrutura

eachfile que contem o nome e datetime do arquivo.

Descricao: esta funcao receba a estrutura dirent que já contem os dados do arquivo

Page 11: programa C minix

que foram obtidos ao ler o diretório e monta a estrutura eachfile, com o nome do arquivo

e a data.

*/

void MakeOneFile(char *directory_name, struct dirent *entry, struct eachfile *file)

{

/* A estrutura stat é retornada pelas funcoes fstat() e stat().

Ela contém as informaçoes detalhadas de um arquivo.

A informaçao retornada depende do tipo de arquivo e/ou arquivo de sistema.*/

struct stat stbuf;

char path[255];

/*funcao que constroi o caminho do arquivo*/

ConstructPath(directory_name, entry->d_name, path);

/*A função dessa system call é obter informações sobre o arquivo

definido por path e escrevê-lo na área apontada pelo argumento buf.

O argumento path aponta ao parthname que nomeia o arquivo.*/

if (stat(path, &stbuf) == 0)

{

/*copia entry->d_name para file->name

lembrando que d_name é o nome do arquivo que foi obtido pelo inode*/

strcpy(file->name, entry->d_name);

/*o datetime de nosso eachfile recebe st_mtime do inode, que

é a data/hora da ultima modificaçao*/

file->datetime = stbuf.st_mtime;

}

else

{

printf("nao foi possivel obter o status do arquivo");

exit(1);

}

}

/*

ConstructPath

Retorno: nao há

Page 12: programa C minix

Parametros: o nome do diretorio, o nome do arquivo e o caminho a ser montado

Descricao: esta funcao recebe o nome do diretorio e um nome de arquivo e os utiliza

para construir um caminho, usando a funcao strcat().

*/

void ConstructPath(char *directory_name, char *file_name, char *path)

{

/*strcpy() copia a string em C apontada pela fonte para o array apontado

pelo destino, incluindo o caractere nulo de fim*/

strcpy(path, directory_name);

/*strcat() junta uma copia da string de origem para com a string de destino.

O caractere nulo no fim do destino é sobrescrito com o primeiro caractere

da string de origem, e um novo caractere nulo é posto ao fim da nova string

formada pela concatenaçao da origem com o destino*/

strcat(path, "/");

strcat(path, file_name);

}

/*

GetQuantityOfFiles

Retorno: quantidade de arquivos em um diretorio (int)

Parametros: o nome do diretorio (um vetor de chars)

Descricao: esta funcao recebe um nome e o utiliza para abrir um diretorio

através das rotinas de diretorio opendir(), readdir() e closedir().

*/

int GetQuantityOfFiles(char *directory_name)

{

int quantity = 0;

struct dirent *entry;

DIR *directory;

/*Opendir() abre o diretorio e retorna um ponteiro para a stream desse diretorio.

Esta rotina retorna um ponteiro nulo se o diretorio nao puder ser aberto

Page 13: programa C minix

ou se nao foi possivel alocar mamoria suficiente para a struct DIR.*/

directory = opendir(directory_name);

do

{

/*Readdir() le uma entrada do diretorio e como uma apontador para a estrutura

contendo o campo d_name, um vetor de caracteres contendo o numero da entrada,

que termina com um valor nulo. esta funcao retorna null se nao há mais entradas ou se

ocorreu um erro*/

entry = readdir(directory);

quantity ++;

}while(!(entry == (struct dirent *) NULL));

/*Closedir() fecha o diretorio

esta funcao retorn 0 caso haja sucesso, -1 se houver erro.*/

closedir(directory);

return quantity;

}

/*

GetFiles

Retorno: numero de arquivos

Parametros: o nome do diretorio, e structs eachfile que serao preenchidas

Descricao: esta funcao recebe o nome do diretorio e estruturas eachfile para serem construidas

com os parametros dos arquivos do diretorio

*/

int GetFiles(char *directory_name, struct eachfile *files)

{

/*o tipo/estrutura DIR representa um diretorio*/

DIR *dir;

int i;

/*struct dirent - uma estrutura com os seguintes membros:

* off_t d_off - nao extatientes em todas as implementacoes

* unsigned short d_namlen - comprimento do nome em d_name

Page 14: programa C minix

* unsigned short d_reclen

* ino_t d_ino - numero serial do arquivo

* char d_name[] - nome do arquivo (nao excede o tamanho NAME_MAX)

*/

struct dirent *entry;

/*Opendir() abre o diretorio e retorna um ponteiro para a stream desse diretorio.

Esta rotina retorna um ponteiro nulo se o diretorio nao puder ser aberto

ou se nao foi possivel alocar mamoria suficiente para a struct DIR.*/

dir = opendir(directory_name);

i = 0;

do

{

/* le um arquivo e poe toda sua estrutura na estrutura dirent entry*/

entry = readdir(dir);

/*esta funcao seta no vetor files[] um arquivo referenciado pela estrutura

dirent entry que foi obtida no diretorio com nome directory_name*/

MakeOneFile(directory_name, entry, &files[i++]);

/* faz esse loop até a estrutura dirent entry nao for nula.

O cast é feito pra comparaçao de nulo com estrutura*/

}while(!(entry == (struct dirent *) NULL));

/*fecha o diretorio*/

closedir(dir);

return i;

}

/*

OrderFiles

Retorno: nao há

Parametros: a quantidade de arquivos, estruturas eachfile com os parametros

Page 15: programa C minix

datetime através das quais os arquivos serao ordenados

Descricao: esta funcao usa o metodo de ordenaçao ____ para ordenar as estruturas

no vetor de acordo com o parametro datetime.*/

void OrderFiles(int quantity, struct eachfile *files)

{

int i, j;

/*estrutura temporária auxiliar ao método*/

struct eachfile tmp;

for(i = quantity - 1; i > 0; i--)

for(j = 0; j < i; j++)

if(files[j].datetime < files[j+1].datetime)

{

tmp = files[j];

files[j] = files[j+1];

files[j+1] = tmp;

}

}

/*

ParseParameters

Retorno: nao há

Parametros: a quantidade de arquivos, estruturas eachfile com os parametros

datetime através das quais os arquivos serao ordenados

Descricao: esta funcao usa o metodo de ordenaçao ____ para ordenar as estruturas

no vetor de acordo com o parametro datetime.*/

void ParseParameters(int argc, char *argv[], char *directory_name)

{

switch(argc)

{

case 1: strcpy(directory_name, "."); break;

case 2: strcpy(directory_name, argv[1]); break;

default: printf("Numero errado de parametros"); exit(1); break;

}

}

/*

PrintFiles

Page 16: programa C minix

Retorno: nao há

Parametros: a quantidade de arquivos, estruturas eachfile com os parametros

name e dattime que serao impressos

Descricao: esta funcao imprime os dados nome e datetime dos arquivos na tela*/

void PrintFiles(int quantity, struct eachfile *files)

{

int i;

printf("\nGRUPO 2\n");

printf("\nIntegrantes: Bruno Grisi");

printf("\n Carolina Dorta");

printf("\n Davi Assahira");

printf("\nInicio do programa\n\n");

for(i = 0; i < quantity; i++)

{

printf("Nome do arquivo: %-15s", files[i].name);

printf("Data: %s", ctime(&files[i].datetime));

}

printf("\nFim\n");

}

int main(int argc, char *argv[])

{

int quantity;

char directory_name[255];

struct eachfile *files;

ParseParameters(argc, argv, directory_name);

files = malloc(GetQuantityOfFiles(directory_name) * sizeof(struct eachfile));

quantity = GetFiles(directory_name, files);

OrderFiles(quantity, files);

PrintFiles(quantity, files);

}

Page 17: programa C minix

4.2. Anexo B – Código Fonte da System Call Modificada

Page 18: programa C minix

5. Bibliografia 1. http://www.minix-vmd.org/pub/Minix-vmd/1.7.0/wwwman/man3/directory.3.html 2. http://www.cplusplus.com/reference/clibrary/cstring/strcpy.html 3. http://en.wikipedia.org/wiki/Dirent.h 4. http://souptonuts.sourceforge.net/code/dir.c.html 5. http://www.mkssoftware.com/docs/man5/struct_stat.5.asp 6. http://en.wikipedia.org/wiki/Time.h 7. http://www.dmoz.org/Computers/Algorithms/Sorting_and_Searching/ 8. http://www.cis.syr.edu/~wedu/seed/Documentation/Minix3/How_to_add_system_call.pdf