Fuse


Fuse merupakan sebuah kerangka sistem berkas pada area pengguna. terdiri dari sebuah modul kernel (fuse.ko), sebuah pustaka pada area pengguna, dan sebuah utilitas untuk melakukan proses mount (fusermount). Salah satu keistimewaan FUSE yang paling utama adalah diizikannya proses mount oleh pengguna biasa yang aman. hal ini memberikan kemungkinan baru untuk menggunakan sistem berkas. salah satu contoh adalah sshfs, sebuah sistem berkas yang beroperasi pada tingkatan jaringan yang menggunakan protokol sftp. Semenjak proses mount() merupakan operasi yang membutuhkan pengguna yang memiliki hak khusus, sebuah program pembantu (fusermount) dibutuhkan untuk melakukannya yang terpasang dengan tingkatan pengguna root. Implikasi dengan menyediakan operasi mount untuk pengguna biasa adalah pemilik operasi mount tidak dapat menggunakan kemampuannya untuk melakukan hal-hal yang dapat membahayakan sistem. Syarat-syarat yang harus dipenuhi seiring dengan adanya keadaan tersebut adalah sebagai berikut :

Pemilik proses mount seharusnya tidak dapat melakukan operasi untuk meninggkatkan hak aksesnya dengan bantuan sistem berkas yang dimount
Pemilik proses mount seharusnya tidak dapat melakukan akses yang terlarang untuk mendapatkan informasi dari pengguna lainnya dan proses-proses yang dimiliki oleh pengguna super (root)
Pemilik proses mount seharusnya tidak dapat mengakibatkan perbuatan yang tidak diinginkan proses pengguna lain ataupun proses-proses yang dimiliki oleh pengguna super.
Meskipun demikian keadaan yang tidak diinginkan berkenaan dengan keistimewaan yang dimiliki oleh FUSE masih dapat terjadi dengan cara sebagai berikut:

Pemilik proses mount dapat meningkatkan hak aksesnya dengan cara :
Membuat sebuah sistem berkas yang berisikan sebuah berkas alat, yang kemudian membukanya.
Membuat sebuah sistem berkas yang berisikan sebuah aplikasi suid ataupun gid, yang kemudian mengeksekusinya.

Membuat fuse sendiri :

#ifdef linux
/* For pread()/pwrite() */
#define _XOPEN_SOURCE 500
#endif

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <sys/statfs.h>

static const char *dirpath = "/home/wicakson/Downloads";

char alamat[1000];

static int xmp_getattr(const char *path, struct stat *stbuf)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = lstat(fpath, stbuf);
if (res == -1)
return -errno;

return 0;
}

static int xmp_readlink(const char *path, char *buf, size_t size)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);

res = readlink(fpath, buf, size - 1);
if (res == -1)
return -errno; 

buf[res] = '\0';
return 0;

}


static int xmp_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
    DIR *dp;
    struct dirent *de;
    int res = 0;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    dp = opendir(fpath);
    if(dp == NULL)
        return -errno;

    while((de = readdir(dp)) != NULL) {
        res = filler(h, de->d_name, de->d_type);
        if(res != 0)
            break;
    }

    closedir(dp);
    return res;
}

static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
{
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = mknod(fpath, mode, rdev);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_mkdir(const char *path, mode_t mode)
{
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = mkdir(fpath, mode);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_unlink(const char *path)
{
    int res,res2;
    char fpath[1000], temp[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    strcpy(temp,fpath);
    res = unlink(fpath);
    do
{
sprintf(temp, "%s-copy", fpath);
res2=unlink(temp);
}
    while(res2!=-1);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_rmdir(const char *path)
{
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = rmdir(fpath);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_symlink(const char *from, const char *to)
{
    int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);

    res = symlink(from, to);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_rename(const char *from, const char *to)
{
     int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);
res = rename(from1, to1);
if (res == -1)
return -errno;

return 0;
}

static int xmp_link(const char *from, const char *to)
{
    int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);

    res = link(from, to);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_chmod(const char *path, mode_t mode)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = chmod(fpath, mode);
    if(res == -1)
        return -errno;
    
    return 0;
}

static int xmp_chown(const char *path, uid_t uid, gid_t gid)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = lchown(fpath, uid, gid);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_truncate(const char *path, off_t size)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    
    res = truncate(fpath, size);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_utime(const char *path, struct utimbuf *buf)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    
    res = utime(fpath, buf);
    if(res == -1)
        return -errno;

    return 0;
}


static int xmp_open(const char *path, int flags)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    
    res = open(fpath, flags);
    if(res == -1) 
        return -errno;

    close(res);
    return 0;
}

static int xmp_read(const char *path, char *buf, size_t size, off_t offset)
{
    int fd;
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);
strcpy(alamat,path);

    fd = open(fpath, O_RDONLY);
    if(fd == -1)
        return -errno;

    res = pread(fd, buf, size, offset);
    if(res == -1)
        res = -errno;
    
    close(fd);
    return res;
}

