Sunteți pe pagina 1din 11

Analista Universitario en Sistemas Sistemas Operativos Llamadas al sistema en Linux

2009

Introduccin: Todo procesador moderno posee al menos dos modos de funcionamiento distintos modo kernel (Protected Mode) y modo usuario (System Management Mode SMM). A grandes rasgos las diferencias entre estos dos modos son las siguientes:

En modo kernel se encuentran disponibles todas las instrucciones y funcionalidades que la arquitectura del procesador es capaz de brindar, sin ningn tipo de restricciones. Es en este modo en el cual corre el kernel (ncleo) del sistema operativo. or lo general es el kernel el nico que corre en este modo. En modo usuario tan s!lo un subcon"unto de las instrucciones y funcionalidades que la arquitectura del procesador ofrece se encuentran disponibles. En este modo se e"ecutan los procesos de los usuarios del sistema (todo proceso corriendo en el sistema pertenece a un usuario). #onocido tambi$n como userland.

%na de las responsabilidades de un &.'. es administrar los recursos del sistema y los procesos que corren en el mismo. #ada vez que un proceso necesite algn recurso del sistema (memoria, uso de un (ard)are espec*fico, e"ecutar otro proceso), ser+ el &.'. el encargado de suministr+rselo. ara esto deber+ e,istir un medio de comunicaci!n entre el &.'. y los procesos en e"ecuci!n. %na de las maneras que e,iste para que los procesos y el sistema operativo puedan comunicarse son las llamadas al sistema. A primer vista las llamadas al sistema lucen como simples funciones las cuales reciben sus par+metros de entrada y entregan un valor de salida, y de (ec(o lo son, solo que estas funciones son implementadas por el ncleo del &.'. Esto significa que ser+ el &.'. quien recibir+ los par+metros de entrada, e"ecutar+ la funci!n que le sea requerida, siempre y cuando sea posible y permitida, y devolver+ los valores necesarios, as* como tambi$n puede o no cambiar el estado de su estructura interna. -e esto tambi$n podemos deducir que estas llamadas al sistema se e"ecutar+n en modo kernel. -e (ec(o, el procesador est+ constantemente cambiando de modo usuario a modo kernel y viceversa (en cualquier &.'. multitarea, como lo es .inu,, en el cual se requiere una mayor responsabilidad del &.'. para administrar los procesos, el procesador alterna entre ambos modos al menos unas cuantas miles de veces por segundo). A(ora bien, para u! son necesarias las llamadas al sistema". #omo di"imos antes, para que los procesos puedan comunicarse con el kernel del &.'. ero seamos un poco m+s espec*ficos, las llamadas al sistema nos brindan un medio para obtener recursos del &.'., obtener informaci!n del mismo, establecer o cambiar el seteo de los recursos que se ofrecen. /eamos algunos e"emplos de esto:

