Linux'te execl ile dosya çalıştırma


execl fonksiyonunu çağırdığımız anda parametre olarak verdiğimiz çalıştırılabilir dosya execute edilir ve program bu yeni process'e dönüşür. 


Aşağıda programda process fork edilip child process'i /bin/ls process'ine dönüştürülmektedir.


Çıktılardan istenilen sonuçların elde edildiği görülmektedir.



Linux'te child process oluşturma


Linux'te child process oluşturmak için ilk aşama fork fonksiyonunun çağrılmasıdır. 


 fork çağrıldığı anda processin bir kopyasını oluşturur. Genelde fork exec'le beraber kullanılarak ikinci bir process oluşturmak için kullanılır. Linux sistemlerde process oluşturmanın yolu fork ve ardından exec fonksiyonunu çağırmaktır. fork fonksiyonunun geri dönüş değeri 0'a eşitse child process anlamına gelmektedir. child process'in  bir process id'si bulunmaktadır ve bu process id'si fork fonksiyonunun geri dönüş değeri olan değer değildir.  Bu ikisi karıştırılmamalıdır.



Yukarıdaki basit kodun çıktısı aşağıdaki gibidir. Görüleceği üzere child process'in parent id'si fork işlemi yapılan processin id'si fork işlemi yapılan process'in id'si de bash programının process id'sine eşit olduğu ps -aux ile net bir şekilde incelenebilir.


atexit Fonksiyonu

06:13

Bir program exit yaparken programdan çıkmadan önce çağrılmasını istediğimiz fonksiyonlar varsa bunlar için atexit fonksiyonunu kullanmamız gerekir. Bu fonksiyon parametre olarak aşağıda görüldüğü gibi geri dönüşü void parametre almayan bir fonksiyon adresini istemektedir. Bu fonksiyon istenildiği gibi çağrıldıktan sonra exit yapılırken devreye girer ve belirtilen fonksiyonlar çağrılarak çalıştırılır ve program sonlanır.



Yukarıda görüldüğü gibi foo ve bar foksiyonları doğrudan çağrılmamasına rağmen çalışmış ve program sonlanmıştır. Çalışma sırası stack veri yapısına uygun sırada olmaktadır.

printf fonksiyonunun türevleri [ printf, sprintf, snprintf, fprintf ]

23:17

Program çıktılarını ekrana, dosyaya vb. yerlere yazmak için kullanılan printf, sprintf, snprintf, fprintf fonksiyonlarını kısaca inceleyelim:

printf:


printf formatlı olarak ekrana yazmak için kullanılan bir fonksiyondur. Ortalama herkesin bildiği bir fonksiyondur.

int printf(const char *format, ...);

sprintf:

sprintf ise formatlı olarak bir veri yapısına yazan fonksiyondur.

int sprintf(char *str, const char *format, ...);




snprintf:

snprintf ise sprintf ile benzer biçimde çalışsa da farkı 2. parametre olarak aldığı değer kadar veri yapısına yazmasıdır.

int snprintf(char *str, size_t size, const char *format, ...);




fprintf:


fprintf ise formatlı olarak dosyaya yazan bir fonksiyondur.

int fprintf(FILE *stream, const char *format, ...);




Linux'te C için statik kütüphane oluşturma ve kullanma


Kütüphane genel olarak bir proje grubunun dış dünyada (diğer yazılım proje gruplarının vb.) kullanılması amacıyla oluşturdukları dosyalar için kullanılan kavramdır. Bu kütüphaneler içeriğinde hangi fonksiyonları kullanabileceğimizi belirten yani dış dünyaya sundukları interface' leri bildiren bir header dosyası ve bu interface' lerin nasıl kullanılacağını anlatan bir dokümantasyon ile beraber verilir. Statik ve dinamik olarak iki farklı kütüphane biçimi bulunmaktadır. Statik kütüphane kullanmanın avantajı programınızı tek bir çalıştırılabilir dosya şeklinde dağıtmanızı sağlamasıdır.Kütüphanenin tamamı çalıştırılabilir dosyanın içine gömülmektedir.(stand-alone executable) Diğer taraftan kütüphanenin tamamının programa eklenmesi hafıza israfına yol açmaktadır. Ayrıca statik kütüphanelerin güncellenmesi de pek kolay değildir. Bunun için hem kütüphanenin hem de bunu kullanan programın tekrardan derlenmesi gerekmektedir.

1.Adım:

ar rc <libname.a> <obj1.o> <obj2.o> ...


ar arşiv oluşturma - düzenleme için kullanılan bir komuttur.

2. Adım:

ranlib <libname.a> ile oluşturduğumuz kütüphanenin indekslememizi sağlar. Peki bu ne işe yarar?

kütüphane içinde index oluşturarak erişim hızını arttırma amaçlı kullanılmaktadır.