\static int xmp_write(const char *path, const char *buf, size_t size,
                     off_t offset)
{
    int fd;
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    fd = open(fpath, O_WRONLY);
char temp1[1000], temp2[1000], kata[1000];
sprintf(temp1, "%s%s", dirpath, alamat);
sprintf(temp2, "%s-copy", temp1);
FILE* a; FILE* b;
a = fopen(temp2,"w+");
b = fopen(temp1, "a+");
while(fgets(kata,1000,b)!=NULL)
{
fprintf(a,"%s",kata);
}
fclose(a);
fclose(b);
    if(fd == -1)
        return -errno;

    res = pwrite(fd, buf, size, offset);
    if(res == -1)
        res = -errno;
    
    close(fd);
    return res;
}

static int xmp_release(const char *path, int flags)
{
    /* Just a stub.  This method is optional and can safely be left
       unimplemented */

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    (void) fpath;
    (void) flags;
    return 0;
}

static int xmp_fsync(const char *path, int isdatasync)
{
    /* Just a stub.  This method is optional and can safely be left
       unimplemented */

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    (void) fpath;
    (void) isdatasync;
    return 0;
}

static struct fuse_operations xmp_oper = {
    .getattr = xmp_getattr, //get file atribut
    .readlink = xmp_readlink, 
    .getdir = xmp_getdir, //get directory
    .mknod = xmp_mknod, //create a file node
    .mkdir = xmp_mkdir, //create directory
    .symlink = xmp_symlink, //create a symbolic link
    .unlink = xmp_unlink, //remove file
    .rmdir = xmp_rmdir, //remove directory
    .rename = xmp_rename, 
    .link = xmp_link, //create a link
    .chmod = xmp_chmod, //change the owner and group of a file
    .chown = xmp_chown, // sama
    .truncate = xmp_truncate, //change the size of a file
    .utime = xmp_utime, //change the access and modification times of a file
    .open = xmp_open,
    .read = xmp_read,
    .write = xmp_write,
    .release = xmp_release, //release directory
    .fsync = xmp_fsync //synchronize file contents
    
};

int main(int argc, char *argv[])
{
    fuse_main(argc, argv, &xmp_oper);
    return 0;
}

0 komentar:

Membuat Quiz Menggunakan Thread pada Bahasa C

Bagaimana membuat quiz dengan kita dapat menentukan waktu pengerjaan tiap soal? jadi jika tidak dapat menjawab soal dalam waktu yang ditentukan, maka akan beralih ke soal berikutnya dan dianggap tidak menjawab soal/salah. Setelah itu jawaban akan dicatat dalam sebuah teks dan hasil quiz akan ditampilkan di layar.

Membuat quiz yang seperti dijelaskan di atas bisa menggunakan thread. Dalam post ini saya menggunakan bahasa c dalam membuat program quiz tersebut.

Kode format soal quiz seperti berikut :

[jumlah_soal]
[waktu_pengerjaan] [kunci_jawaban]
[soal


]
* //soal diakhiri dengan tanda bintang ini '*'
[waktu_pengerjaan] [kunci_jawaban]
... //dan seterusnya

Contoh soal quiz :
------------------------------------------------------------------------------------
4
5 b
Berapakah 1 menit dalam detik?
a. 30
b. 60
c. 15
d. 25
*
4 c
Hewan yang bukan berkaki empat?
a. Kucing
b. Anjing
c. Ayam
d. Sapi
*
6 a
Ibukota Indonesia?
a. Jakarta
b. Jambi
c. Maluku
d. Surabaya
*
3 d
4 + 4 =
a. 2
b. 4
c. 6
d. 8
*
------------------------------------------------------------------------------------
Kode main.c :
------------------------------------------------------------------------------------
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

int wak[10],nos[10];
char jaw[10];

char soal[10][255];

int flag[10];

pthread_t thread1, thread2;

FILE *rit, *krit, *krit2;

char jabt;
int noso=1;

int nilai=0, count;

void *input(int *no)
{
    int a = *( (int *) no);
    system("clear");
    printf("%d. %s",noso, soal[a]);
    printf("Jawab : ");
    scanf("%c", &jabt);
    getchar();
    pthread_cancel(thread1);
}

void *waktu(int *no)
{
    int a = *( (int *) no);
    while(wak[a]>0)
    {
        count++;
        sleep(1);
        if(count==wak[a])
        {
            pthread_cancel(thread2);
            pthread_cancel(thread1);
        }
    }
}

void cek(int no)
{
    if (jabt==jaw[no])
    {
        fprintf(krit,"%d %c benar - waktu : %d\n", no+1, jabt, count);
        nilai+=10;
    }
    else
        fprintf(krit,"%d %c salah - waktu : %d\n", no+1, jabt, count);
}

int main()
{
    krit=fopen("/home/wicakson/Documents/shift3/hasil.txt","w+");
    rit=fopen("/home/wicakson/Documents/shift3/soal.txt","r");
    int no=0, jumlah, i;
    fscanf(rit, "%d", &jumlah);
    for(no=0;no<jumlah;no++)
    {
        flag[no]=0;
        fscanf(rit,"%d", &wak[no]);
        fgetc(rit);
        fscanf(rit,"%c", &jaw[no]);
        fgetc(rit);
        i=0;
        fscanf(rit, "%c", &soal[no][i]);
        while(soal[no][i]!='*')
        {
            i++;
            fscanf(rit, "%c", &soal[no][i]);
        }
        soal[no][i]='\n';
    }
    for(no=0;no<jumlah;no++) puts(soal[no]);
    int sek, k=jumlah;
    while (k)
    {
        srand(time(NULL));
        sek = rand() % jumlah ;
        if(flag[sek]==0)
        {
            count=0;
            pthread_create(&thread2, NULL, (void *) &input, (void *) &sek);
            pthread_create(&thread1, NULL, (void *) &waktu, (void *) &sek);
            pthread_join(thread1, NULL);           
            pthread_join(thread2, NULL);
            cek(sek);
            pthread_cancel(thread1);
            k--;
            noso++;
            flag[sek]= 1;
        }
        jabt='\0';   
    }

    fprintf(krit,"\nNilai Anda: %d\n",nilai);
    char str[255];
    sprintf(str, "zenity --info --title=\"Selamat\" --text=\"Nilai Anda: %d\"", nilai);
    system(str);
    return 0;   
}
------------------------------------------------------------------------------------
Penjelasan beberapa fungsi dalam kode tersebut :
1.
2.
3.
4.
krit=fopen("/home/wicakson/Documents/shift3/hasil.txt","w+");
dan beberapa fungsi fprintf akan menghasilkan hasil.txt yang menampilkan hasil pengerjaan seseorang jika telah menjalankan quiz tersebut.

Contoh hasil.txt
------------------------------------------------------------------------------------
4 \00 salah - waktu : 4
3 \00 salah - waktu : 7
1 b benar - waktu : 3
2 b salah - waktu : 2
Nilai Anda: 10
------------------------------------------------------------------------------------
Contoh di atas terjadi jika anda tidak menjawab pada soal pertama dan kedua yang muncul, lalu anda menjawab b pada soal ketiga saat detik ke-3 dan menjawab b pada soal keempat saat detik ke-2.
Karena soal pada quiz ini dirandom pengeluarannya, maka setiap anda menjalankan program, akan berbeda urutan soalnya.
2 b salah - waktu : 2
[kode_soal] [input_jawaban]  [benar/salah] - waktu : [waktu_pengerjaan]
Jika anda tidak menjawab sama sekali seperti pada contoh di bawah ini
3 \00 salah - waktu : 7
maka waktu akan diset menjadi [waktu_pengerjaan+1]

1 komentar:

Thread

Apa itu thread ? thread merupakan intruksi yang dijalankan. Lalu, apa bedanya dengan proses ?


Gambar di atas menunjukkan tingkatan kombinasi proses dan thread yang dimiliki oleh sebuah komputer dari masa ke masa, contoh dari masing masing kombinasi adalah:
1. One Process One Thread -> MS DOS
2. One Process Multi Threads -> Java Virtual Machine
3. Multi Processes One Thread -> UNIX Family
4. Multi Processes Multi threads -> Hampir seluruh OS saat ini


PROSES VS THREAD
Proses:
- Memiliki ruang/space sendiri di memori untuk menampung process image
- Tidak dapat mengakses ruang lain di memori yang menjadi milik proses lain

Thread:
Dalam sebuah thread pada sebuah proses terdapat :
- Thread state
- Saved Thread Context saat tidak berjalan (Individual Program Counter)
- Execution Stack
- Local Variables
- Akses ke memory dan resource yang dimiliki oleh prosesnya
 
KEUNTUNGAN THREAD
1. Waktu pembuatan yang lebih cepat
2. Waktu pemberhentian yang lebih cepat
3. Waktu pergantian antar thread lebih cepat daripada antar proses
4. Komunikasi antar thread lebih efisien

PENGGUNAAN THREAD
a. Foreground & Background Work
b. Asynchronous Processing
c. Speed of Execution

THREAD STATE
Spawn - Thread muncul/dibuat oleh proses/OS
Block
 - Thread menunggu sebuah event
Unblock
 - Ketika event yang ditunggu oleh thread muncul
Finish
 - Thread selesai
 - Register context dan stack yang digunakan dibebaskan.

Jenis Implementasi Thread





USER LEVEL THREAD
Ciri-ciri :
- Kernel tidak mengetahui keberadaan thread
- Thread management dilakukan oleh aplikasi user level/library
Keuntungan :
- Thread switching tidak membutuhkan kernel mode privileges
- Dapat berjalan di berbagai OS
Kerugian :
- Satu  thread blocked, thread lain pada proses yang sama juga blocked
- Dua thread pada proses yang sama tidak dapat berjalan bersamaan pada dua prosesor

KERNEL LEVEL THREAD
Ciri-ciri :
 - Thread management dilakukan oleh kernel
Keuntungan :
- Thread pada proses yang sama dapat dijalankan pada prosesor yang berbeda
- Kernel routines juga dapat multithreaded
Kerugian :
- Thread switching antar proses yang sama tetap melibatkan kernel
- Dapat memperlambat

HYBRID LEVEL THREAD
Ciri-ciri :
- Ada sejumlah kernel level thread yang dipetakan ke sejumlah user level thread
- Pembuatan thread, scheduling, sinkronisasi dilakukan di user space.

Fakta menarik menengai thread :

  • Sebenarnya, yang berjalan pada prosesor adalah thread
  • Program mempunyai baris instruksi yang sangat banyak dijalankan secara sekuensial.
  • 1 proses merupakan sekumpulan thread, minimal 1 thread
  • 1 thread sekumpulan instruksi
  • Mozzila Firefox merupakan contoh multithread
  • Google Chrome merupakan contoh multiproses
  • Multi Process dan multi thread -> Apache
Mozzilla firefox dan google chrome merupakan salah satu web browser terbesar, tapi yang satu mengguna muultithread, yang satunya multi proses, apa dampaknya ?

Thread lebih cepat dibanding dengan proses. Tapi dalam beberapa thread pada satu proses, ada kemungkinan mereka saling berinteraksi, dan inilah yang membuat sistem keamanannya tidak seperti multiproses.

Ada juga beberapa aplikasi yang menggunakan multiproses dan multithread sekaligus, sehingga kecepatannya ramah, dan aman pada level tertentu 

0 komentar:

Socket Programming dengan bahasa C pada Linux


Socket
adalah interface pada jaringan yang menjadi titik komunikasi antarmesin pada Internet Protocol, dan tentunya tanpa komunikasi ini, tidak akan ada pertukaran data dan informasi jaringan.
Socket terdiri dari elemen-elemen utama sebagai berikut:

  • Protokol.
  • Local IP.
  • Local Port.
  • Remote IP.
  • Remote Port.

Komunikasi socket jaringan memang tidak mengenal lelah, pertukaran data terjadi terus-menerus dan memegang peranan vital.
Bayangkan sebuah server game online yang berkomunikasi tanpa henti, dimainkan oleh entah berapa banyak client yang tersebar. Ini merupakan salah satu contoh aplikasi dari sekian banyak aplikasi yang menggunakan socket jaringan untuk saling berkomunikasi dan bertukar data.

1. Membuat socket

Hal pertama ini harus dilakukan adalah membuat soketFungsi socket melakukan hal ini.
Berikut adalah contoh kode:

#include<stdio.h>
#include<sys/socket.h> 

int main(int argc , char *argv[])
{
 int socket_desc;
 socket_desc = socket(AF_INET , SOCK_STREAM , 0);
 
 if (socket_desc == -1)
 {
  printf("Could not create socket");
 }
 
 return 0;
}

2. Hubungkan socket ke server
 

Yang kita perlukan ada 2 hal, yaitu alamat ip dan nomor port untuk menyambung ke.