En los sistemas %012 (.inu, es uno de ellos) todo los dispositivos son representados mediante arc(ivos, y dado que es el &.'. el encargado de administrar el sistema de arc(ivos, file system, (as* como los dispositivos, por supuesto), es por medio de $ste que podremos utilizar un dispositivo espec*fico como puede ser una lectora de #-, una placa de video, el mouse o el teclado. 'tro de los recursos administrados por el &.'. es la memoria. #ada vez que un proceso requiera de m+s cantidad de memoria, o desee liberar parte de la misma que tiene asignada, necesitar+ usar las llamadas al sistema para informar al ncleo del &.'. 3ay cosas m+s simples que solo pueden ser accedidas mediante el &.'. como la (ora actual, el nombre de un equipo, (asta el simple almacenamiento de datos en un arc(ivo de te,to.

Todas estas tareas no pueden realizarse sin la ayuda del &.'., entonces4 qu es lo que se puede hacer sin la ayuda del S.O.? .a respuesta es nada, ya que para poder e"ecutar un proceso, necesitamos del &.'., y sin un proceso corriendo no podemos (acer nada. A(ora, supongamos que tenemos a un proceso corriendo en el sistema, que es lo que este puede (acer sin emplear llamadas al sistema, la respuesta ser+ virtualmente la misma. Este podr+ e"ecutar todas las instrucciones que la arquitectura del procesador permita que sean e"ecutadas en modo usuario pero nada m+s. &i tenemos en cuenta que toda comunicaci!n entre el procesador y el mundo e,terior se (ace mediante dispositivos perif$ricos (teclado, monitor, placa de red, etc.)
#$%ina & de &&

y que es el &.'. el encargado de administrarlos, y por tanto, el nico que puede con ellos comunicarse, r+pidamente nos daremos cuenta (asta que punto somos dependientes del &.'. para poder llevar a cabo cualquier tipo de tarea. ara resumir, si alguien nos preguntase que es todo lo que podemos (acer como usuarios de un &.'., podr*amos responder que todo lo que uno puede (acer, se encuentra acotado por las instrucciones que la arquitectura del sistema en que traba"amos nos permite e"ecutar en modo usuario, m+s las tareas que pueden ser realizadas por medio de llamadas al sistema. Eso es todo, c(equeando estos dos par+metros podremos saber que es lo que un &.'. nos permite realizar. El &.'. .inu, posee m+s de 566 llamadas al sistema, las cuales se encuentran enumeradas en el arc(ivo /usr/include/asm/unistd.h. 'mo utili(ar las llamadas al sistema: 7+s del 869 del c!digo de .inu, se encuentra escrito en # y si bien una llamada al sistema puede invocarse utilizando cualquier lengua"e de programaci!n, el lengua"e que nosotros utilizaremos ser+ el #, dado que se trata del lengua"e nativo de dic(o &.'. odr*a parecer que analizar las mismas desde un lengua"e assembler es quiz+s una apro,imaci!n m+s pura, pero esto es algo falso, dado que .inu, funciona sobre un gran nmero de arquitecturas diferentes, y para cada arquitectura e,iste una forma distinta de e,presar en c!digo m+quina las llamadas al sistema, en # estos detalles resultan transparentes al ser un lengua"e de nivel superior menos relacionado con la arquitectura subyacente. &in embargo diremos algunas pocas palabras acerca de c!mo utilizar las llamadas al sistema en un lengua"e assembler. Llamadas al sistema en assem)ler: .as llamadas al sistema en .inu, se realizan mediante la l*nea de interrupci!n por soft)are numero 0x*0 (:6 en (e,adecimal), y los par+metros de las mismas se pasan usando los registros del procesador. En +A, se guardar+ el n mero de la llamda al sistema al cual queremos invocar, estos nmeros est+n descriptos en /usr/include/asm/unistd.h, luego, los par+metros ser+n pasados en los registros siguientes, +-,, +',, +.,, +SI y +.I consecutivamente. or tanto, el m+,imo nmero de par+metros que puede recibir una llamada al sistema es cinco. El valor devuelto por la llamada se almacena en +A,. ara finalizar analizaremos este e"emplo escrito en !"SM en el cual se realiza una llamada a la funci!n read: Fragmento cdigo (1) mov eax,0x3 mov ebx,0 mov ecx,edi mov edx,0x1f int 0x80 ;ecordemos el prototipo de la funci!n read: ssize_t read(int fd, void *buf, size_t count); En caso de ignorar el funcionamiento de la funci!n read (o de otra llamada al sistema), pueden consultarse las p+ginas del manual de .inu,, utilizando el comando: $ man 2 read Aqu* se especifica la bsqueda de informaci!n sobre la funci!n read en la secci!n 5 del manual. obtener informaci!n de las llamadas al sistema tambi$n (aciendo uso del comando: $ man 2 syscalls < luego consultando la p+gina individual de cada una de las llamadas. .a funci!n read lee del arc(ivo descripto por fd (asta un m+,imo de count bytes, los guarda a partir de la direcci!n de memoria buf y retorna el nmero de bytes le*dos. En el =ragmento de c!digo (>) anterior, inicialmente se carga en +A, (1) el nmero que describe a la funci!n que queremos llamar (el ? es el nmero asociado a la funci!n read). .uego pasamos como primer par+metro el valor 6 (2), en EBX, que es un descriptor de arc(ivo generalmente referido a la entrada est+ndar ( stdin), el
#$%ina 2 de &&

(1) (2) (3) (4)

odemos

teclado. .uego le pasamos como segundo par+metro el contenido de +.I (3), en +',, que es una direcci!n en donde deber+ guardar los bytes le*dos, y por ultimo (4), en +.,, le pasamos el nmero m+,imo de bytes que queremos que lea, en este caso 6,>f, o sea ?>. or ltimo llamamos a la interrupci!n por soft)are numero 0x*0, que es por medio de la cual se realizan las llamadas al sistema en .inu,. Al retornar la e"ecuci!n del programa, luego de (aberse e"ecutado la interrupci!n, tendremos a partir de la direcci!n apuntada por +.I los bytes le*dos, y en +A, cu+ntos (an sido estos. /O0A Esto es todo lo que (ablaremos de assembler en este documento, de a(ora en adelante todo c!digo estar+ e,presado en #. Llamadas al sistema en ': /eamos a(ora como ser*a la misma llamada pero implementada en #: /* read.c L amada a #include <unistd.h> int main !" char buf#32$% int result% result & read 0,buf,si'eof buf!!% return result% sistema read en ! */

#ada vez que el int$rprete de comandos (shell) e"ecuta un programa asocia al mismo tres descriptores de arc(ivos conocidos como la entrada est+ndar (stdin), salida est+ndar (stdout) y salida de errores (stderr), cuyos valores son respectivamente 6, > y 5. or tanto el valor 6 pasado como argumento a la funci!n read indica que lea de la entrada est+ndar. @sta puede ser tanto el teclado como un arc(ivo de te,to dependiendo de como uno e"ecute el programa desde el shell. or la general para realizar una llamada al sistema desde # no se necesita m+s que incluir las directivas del preprocesador 1include (aciendo referencia a los arc(ivos de cabecera ( headers# mencionados en la correspondiente p+gina del manual de la llamada y luego simplemente invocar la funci!n que e"ecuta la llamada. En este caso $unistd.h%. .a &!' ( li)rary, "unto con las dem+s que provee, incluye funciones que llevan a cabo la tarea de pasar los par+metros al kernel y llamar a la interrupci!n adecuada, de manera transparente para el programador. A continuaci!n listaremos un programa llamado mi*date.c que imita al conocido comando %012 date, y muestra la fec(a y (ora actual por pantalla:

#$%ina 2 de &&

/* mi_date.c " #uestra #include <stdio.h> #include <sys)time.h> #include <time.h> #include <unistd.h>

a fec$a %

a $ora actua

&or &anta

*/

void *rint+time ! " struct timeva tv% struct tm, *tm% char time+strin-#.0$% ),/btenemos la fecha y hora del d0a y la transformamos en un estructura tm,) gettimeofda% 1tv, 2344!% *tm & oca time 1tv.tv+sec!% ),3tili'ando la estructura tm creamos un strin- con la informacion 5ue deseamos,) strftime time+strin-, si'eof time+strin-!, 67d)7m)78 79:7;:7<6 , *tm!% ( *rintf 67s=n6 ,time+strin-!%

int main ! " *rint+time !% return 0% ( Este programa utiliza la llamada al sistema %ettimeo3da4 para conseguir la fec(a y (ora actual, que son obtenidas por el kernel consultando el ;T# (real time clock) de la m+quina. .a funci!n %ettimeo3da4 en nuestro e"emplo toma como primer par+metro un puntero a una estructura struct timeval, el segundo argumento es un puntero a una estructura time+one que aqu* no es utilizada (0%..). struct timeval " ++time+t tv+sec% ++suseconds+t tv+usec% (%

), <econds ,) ), ;icroseconds ,)

.a estructura time,al es instanciada por el kernel con los valores actuales de tiempo, la misma contiene la cantidad de segundos y microsegundos (timestamp) que (an transcurrido desde el comienzo de la llamada UNIX Epoch, la medianoc(e del primero de enero de >8A6. #omo esta representaci!n del tiempo no es muy c!moda para la gran mayor*a de los (umanos, utilizamos las funciones de la librer*a li)c localtime y strftime, las cuales son utilizadas para ofrecer un formato m+s legible para la fec(a y (ora actual. ueden consultarse las man pages de estas funciones con los comandos: $ man 3 localtime $ man 3 strftime /eamos otro e"emplo de una llamada al sistema. &e trata de un programa que muestra por pantalla informaci!n acerca del sistema. .a llamada al sistema que utiliza, s4sin3o, establece los valores de una estructura de tipo struct s4sin3o la cual se encuentra definida en /usr/include/linux/kernel.h.

#$%ina 5 de &&

/* stats.c " #uestra estad'sticas de en e(ecucin. */ #include #include #include #include <stdio.h> <linux)>ernel.h> <linux)sys.h> <sys)sysinfo.h>

sistema res&ecto a

uso de memoria %

os &rocesos

int main ! " const lon- minute & ?0% const lon- hour & minute , ?0% const lon- day & hour , 2.% const double me-abyte & 102. , 102.% struct sysinfo si% ), /btenemos estad0sticas del sistema ,) sysinfo 1si!% ), ;ostramos al-unos valores interesantes contenidos en la estructura sysinfo. ,) *rintf 6@iem*o 5ue lleva el sist. en funcionamiento: 7ld dias , 7ld:702ld:702ld=nA, si.u*time)day, si.u*time 7 day! ) hour, si.u*time 7 hour! ) minute, si.u*time 7 minute!% *rintf 6;emoria BC; total: 7D.1f ;b=n6 , si.totalram ) me-abyte!% *rintf 6;emoria BC; libre: 7D.1f ;b=n6 , si.freeram ) me-abyte!% *rintf 6Eantidad de *rocesos corriendo: 7d=n6 , si.*rocs!% ( return 0%

0ipos de llamadas al sistema: &i bien no e,iste ninguna definici!n formal de esto, las llamadas al sistema pueden ser agrupadas en ciertos grupos segn las funcionalidades que las mismas ofrecen. &in dar m+s detalles enumeraremos estos grupos. /O0A &alvo para el caso de las llamadas asociadas al mane"o de arc(ivos, no e,iste en el diseBo del ncleo nada que refle"e e,pl*citamente esta agrupaci!n que (aremos. Acceso a arc6ivos: Estas llamadas tienen como ob"etivo el leer, escribir, abrir, cerrar, etc., arc(ivos. Algunas de estas son: open close 7rite read lseek readdir ioctl 3s4nc 3lock mmap #omo ya di"imos, un arc(ivo, ba"o .inu,, puede estar representando muc(as cosas distintas. uede ser un simple arc(ivo de datos, que almacena informaci!n, puede representar un dispositivo de entradaCsalida, como el mouse o el teclado, o puede ser simplemente informaci!n almacenada en la memoria que utiliza el kernel para guardar informaci!n, como lo son los arc(ivos contenidos en el directorio -proc. Antes de poder usar cualquier arc(ivo, un proceso necesita abrir el mismo, esto se lleva a cabo con la funci!n open. .a misma devuelve al proceso un descriptor de arc(ivo (file descriptor) que en realidad no es m+s que un nmero que identifica un*vocamente al arc(ivo solicitado. El resto de la funciones necesitar+n este descriptor para saber sobre que arc(ivo deben e"ecutarse. .a funci!n 7rite escribe a un determinado arc(ivo y la funci!n read lee del mismo. .a sem+ntica de estas funciones depende del tipo de arc(ivo con el cual se est$ traba"ando. or e"emplo, los arc(ivos -de,-tty., -de,-tty/, etc. representan consolas virtuales, como las que usamos para
#$%ina 8 de &&

traba"ar de ordinario con el )ash por e"emplo. Escribir a -de,-tty. significar+ mostrar por pantalla en esa consola los caracteres que escribamos. Escribir a un arc(ivo normal del &.'. (normal por decir de alguna manera) significar+ guardar informaci!n en el disco r*gido. .eer del arc(ivo -de,-mouse (solo el root tiene permiso) devolver+, dependiendo del tipo de mouse con el cual traba"emos, una serie de bytes que representa las coordenadas de los movimientos del mouse. .eyendo el arc(ivo -proc-interrupts obtendremos un listado de las interrupciones que est+ atendiendo el sistema, y qu$ dri,er se encarga de atenderla a cada una, adem+s de otros datos. /eamos un e"emplo, el programa se llamara ej1.c, el mismo tomar+ dos opciones por l*nea de comandos: el nombre del arc(ivo, y a partir de que car+cter leer. .uego mostrar+ por pantalla (asta ?> caracteres despu$s del car+cter seleccionado. #include #include #include #include #include <unistd.h> <errno.h> <strin-.h> <stdlib.h> <cty*e.h>

int main int ar-c , char ,ar-v#$!" int fd,c,i&0% int result% int offset% char buf#32$% ), che5ueamos 5ue se *asen los ar-umentos necesarios ,) if ar-c < 3!" *rintf 63so: 7s <file> <nro. de caracteres a mostar>=n6, ar-v#0$!% exit 1!% (% ), che5ueamos 5ue el tercer ar-umento 2Fesimo en ar-v! sea un di-ito ,) Ghile c & ar-v#2$#i$!" if Hisdi-it c!!" *rintf 6errorH Iebe in-resar un numero de di-itos 6!% *rintf 6como se-undo ar-umento=n6!% exit 1!% ( iJJ% ( ), verificado 5ue es un numero, convierto el ar-umento char,!F> int! ,) offset & aoti ar-v#2$!% if fd & o&en ar-v#1$,O_RDONLY!! && F1! *error 6errorH6!% if see) fd, offset, SEEK_SET! && offsetF1!! *error 6errorH6!% if result&read fd, buf, 31!! && F1! " *error 6errorH6!% exit 1!% ( buf#result$ & K=0K% *rintf 6char 7d: 7s=n6, offset, buf!% close fd!% ( return 0% /*(1)*/ /*(*)*/ /*(+)*/

.as tres llamadas al sistema aqu* utilizadas son open, lseek y read, la primera 9&:, se utiliza para abrir un arc(ivo, la segunda 92:, es utilizada para acomodar el puntero interno de un arc(ivo a un valor determinado, y la tercera, 92: se utiliza para leer bytes desde un arc(ivo (ver las man pages de cada una de las funciones para m+s detalles).

#$%ina ; de &&

A(ora iremos me"orando nuestro programa poco a poco y agreg+ndole funcionalidades. or e"emplo las l*neas: if if ( lsee> fd, offset,<LLM+<L@! && offsetF1! ! *error 6errorH6!% result&read fd,buf,31!! && F1!" *error 6errorH6!% exit 1!%

odr*an reemplazarse con: if result&*read fd, buf, 31, offset!! && F1!" *error 6errorH6!% exit 1!%

( y resultar*a lo mismo dado que la funci!n pread toma como cuarto argumento el valor de la posici!n desde la cual se debe de comenzar a leer el arc(ivo, por tanto podemos suprimir la llamada a lseek. /O0A El valor de offset que tome pread() ser+ siempre contando desde el principio del arc(ivo, mientras que la funci!n lseek() podr+ acomodar este para que sea relativo tanto desde el principio, desde el final, como desde la posici!n actual. A(ora podr*amos (acer que lea (asta n caracteres desde el punto que deseemos iniciar la lectura. Tambi$n (aremos que en lugar usar print3(), utilice la llamada 7rite para escribir el mensa"e en pantalla.

#$%ina < de &&

#include #include #include #include #include #include #include #include

<unistd.h> <errno.h> <strin-.h> <stdlib.h> <cty*e.h> <sys)ty*es.h> <sys)stat.h> <fcntl.h>

), continua en *roxima *a-ina... ,) int isIi-it char ,s! " Ghile c & ,s#i$!" if Hisdi-it c!!" *rintf 6errorH: el *arametro 7s no es un numeroH=n6, s!% exit 1!% ( iJJ% ( int main int ar-c , char ,ar-v#$!" int fd% char buf#32$% int result, offset, cuantos% ), che5ueamos 5ue se *asen los ar-umentos necesarios ,) if ar-c < .!" *rintf 63so: 7s <archivo> <nro. de caracter de *artida> = <cuantos caracteres mostrar>=n6, ar-v#0$!% exit 1!% (% ), che5ueamos 5ue el 3er y .to ar-umento sea un numero ,) isIi-it ar-v#2$!% isIi-it ar-v#3$!% offset & atoi ar-v#2$!% cuantos & atoi ar-v#3$!% if cuantos > 31 !" *rintf 6error, sobre*asa el limite del buffer=n6!% exit 1!% ( if fd & o*en ar-v#1$,/+BI/248!! && F1! *error 6errorH6!% if result&*read fd,buf,cuantos,offset!! && F1!" *error 6errorH6!% exit 1!% ( buf#result$ & K=0K% ), Beem*la'o de *rintf 6caracter 7d: 7s=n6,offset,buf!% ,) " char aux#8$% char mensa-e#.8$% strcat mensa-e,6caracter 6!% s*rintf aux,67d6,offset!% strcat mensa-e,aux!% strcat mensa-e,6: 6!% strcat mensa-e,buf!% aux#0$ & K=012K% aux#1$ & 0 % ), *ara adherir el strcat mensa-e,aux!% ,rite 1, mensa-e, strlen mensa-e!!% ( fsync fd!%

=n! ,)

#$%ina * de &&

#omo podemos ver, sustituir a print3() no es una tarea sencilla. Es verdad que esto podr*a (aberse (ec(o de una manera mas !ptima, pero dado que lo que nos compete es comprender y utilizar llamadas al sistema nos conformaremos con este c!digo. Tambi$n agregamos a este e"emplo una llamada a la funci!n 3s4nc, la cual sirve para sincronizar los datos contenidos en los )uffers del sistema asociados a este arc(ivo con los del disco r*gido, o sea, actualizar los contenidos del disco. or ltimo veremos el uso de la llamada al sistema 3stat para determinar el tamaBo de un arc(ivo: int file+si'e int fd! " struct stat *ts% fstat fd,1*ts!% return *ts.st+si'e% ( .a estructura struct stat tiene la forma: struct stat " dev+t st+dev% ino+t st+ino% mode+t st+mode% nlin>+t st+nlin>% uid+t st+uid% -id+t st+-id% dev+t st+rdev% off+t st+si'e% unsi-ned lon- st+bl>si'e% unsi-ned lon- st+bloc>s% time+t st+atime% time+t st+mtime% time+t st+ctime% (% ), ), ), ), ), ), ), ), ), ), ), ), ), device ,) inode ,) *rotection ,) number of hard lin>s ,) user NI of oGner ,) -rou* NI of oGner ,) device ty*e if inode device! ,) total si'e, in bytes ,) bloc>si'e for filesystem N)/ ,) number of bloc>s allocated ,) time of last access ,) time of last modification ,) time of last chan-e ,)

0ra)a=ando con directorios 4 arc6ivos: #omo ya (emos dic(o, una de las tareas m+s importantes del &.'. es la de administrar el sistema de arc(ivos. Todos sabemos que el sistema de arc(ivos se organiza mediante el uso de un tipo particular de arc(ivos, denominados directorios. Estos tienen como particularidad que en lugar de contener datos, contienen a otros arc(ivos o directorios, o m+s bien, contienen los datos para poder (allar a estos. En la secci!n anterior vimos como acceder a los arc(ivos y como obtener informaci!n de ellos ( stat, 3stat, lstat), a(ora veremos como podemos alterar sus atributos y como leer este tipo particular de arc(ivos. &i uno intenta utilizar la funci!n read sobre un arc(ivo que es un directorio, el sistema devolver+ un error, esto se debe a que este tipo de arc(ivos cuenta con una funci!n propia para ser le*do, esta funci!n es readdir, sin embargo esta llamada al sistema esta quedando obsoleta ya que su funci!n (a sido reemplaza por la llamada %etdents. &in embargo, no utilizaremos estas llamadas para leer los directorios, en su lugar usaremos la funci0n que ofrece la librer*a est+ndar de # readdir9: (m+s all+ de que posea el mismo nombre que la llamada al sistema, esta es una funci!n de librer*a que utilizando la llamada al sistema (om!nima brinda la misma funcionalidad). /eamos a(ora como podemos (acer para listar todos los arc(ivos de tipo directorio pertenecientes a un directorio. uede tomar el directorio desde la linea de comandos o, de no pas+rsele ningn par+metro, listar+ los arc(ivos del directorio actual.

#$%ina 9 de &&

#include #include #include #include #include #include

<unistd.h> <sys)ty*es.h> <dirent.h> <errno.h> <sys)stat.h> <strin-.h>

#define O3P<NQL ?. int main int ar-c, char ,,ar-v! " INB ,dd% struct dirent, dir*% struct stat stats% char namebuf#O3P<NQL$% int name+len% if ar-c < 2! -etcGd namebuf, O3P<NQLF1!% else strc*y namebuf, ar-v#1$!% name+len & strlen namebuf!% if ( dd & o&endir namebuf!! && 0! " *error 6Lrror16!% exit 1!%

Ghile dir* & readdir dd!! " namebuf#name+len$ & K=0K% strcat namebuf,6)6!% strcat namebuf, dir*F>d+name!% if stat namebuf,1stats!! " *error 6error26!% exit 2!% ( if <+N<INB stats.st+mode!! *rintf 67s=n6,namebuf!%

( return 0% (

.a primer gran diferencia que vemos aqu* con los e"emplos anteriores es que para abrir el directorio usamos la funci!n opendir(), esta es una funci!n de librer*a, que internamente utiliza la llamada al sistema open, pero que esconde esto a nuestros o"os y que en lugar de retornar un file descriptor nos devuelve un puntero a dato del tipo -1;. #on este puntero invocaremos a la funci!n readdir(), la cual devolver+ un puntero a una estructura dirent, la cual usaremos para conocer que arc(ivos contiene este directorio. .a estructura dirent tiene la siguiente forma: struct dirent " lon- d+ino% off+t d+off% unsi-ned short d+reclen% char d+name #2C;L+;CTJ1$% (

), ), ), ),

nRmero de iFnodos offset res*ecto al *rSximo dirent lon-itud de este dirent nombre de archivo terminado en null!

,) ,) ,) ,)

%sando el campo d*name podemos conocer el nombre de cada arc(ivos que contiene el directorio. .uego, para
#$%ina &0 de &&

saber si el arc(ivo en cuesti!n se trata de un directorio, usamos la funci!n stat. .a macro S*1S213, definida en /usr/include/sys/stat.h, retorna DverdaderoE si el arc(ivo en cuesti!n es un directorio. 'tras macros similares pueden ser consultadas a trav$s de la p+gina del manual de 3stat. 'tras llamadas al sistema, tiles para modificar ciertos aspectos de los arc(ivos, son: c6o7n cambia los datos relacionados con el dueBo de un arc(ivo. c6mod cambio los permisos de acceso a un arc(ivo. rename cambia el nombre de un arc(ivo. Otras llamadas al sistema A(ora listaremos brevemente algunas llamadas al sistema que pueden ser de utilidad para la pr+ctica: %etrlimit y setrlimit Estas llamadas al sistema sirven para establecer tanto como para consultar los valores actuales y m+,imos de los recursos del sistema que el proceso que e"ecuta la llamada consume, o puede llegar a consumir del sistema. uotact Esta llamada sirve para manipular la cantidad de espacio de disco r*gido que un usuario o grupo puede utilizar %etrusa%e &irve para obtener estad*sticas acerca del proceso que efecta la llamada mlock &irve para evitar que un sector de memoria sea guardado en el disco debido al uso de memoria virtual y paginaci!n. nanosleep &irve para dormir un proceso por un tiempo determinado, es sumamente preciso send3ile &irve para copiar en forma !ptima datos de un arc(ivo a otro uname &irve para obtener informaci!n til acerca de la m+quina, el nombre y versi!n del sistema

/ota 3inal &e recomienda fuertemente e"ecutar los programas aqu* e,puestos y proponerse e"ecicios que respondan a modificaciones de los c!digos aqu* escritos.

#$%ina && de &&

S-ar putea să vă placă și