3. Adım: Kullanma


  •  1. derleme işleminde libmath.h dosyasını bulamadığını söylüyor ki bu konuda haklı standart include dosyalarına baktığı yerlerde bulunmamaktadır. Bu nedenle bakması gereken yeri -I parametresi ile söylememiz gerekmektedir.
  • 2. ve 3. derleme I ile verdik fakat -L ile kütüphaneleri link ederken standart baktığı yerler dışında -L ile verdiğimiz yol ifadesinde belirtilen yere de bakmasını söyledik fakat derlemede gene link hatasıyla karşılaştık. Çünkü kullandığımız kütüphaneyi link etmesi gerektiğini söylemedik. Bunun için -l parametresi ile libmath kütüphanesini de link ederken kullanmasını söylememiz gerekmektedir. -l' ile parametre verirken libmath başındaki lib kelimesini yazmadığımız dikkatinizden kaçmasın. 
  • 4. derlemede sonunda başarılı bir şekilde derleme ve çalıştırma gerçekleştirilmiştir.








Linux'te cURL Kütüphanesinin Kullanılması

12:03 , ,

apt-get install libcurl4-gnutls-dev ile ilgili kütüphanelerin kurulumu yapilir.


Yukarıdaki gibi örnek bir http get isteği için kod yazılır. Derleme işlemi sirasinda linker'a -l parametresi ile curl kütüphanesi ilave edilir. eğer linker libcurl'ü bulamıyorsa bu durumda -L ile curl kütüphanesinin bulunduğu yeri vermemiz gerekebilir.


Derleme işleminin ardindan kod çalıştırılırsa başarılı bir şekilde indirme işmenin gerçekleştirildiği görülür.

gcc derleme parametreleri

11:51

Linux üzerinde kodlama yapıyor ve eclipse gibi IDE'ler kullanmıyorsanız gcc ile komut satırında fazlasıyla iç içe olunması gerekmektedir. Biz de çok kullanılan gcc parametrelerini buradan inceleyelim:


gcc <.c dosyasi>

Verilen dosyadan çalıştırılabilir (hata yoksa) bir dosya oluşturur. Aşağıda görüldüğü gibi a.out adında bir dosya oluşmuştur.


-o parametresi

gcc'nin üreteceği dosyaya isim vermek için bu parametre kullanılır. -o <isim> dediğimizde o isimde bir dosya oluşturulur.


-Wall parametresi

-Wall parametresi derleme sırasında tüm uyarıların ekrana basılmasını sağlar. Daha sağlıklı bir derleme&geliştime için kullanılabilir.


-S parametresi

-S parametresi ise gcc'nin assembly çıktısı üretmesi için kullanılır. -masm ile de assembly syntax'ının nasıl olması gerektiği belirtilir(ilgili kişiler ne anlama geldiğini anlayacaktır). Çıktıları aşağıdaki gibi farklı biçimlerde manipule edebiliriz.


-E parametresi

-E parametresi ile gcc'ye sadece preprocessor işlemi yaptırılabilir.


preprocessor işleminin kod yazılan dosyayı ne kadar büyüttüğü aşağıda görülecektir:


-c parametresi

-c parametresi ile derleme işleminin link edilmeden yapılmasını sağlayabiliriz.


 Oluşan .o dosyasını çalıştırmaya çalıştığımızda aşağıdaki gibi bir hata alırız:


-save-temps parametresi

-save-temps flag'i ile çalıştırılabilir bir dosyanın tüm aşamaları farklı uzantılarda oluşmaktadır.


-v parametresi

çalıştığınız gcc'nin versiyonunu öğrenmek isterseniz -v parametresini yalnız başına kullanılması gerekmektedir.


-v parametresi -ikinci durum-

verbose denilen derleme işlemi sırasında ayrıntılı çıktı üretmemizi sağlayan bir flagtir.


-ansi parametresi

-ansi parametresi ise C89 standarlarına göre derleme yapılmasını sağlar.


-D parametresi

-D parametresi ise preprocessor'e parametre verilmesini sağlar


-Werror parametresi

Werror tüm uyarıları error kabul eder ve derleme işleminde uyarı varsa bu nedenle derleme başarısız olmaktadır. Uyarısız(!) kodlama için kullnılır.


-l parametresi

l parametresi ile ise linker' a ek kütüphaneler parametre olarak verilebilmektedir. -l ile kütüphane ismini verirken dosya isminin başındaki lib'in kaldırıldığına dikkat edilmeli. –L seçeneği ile gcc'ye kütüphaneleri ararken hangi dizinlere bakacağı bildirilir.


-I parametresi

I parametresi ile preprocessor'e ek header dosyaların yeri verilmektedir. Header dosyalar genel olarak /usr/include içindedir. Eğer bu başlık dosyaları farklı bir yerde ise, bulundukları yerin belirtilmesi için (-I) parametresi ile yeri gösterilmelidir.

-@ parametresi

Yukarıda öğrendiğimiz tüm derleme parametrelerini bir dosyaya yazıp bunu @ile parametre olarak verebiliriz.


C'de multi solution projelerde visual studio ayarları

11:38 ,