Untuk menyambung ke server jauh yang perlu kita lakukan beberapa halPertama adalah untuk menciptakan struktur sockaddr_in dengan nilai-nilai yang tepat.

Berikut contoh kodenya:

// IPv4 AF_INET sockets:
struct sockaddr_in
{
    short            sin_family;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // see struct in_addr, below
};

sockaddr_in memiliki anggota disebut sin_addr jenis in_addr yang memiliki s_addr yang tidak lain adalah sebuah panjangIni berisi alamat IP dalam format lama.

Fungsi inet_addr adalah fungsi yang sangat berguna untuk mengkonversi alamat IP ke format lama.

Berikut contoh kodenya:

server.sin_addr.s_addr = inet_addr ("10.42.0.1");

Jadi, Anda perlu tahu alamat IP dari server jauh Anda hubungi. 

Hal terakhir yang dibutuhkan adalah fungsi connectPerlu soket dan struktur sockaddr untuk menyambung ke.

Berikut adalah contoh kode:
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])
{
 int socket_desc;
 struct sockaddr_in server;
 
 //Create socket
 socket_desc = socket(AF_INET , SOCK_STREAM , 0);
 if (socket_desc == -1)
 {
  printf("Could not create socket");
 }
  
 server.sin_addr.s_addr = inet_addr("10.42.0.1");
 server.sin_family = AF_INET;
 server.sin_port = htons(8080);

 //Connect to remote server
 if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)
 {
  puts("connect error");
  return 1;
 }
 
 puts("Connected");
 return 0;
}

Berikut adalah kode client socket

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h> 

int main(int argc, char *argv[])
{
    int sockfd = 0, n = 0;
    char recvBuff[1024];
    struct sockaddr_in serv_addr; 

    if(argc != 2)
    {
        printf("\n Usage: %s <ip of server> \n",argv[0]);
        return 1;
    } 

    memset(recvBuff, '0',sizeof(recvBuff));
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Error : Could not create socket \n");
        return 1;
    } 

    memset(&serv_addr, '0', sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(5000); 

    if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
    {
        printf("\n inet_pton error occured\n");
        return 1;
    } 

    if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
       printf("\n Error : Connect Failed \n");
       return 1;
    } 

    while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
    {
        recvBuff[n] = 0;
        if(fputs(recvBuff, stdout) == EOF)
        {
            printf("\n Error : Fputs error\n");
        }
    } 

    if(n < 0)
    {
        printf("\n Read error \n");
    } 

    return 0;
}
Berikut adalaj kode server socket

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h> 

int main(int argc, char *argv[])
{
    int listenfd = 0, connfd = 0;
    struct sockaddr_in serv_addr; 

    char sendBuff[1025];
    time_t ticks; 

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(&serv_addr, '0', sizeof(serv_addr));
    memset(sendBuff, '0', sizeof(sendBuff)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(5000); 

    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 

    listen(listenfd, 10); 

    while(1)
    {
        connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 

        ticks = time(NULL);
        snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
        write(connfd, sendBuff, strlen(sendBuff)); 

        close(connfd);
        sleep(1);
     }
}

1 komentar:

IPC -> Pipe




IPC (Inter-Process Communication)
adalah komunikasi antar proses untuk mengirim data dari satu proses ke proses yang lain, baik antar proses dalam satu komputer maupun proses-proses dalam komputer yang berbeda. Salah satu metode IPC adalah 'pipe'.

Pipe
merupakan komunikasi sekuensial antar proses yang saling terelasi, namun pipe memiliki kelemahan yaitu hanya bisa digunakan untuk komunikasi antar proses yang saling berhubungan, dan komunikasinya yang dilakukan adalah secara sekuensial. Urutan informasi yang ada dalam sebuah pipe ada yang mirip dengan antrian queue. Jika komunikasi yang diinginkan adalah komunikasi dua arah maka kita harus membuat dua pipe, karena sebuah pipe hanya bisa digunakan untuk komunikasi satu arah saja. 

Ada 2 jenis pipe, yaitu Named Pipe dan Unnamed Pipe.
Namun metode pipe yang sering digunakan adalah named pipe. Keuntungan named pipe adalah kemampuan untuk mengkomunikasikan dua proses yang dimulai secara independent, dimana salah satu proses tidak fork off sebuah proses baru. 

Named pipe bisa juga disebut FIFO karena prinsip kerjanya FIFO. Data yang pertama kali ditulis di pipe adalah data yang pertama dibaca.  Named pipe digunakan untuk 2 proses yang berjalan sendiri-sendiri dan hanya bisa digunakan pada proses-proses yang menggunakan filesystem yang sama. Secara umum, named pipe yaitu metode yang menggunakan file bertipe pipe file yang diciptakan terlebih dahulu oleh salah satu proses dengan menggunakan mkfifo, kemudian proses yang lain membacanya.

Berikut adalah langkah-langkah membuat named pipe :

Write Process :

1. Deklarasi variabel

Variabel pertama bertype char pointer (char *fifo), di mana variabel fifo tersebut berisi lokasi yang akan digunakan untuk membuat file pipe, misal lokasinya adalah "/tmp/fifo/". Maka deklarasinya adalah :

               char *fifo = "/tmp/fifo/";


Variabel kedua adalah variabel bertype integer yang akan digunaka untuk membuka file pipe tadi (int fd) dan juga variabel array of integer untuk ditulis ke dalam file pipe tersebut (arr[100]). Maka deklarasinya adalah :

               int fd,arr[100];

2. Membuat file pipe

File pipe bisa dibuat melalui perintah mkfifo, di mana salah satu parameternya adalah 0666, yaitu menandakan bahwa file pipe tersebut bisa di read dan write.

               mkfifo(fifo,0666);

3. Membuka file pipe
     File pipe yang tadi telah kita buat kemudian dibuka dengan menggunakan perintah "open", lalu dimasukkan ke dalam variabel integer yang telah kita buat tadi.Parameter ke dua isikan dengan "O_WRONLY" yang dimaksudkan untuk file tersebut dibuka dengan dalam mode write only.

               fd = open(fifo,O_WRONLY);

4. Menuliskan isi file pipe

Menuliskan isi file pipe bisa menggunakan perintah "write".

               write (fd,arr,sizeof(arr));

5. Menutup file pipe

Menutup file pipe bertujuan agar file pipe tersebut tidak akan diakses terus menerus. Menutup file pipe menggunakan perintah "close"

               close(fd);

6. Menghapus file pipe

Menghapus file pipe menggunakan perintah "unlink";
  
               unlink(fifo);

Read Process :

1. Deklarasi variabel

Variabel pertama bertype char pointer (char *fifo), di mana variabel fifo tersebut berisi lokasi yang telah digunakan untuk membuat file pipe, misal lokasinya adalah "/tmp/fifo/". Maka deklarasinya adalah :

               char *fifo = "/tmp/fifo/";

Variabel kedua adalah variabel bertype integer yang akan digunaka untuk membuka file pipe tadi (int fd) dan juga variabel array of integer untuk ditulis ke dalam file pipe tersebut (arr[100]). Maka deklarasinya adalah :

               int fd,arr[100]; 

2. Membuka file pipe

File pipe yang tadi telah kita buat kemudian dibuka dengan menggunakan perintah "open", lalu dimasukkan ke dalam variabel integer yang telah kita buat tadi.Parameter ke dua isikan dengan "O_RDONLY" yang dimaksudkan untuk file tersebut dibuka dengan dalam mode read only.

               fd = open(fifo,O_RDONLY);

3. Membaca isi file pipe

Membaca isi file pipe bisa menggunakan perintah "read".

               read (fd,arr,sizeof(arr));

4. Menutup file pipe

Menutup file pipe bertujuan agar file pipe tersebut tidak akan diakses terus menerus. Menutup file pipe menggunakan perintah "close"

               close(fd);

Kode Program

Write Process :

               char *fifo = "/tmp/fifo/";
               int fd,arr[100];
               mkfifo(fifo,0666);
               fd = open(fifo,O_WRONLY);
               write (fd,arr,sizeof(arr));
               close(fd);
               unlink(fifo);

Read Process :

               char *fifo = "/tmp/fifo/";
               int fd,arr[100]; 
               fd = open(fifo,O_RDONLY);
               read (fd,arr,sizeof(arr));
               close(fd);

0 komentar:

Thread Programming

Thread di Linux
GNU/Linux menggunakan POSIX Standard Thread API
Dikenal dengan nama pthread
Program dengan thread harus di-compile dengan option : -lpthread

Pembuatan Thread
Setiap thread dalam sebuah program diidentifikasi dengan thread ID
Type : pthread_t
Fungsi untuk membuat thread :
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
Parameter :
1 → thread ID
2 → thread attribute (NULL untuk default attribute)
3 → Fungsi yang ingin dijalankan
4 → Parameter untuk fungsi yang dijalankan

Contoh kode :

















Passing Data ke Thread
Parameter ke-4 dari pthread_create adalah parameter yang akan dimasukkan ke fungsi yang dijalankan oleh suatu thread
Parameter ke-4 bertipe pointer void
Jika ada lebih dari 1 nilai parameter yang ingin digunakan, maka gunakanlah struct

Menanti Sebuah Thread
Thread akan dijadwalkan oleh sistem operasi
Pengguna tidak akan pernah tahu mana yang berjalan dahulu
Fungsi untuk menunggu eksekusi sebuah thread selesai :
int pthread_join(pthread_t thread, void **retval);
Parameter :
1 → thread ID yang ditunggu
2 → Variabel untuk menyimpan return value dari thread (NULL jika tidak dibutuhkan)

Fungsi penting lain:
Pthread_self() : Digunakan untuk mengetahui thread ID dari thread yang sedang aktif
Pthread_equal() : Membandingkan thread ID yang satu dengan yang lain, apakah sama atau tidak

Prime single-thread





































Prime multi-thread

0 komentar:

Process Programming

Process Programming menjelaskan tentang proses dari sudut pandang seorang programmer di linux.

1. PID

Pertama – tama kita akan membahas PID, apa itu PID? PID adalah “Process ID” atau “Process Identifier”. Process identifier adalah integer unik berukuran 16 bit yang berurutan, anda bisa menganggap PID ini sebagai sebuah nomor induk (primary key) untuk membedakan process satu dengan yang lain. Selain itu juga ada PPID, Parent PID, yaitu adalah PID dari process yang men-spawn atau memanggil suatu process. Contohnya ada process “A” yang membutuhkan process “B”, maka process “A” akan memanggil process “B”, lalu process “B” akan memiliki sebuah PID unik dan sebuah PPID yaitu PID dari process yang memanggilnya, dalam kasus ini yang memanggilnya adalah process “A” sehingga PPID dari process “B” adalah PID process “A”.
Setiap process pasti memiliki PID dan PPID, kecuali process “init”, yang mana process ini adalah parent dari semua process, sehingga tidak memiliki PPID(karena tidak ada parent nya).
Ada beberapa cara untuk mengetahui PID dan PPID dari suatu process, salah satunya(menggunakan bahasa C++) adalah dengan menggunakan fungsi getpid(); dan getppid(); . jangan lupa gunakan typecast untuk merubah return valuenya menjadi integer. Kurang lebih seperti ini:
========================================================================printf(“PID=%d”,(int)getpid());
========================================================================

2. PROCESS SPAWNING

Tadi anda membaca istilah “men-spawn” process, atau memanggil process lainnya. Sekarang penulis akan menjelaskan bagaimana sebuah process men-spawn process lainnya. Terdapat 3 cara, yaitu :

System Call Fork

system call fork adalah sebuah fungsi yang digunakan untuk menduplikasi suatu process, misal ada sebuah process “A” yang melakukan fork, maka process “A” akan men-spawn process “A”(anak) juga (dengan PID yang berbeda tentunya).cara menggunakannya adalah
=================
pid_t cpid;
cpid=fork();
=================
cpid(singkatan untuk child pid) akan berisi PID dari process “A”(anak).bila PID>0 maka fork berhasil dan nilainya adlaah PID dari anaknya. Bila PID=0 berarti fork dijalankan di process anak (karena process anak sama dengan process parent maka ia pasti akan melakukan fork juga, namun karena posisinya sebagai anak maka fork nya tidak dijalankan, sehingga return value nya 0), bila return nya kurang dari 0 maka fork gagal karena beberapa alasan, salah satunya kehabisan memory.

System Call Exec Family

System call exec adalah sekumpulan fungsi yang digunakan untuk mengganti process yang sedang berjalan dengan process yang lain. Misal anda menjalankan process “A” dan meng-exec-nya menjadi process B. maka process A tadi akan dirubah menjadi process “B”, namun karena process tersebut hanya dirubah, maka PID akan tetap(pid nya tetap pid A).
ada banyak cara menggunakan exec, contohnya execv, execvp, dan lain lain, berikut penulis lampirkan situs yang sebaiknya anda baca:
a.) tentang keluarga exec:
b.) cara menggunakan execvp
Biasanya, bila suatu process ingin melakukan spawn process baru, ia akan melakukan fork() dahulu, untuk membuat “anak process”, lalu akan mengganti kerja dari anak process tersebut menjadi process yang dikehendaki dengan exec family. Bila butuh penjelasan lebih lanjut silahkan baca:

Fungsi “system”

fungsi system adalah cara yang paling gampang, anda tinggal menulis system(“X”) dengan X diganti menjadi process yang ingin dijalankan. Namun process ini sangat buruk dari sisi komputer. Berikut adalah sedikit kerja yang dilakukan komputer bila anda menggunakan fungsi system:
a.mensuspend program anda
b.memanggil operating system
c.membuka OS Shell (menjalankan OS baru didalam OS asli anda)
d.sekarang OS baru teserbut harus mencari program X untuk dijalankan
e.mengalokasikan memory untuk process X
f.mengeksekusi process X
g.dealokasi memory
h.menutup OS Baru tadi
i.melanjutkan program anda
jadi ibaratnya, kalau anda menggunakan fork-exec adalah anda pergi ke toko, membeli kompor untuk memasak indomie di rumah, maka pemanggilan fungsi system ini seperti membuat rumah baru lalu membakar rumah anda untuk memasak indomie tadi. Memang sama sama hasilnya tercapai (memasak indomie) namun sangat boros resource, selain itu antivirus membenci fungsi system karena boros resource dan tidak aman(pemanggilan process di OS baru berarti seperti memberikan kernel previlage pada process tsb), ibaratnya bila anda membakar rumah pasti ada polisi datang, walau anda tidak ditangkap tapi pasti ada keributan yang terjadi (menunggu antivirus berjalan, dan melakukan pekerjaannya).maka dari itu biasakanlah menggunakan fork-exec.
Exec dan fork membutuhkan #include <unistd> dan system membutuhkan #include <stdlib.h>. beda dari system call dengan fungsi system adalah:system call berarti menjalankan suatu fungsi dari system, sedangkan system adalah memanggil system baru dan menjalankan fungsi didalam system baru tersebut.

SIGNALS

adalah sebuah event yang dikirimkan oleh sebuah proces ke process itu sendiri atau process lain yang digunakan untuk notifikasi bahwa terjadi suatu event. Contoh beberapa signal terkenal yaitu:
1.) SIGKILL (membunuh process secara paksa)
2.)SIGTERM (mengirim request untuk membunuh process)
3.)SIGSEGV (Signal segmentation violation, error pada memory akses, biasanya ingin mengakses memory yang bukan hak nya)
4.)SIGSTOP (men-stop/pause suatu process)
5.)SIGCONT(meng-contintue suatu process yg di stop)
6.)SIGINT (Interrupt suatu process, contohnya ketika ada input dari keyboard.
Cara mengirimkannya ada 2 cara, bisa dengan syntax
=====
Kill –[SIGNAL] pid
====
Dengan [SIGNAL] diganti signal apa yang dikirim(SIGKILL, SIGSEGV,SIGTERM) dan pid adalah pid dari process tujuan(yang mau kita kirimin signalnya)
Bisajuga dengan system call kill(pid_t pid,int sig);, dengan pid adalah pid dari tujuan signal dan dengan sig adalah padanan angka dari signal, contohnya padanan dari SIGKILL adalah 9. Sebagai tambahan, bila menggunakan cara pertama bisa dengan “cara kill -9 pid” untuk mengirim signal SIGKILL. Pengiriman signal membutuhkan header file #include <sys/types.h> dan #include <signal.h>.

WAIT

Ketika sebuah process memanggil process baru(anak) maka process parent tersebut bisa menunggu(di block) sampai process anak selesai dengan fungsi wait. fungsi wait membutuhkan header file #include <sys/types.h> dan #Include <sys/wait.h>
Cara melakukannya adalah dengan cara:
===
int status;
pid_t temp;
temp=wait(&status);
===
Dengan temp adalah pid dari anak yang selesai, masalahnya adalah bila ada banyak process dan kita hanya ingin menunggu selesainya sebuah process spesifik, maka kita tidak bisa menggunakan wait() (sebenarnya bisa namun dengan cara yang agak panjang), namun cara mudahnya adalah dengan menggunakan waitpid,syntaxnya adalah
=============
Int temp = waitpid(pid_t cpid, int *status, int option);
=============
dengan cpid adalah pid dari child yang ingin ditunggu, status tidak perlu dipedulikan, dan option adalah option dari waitpid(anda bisa membuka man waitpid untuk melihat optionnya.), return dari waitpid(ditampung dalam variabel temp) adalah pid dari child yang berubah(bernilai sama dengan cpid),atau -1 bila error.

0 komentar: