C İle Sistem Çağrıları Yapmak

C ile sistem cagrisiBazı C programcılarının Pardus’ta program yazarken kendisini kötü hissettiğini ve bu yüzden eski sistemlerine geri döndüklerini üzülerek görüyoruz. Ülkemizdeki Türkçe kaynak eksikliği yüzünden Linux ve dolayısıyla Pardus çok değerli kullanıcı ve programcı arkadaşları kaybedebiliyor. Son zamanlarda Özgürlükİçin’in müthiş katkılarıyla bu eksiklik kısmen giderilmiş olsa da, belgelendirme halen istenilen düzeyde değil. Ben de programcı arkadaşları düşünerek, Pardus’ta daha usta işi C programları nasıl yazacaklarına dair ufak bir makale hazırlamak istedim.

Bu sayımızda hep birlikte C dilini kullanarak Pardus’ta sistem çağrılarını nasıl yapacağımızı öğreneceğiz. Makalenin seviyesi, C dilinin temellerini bilen ve herhangi bir işletim sistemindeki sistem çağrısının ne anlama geldiğini bilenleri hedef almıştır. Bu yüzden C ve Linux’u iyi bilen arkadaşlara makale çok yavan gelebilir. Özellikle C ve herhangi bir işletim sistemini iyi bilen programcı arkadaşlarımızın ilgisini çekeceğini düşündüğüm bu konu, sizlerden gelecek istekler doğrultusunda bir seri makale haline de gelebilir. Makale hakkındaki görüş ve önerilerinizi forumlarımızda dile getirebilirsiniz.

Lafı fazla uzatmadan hemen konuya girelim; Sistem çağrıları Linux Kernel’i tarafından bizlere servis edilmektedir. C programları sistem çağrıları yapabilmek için genellikle libc’de tanımlanmış fonksiyonları kullanırlar. Sistem çağrısı yaptığınızda Kernel’in doğrudan işi yaptığını görürsünüz. Bu durum size hız kazandıracaktır. Yalnız burada unutulmaması gereken konu, sistem çağrılarını bilinçsiz kullanmamanız gerektiğidir. Uygun olmayan kullanımlar hem sistemin hızını düşürecek hem de zaman zaman kilitlenmesine sebep olacaktır. Tüm sistem çağrıları aslında numaralandırılmış fonksiyonlardır ve <syscall.h> veya <unistd.h> başlık dosyalarında tanımlanmıştır. Siz dilerseniz tüm sistem çağrılarını syscall(Çağrı No) fonksiyonu ile yapabilirsiniz ancak hafızanızda tüm sistem çağrılarının numaralarını tutamayacağınız aşikâr. Bu durumda C dili için oluşturulmuş <sys/statfs.h>, <sys/utsname.h> gibi birçok başlık dosyası (Header File) imdadımıza yetişir. Bu dosyaların içerisinde sistem çağrılarına akılda kalıcı fonksiyon isimleri verilmekte ve bu sayede sayıları aklımızda tutmamız gerekmemektedir. Herhangi bir sistem çağrısı yapıldığında 0x80 numaralı kesme (Interrupt) devreye girer ve kontrol Kernel’e geçer.

Sistem çağrılarının tablosu Linux Kernel kaynak dosyasında tanımlanmıştır “arch/i386/kernel/entry.S” Sistem çağrıları hakkında detaylı bilgilere kılavuz sayfalarından (man pages) ulaşabilirsiniz. Biz aşağıdaki örnek sistem çağrılarını KDevelop ile yaptık. Eğer sisteminizde KDevelop yüklü değilse Paket Yöneticisi’ni kullanarak sisteminize kurun. Elbette sadece KDevelop kullanmak zorunda değilsiniz. Dilediğiniz tüm C derleyici ve IDE’sini ve hatta en basit editörleri dahi kullanabilirsiniz. Benim tavsiyem, yeni başlayan arkadaşlar için KDevelop gibi kullanımı basit ve takıldığınızda size yardım edebilecek bir IDE olmasıdır.

Şimdi örnek programımızı inceleyelim;

#include <syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/statfs.h>
int main(void)
{
  long ID1, ID2, ID3, ID4, ID5;
  char *Mevcut_Klasor;
  struct utsname sistem_bilgisi[1];
struct statfs dosya_sistemi[1];

/* <unistd.h> içinde tanımlanan ve bu programın çalıştığında kullandığı
PID numarasını öğrenen getpid() fonksiyonunu çağırıyoruz */


ID1 = getpid();
 printf (“İşlem numarası --> getpid() = %ld\n\n”, ID1);

/* <unistd.h> içinde tanımlanan ve bu programın çalıştığında kullandığı
işlem grup numarasını öğrenen getpgrp() fonksiyonunu çağırıyoruz */


ID2 = getpgrp();
 printf (“İşlem grup numarası --> getpgrp() = %ld\n\n”, ID2);

/* <unistd.h> içinde tanımlanan ve bu programın hangi klasör içerisinde
çalıştığını öğrenen get_current_dir_name() fonksiyonunu çağırıyoruz */


Mevcut_Klasor = get_current_dir_name();
printf (“Mevcut klasör --> get_current_dir_name() = %s\n\n”, Mevcut_Klasor);

/* <sys/utsname.h> içinde tanımlanan ve bu programın çalıştığı
işletim sistemi hakkında bilgi alan uname() fonksiyonunu çağırıyoruz */


ID3 = uname(sistem_bilgisi);
printf(“Sistem bilgisi --> uname()\n”);
if(ID3==0)
 {
 printf (“ Sistem adı --> %s\n”,sistem_bilgisi->sysname);
 printf (“ Node adı --> %s\n”,sistem_bilgisi->nodename);
 printf (“ Uyarlama --> %s\n”,sistem_bilgisi->release);
 printf (“ Sürüm --> %s\n”,sistem_bilgisi->version);
 printf (“ Makina --> %s\n\n”,sistem_bilgisi->machine);
 } else printf(“Hata oluştu. %lx\n\n”,ID3);


/* <sys/statfs.h> içinde tanımlanan ve bu programın çalıştığı işletim
sistemindeki mevcut dosya sistemi hakkında bilgi alan statfs()
fonksiyonunu çağırıyoruz */

ID4 = statfs(Mevcut_Klasor,dosya_sistemi);
printf(“Dosya sistemi --> statfs()\n”);
if(ID4==0)
 {
 printf (“Dosya sistemi tipi-->%lx\n”,dosya_sistemi->f_type);
 printf (“İdeal blok boyutu-->%lx\n”,dosya_sistemi->f_bsize);
 printf (“Toplam veri bloğu sayısı-->%lx\n”,dosya_sistemi->f_blocks);
 printf (“Boş blok sayısı-->%lx\n”,dosya_sistemi->f_bfree);
 printf (“Faydalı boş bloklar-->%lx\n”,dosya_sistemi->f_bavail);
 printf (“Toplam dosya düğümü sayısı-->%lx\n”,dosya_sistemi->f_files);
 printf (“Boş dosya düğümü sayısı-->%lx\n”,dosya_sistemi->f_ffree);
 printf (“Tanım numarası-->%lx\n”,dosya_sistemi->f_fsid);
 printf (“Maks. dosya adı uzunluğu-->%lx\n\n”,dosya_sistemi->f_namelen);

} else printf(“Hata oluştu. %lx\n\n”,ID4);
 return(0);
}

Eğer kodlamada bir hata yapmadıysanız ekran çıktınız aşağıdakine benzer olacaktır.

C ile sistem cagrisi

7 yorum .

yazdır
Son güncelleme: 02 Haziran 2009