C veya C++ projelerinde birden fazla projeyi aynı anda yönetmek bir projenin çiktisini .lib yapmak ve diğer projenin bu .lib'i kullanması gibi senaryolar yazilim proje dünyasında sık karşılaşılan durumlarıdır. Visual Studio yardımıyla biz de temel düzeyde bir örnek oluşturalım. Bir tane .lib üreten proje bir tane de bu .lib 'i kullanan projemiz olsun.



yapmamız gereken iki ayar mevcuttur. ilk olarak oluşturduğumuz kullanan tarafta add new reference kısmına .lib üreten projemizi eklemek


ardından .h dosyasini kullanan tarafa eklemek yeterli olacaktır.



 ardından funcpool.c 'de Karesi fonksiyonunda yaptiğimiz bir değişiklik ardından projerler derlendiğinde otomatik olarak güncel versiyon üzerinden çalıştığı görülecektir.


if deyimi ile ilgili tüyolar

10:37

  • if deyimi yazılırken if’in içinde birden fazla kontrol yapılacaksa if(exp1 && exp2 && exp3 … gibi durumlarda) başa en az maliyetli olan konur ki çalışma anında kontrol maliyeti düşsün ya da olumsuz olma ihtimali yüksek olan varsa başa gene bu ifade konulur ki maliyet açısından avantajlı çalışabilsin.
  • Bütün deyimler basit deyim ise virgül operatörü kullanılarak fazlalıklar elenebilir.

image
  • if(Foo()) ifadesinde Foo fonksiyonu geriye bir şey döndürmüyorsa logic true olacaktır hata vermeyecektir ve if ifadesinin içi her zaman çalışacaktır.
  • C’de redundancy kavramı fazladan ,fuzuli kod yazma anlamına gelmektedir. C’de bir kodu yazmadan da oluyorsa o kodu yazmamak genellikle doğru olacaktır. Mesela
image

olarak ta yazabiliriz. Burada görüldüğü gibi else ifadesine gerek yoktur.

image

ifadesi aslında y=x anlamına gelmekedir.

image

  ifadesi aslında z=y==x ifadesiyle aynı çalışacaktır.

image

Yukarıdaki else hangi if’e aittir. Bu else ingilizcede dangling else denir. Ve C ‘de bu else içteki if’e aittir.

  • if else veya switch-case’lerde sıralama yapılırken olma olasılığı yüksek olan ifadeler yukarı yazılır ki fazla kontrolden sakınılmış olsun.


C'de memory alanlarının kopyalanması

11:37
Aşağıda anlatacağım C fonksiyonları bir memory bloğundaki verileri başka bir memory bloğuna kopyalamak için kullanılmaktadır.

memcpy:

memcpy bir memory bloğundaki bilgiyi diğer memory bloğuna fonksiyona geçirilen 3. parametrede geçen değer kadar byte kopyalaması yapar. memory overlap sorununa karşı korumasız durumdadır. Yani source ve destination memory alanlarında üst üste gelme durumu varsa fonksiyon istenilen çıktıları üretememektedir.


Aşağıda örnek bir kod ve çalışması görülmektedir.



 Aşağıda 24 byte kopyalama yapılmıştır. Böylece Null karakter kopyalaması da ptrDest dizisine kopyalanmıştır.





memccpy:

memccpy memcpy ile benzer çalışmakta 3. ve 4. parametreler  ise 3. parametrede karakter olarak gönderilen değerle karşılaşıncaya kadar kopyalama yapar bulamazsa 4. parametre verilen boyuta kadar kopyalama yapar.


  Aşağıdaki örnekte B harfini gönderene kadar ya da maksimum 24 byte kopyalama yapar.



mempcpy:

mempcpy fonksiyonu memcpy ile benzer çalışmakta yalnızca geri dönüş değeri olarak kopyalama işlemi yaptıktan sonra (hedef alana) bir sonraki adresi geri dönüş olarak verir. Bu fonksiyon daha çok birden fazla hafıza alanından birleştirme yaparken kullanılır.


 Örnek bir kullanım aşağıdaki gibidir:





memmove:

memmove memcpy ile benzer yapıdadır. Fakat memory overlap'e karşı önce kaynağı temp bir alana kopyalar ardından hedef olarak verilen yere temp alandan kopyalama yapar. Daha güvenli bir kopyalama sağlar ama memcpy 'ye göre daha yavaştır.


 Örnek bir memmove kullanımı aşağıdaki gibidir:




 Aşağıda memory overlap durumuna bir örnek verilmiştir.





strcpy:

strcpy fonksiyonu ise hedef ve kaynak parametrelerini alır hedefte verilen string'i null karakter görene kadar hedef alana kopyalamaya çalışır. Ya da üçüncü parametre olarak verilen byte kadar kopyalama yapar. Eğer verilen uzunluk dahilinde string içinde Null karakter yoksa kopyalama sonrası hedef alanda sonunda null karakter olmayan bir string olacaktır.


string kopyalama işlemlerinde daha çok strcpy fonksiyonu kullanılmaktadır. Örnek bir uygulama aşağıdaki gibidir:







bcopy:

deprecated olmuş bir fonksiyondur. memcpy ile benze çalışmaktadır. Memory overlap durumuna karşı korumalıdır.


 Örnek bir uygulama: