signal

#include < signal.h >

#include < unistd.h >
#include < stdio.h >

static void
func_int()
{
    write(2, "SIGINT\n", 7);
}

int main()
{
    if (signal(SIGINT, func_int) == SIG_ERR){
        perror("signal");
        return 1;
    }
    sleep(60);
    return 0;
}

getitimer

インターバルタイマーを使って一定時間間隔でシグナルを発生。

#include < sys/time.h >

#include < signal.h >
#include < unistd.h >
#include < stdio.h >
#include < string.h >

static void
interval()
{
    write(2, ".", 1);
}

int main()
{
    struct itimerval val;
    struct sigaction act;
    sigset_t set;
    
    memset(&act, 0, sizeof act);
    act.sa_handler = interval;
    if (sigaction(SIGALRM, &act, NULL)< 0){
        perror("sigaction");
        return 1;
    }
    
    val.it_interval.tv_sec = 1;
    val.it_interval.tv_usec = 0;
    val.it_value = val.it_interval;
    if (setitimer(ITIMER_REAL, & val, NULL) < 0){
        perror("setitimer");
        return 1;
    }
    
    if (getitimer(ITIMER_REAL, &val) < 0){
        perror("getitimer");
        return 1;
    }
    printf(
    "it_interval = %ld.%ld\n"
           "it_value = %ld.%ld\n",
           val.it_interval.tv_sec, val.it_interval.tv_usec,
           val.it_value.tv_sec, val.it_value.tv_usec);
    
    sigemptyset(&set);
    for(;;){
        sigsuspend(&set);
    }
    return 0;
}

sigsuspend

シグナルの到着を待つシステムコールです。シグナルを受信するまでプロセスは停止します。

#include < signal.h >
#include < unistd.h >
#include < stdio.h >
#include < string.h >

static void func_int() {}

int main()
{
    struct sigaction act;
    sigset_t set;
    
    memset(&act, 0, sizeof act);
    act.sa_handler = func_int;
    if (sigaction(SIGINT, &act, NULL) < 0){
        perror("sigaction");
        return 1;
    }
    sigemptyset(&set);
    sigsuspend(&set);
    write(2, "SIGINT\n", 7);
    return 0;
}

sigaction

sigaction構造体をあらかじめmemset()で0クリアしてから、sa_handlerにシグナルハンドラの関数名を代入します。

#include 

#include 
#include 
#include 

static void
func_int()
{
    write(2, "SIGINT\n", 7);
}

int main()
{
    struct sigaction act;
    
    memset(&act, 0, sizeof act);
    act.sa_handler = func_int;
    if (sigaction(SIGINT,&act, NULL) < 0){
        perror("sigaction");
        return 1;
    }
    sleep(60);
    return 0;
}

シグナル送信kill

killは引数pidで指定したプロセスに、引数sigで指定したシグナルを送信します。

#include < sys/types.h >
#include < signal.h >

#include < stdio.h >
#include < stdlib.h >

int main(int argc, char *argv[])
{
    pid_t pid;
    
    pid = 0;
    if (argc >= 2){
        pid = atoi(argv[1]);
    }
    
    if (kill(pid, SIGTERM) < 0){
        perror("kill");
        return 1;
    }
    return 0;
}

mprotect

引数addrのアドレスから、引数lenの長さのメモリ領域のアクセス保護を、引数protの状態に変更。

#include < sys/mman.h >
#include < unistd.h >
#include < stdio.h >

int main(){
    size_t pagesize;
    char *mp;
    
    pagesize = getpagesize();
    
    mp = mmap(0, pagesize, PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
    if (mp == MAP_FAILED){
        perror("mmap");
        return 1;
    }
    
    if (mprotect(mp, pagesize, PROT_READ) < 0){
        perror("mprotect");
        return 1;
    }
    
    *mp = 1;
    return 0;
}

mmapでファイルコピー

mmapを利用して、効率良くファイルをコピー。通常ファイルが標準入力にリダイレクトされていることを想定。

#include < sys/mman.h >
#include < sys/types.h >
#include < unistd.h >
#include < stdio.h >

int main(){
    off_t p, file_size;
    size_t pagesize, len;
    char *mp;
    
    pagesize = getpagesize();
    
    if ((file_size = lseek(0, 0, SEEK_END))<0){
        perror("lseek");
        return 1;
    }
    
    len = pagesize;
    for(p = 0; p < file_size; p += len){
        if (file_size - p < pagesize){
            len = file_size - p;
        }
        
        if ((mp = mmap(0, len, PROT_READ,MAP_PRIVATE, 0, p))== MAP_FAILED){
            perror("mmap");
            return 1;
        }
        write(1, mp, len);
        if (munmap(mp, len)< 0){
            perror("munmap");
            return 1;
        }
    }
    return 0;
}

creatで新規ファイルを作成オープン

creatは、引数pathnameで指定したパス名のファイルを引数modeの値をumask値でマスクしたファイルモードで作成し、書き込み専用でオープンして、そのファイル記述子を戻り値として返します。

#include 
#include 
#include 

#include 

int main()
{
    int fd;
    
    if((fd = creat("file.txt",0666)) < 0){
        perror("creat");
        return 1;
    }
    
    return 0;
}

pread

preadはオフセットを指定してファイルを読み書きできるように、readシステムコールを改変したものです。

#define _XOPEN_SOURCE 500
#include < unistd.h >

#include < sys/types.h >
#include < sys/stat.h >
#include < fcntl.h >
#include < stdio.h >

int main()
{
    int fd_r, fd_w;
    ssize_t n;
    char buf[256];
    
    if ((fd_r = open("file1.txt", O_RDONLY)) < 0){
        perror("open(file1.txt)");
        return 1;
    }
    if ((fd_w = open("file2.txt", O_WRONLY|O_CREAT, 0666)) < 0){
        perror("open(file2.txt)");
        return 1;
    }
    if ((n = pread(fd_r, buf, sizeof buf, 10))< 0){
        perror("pread");
        return 1;
    }
    
    if (pwrite(fd_w, buf, n, 10)<0) {
        perror("pwrite");
        return 1;
    }
    return 0;
}

writev

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

int main()
{
    ssize_t n;
    struct iovec vector[3];
    
    vector[0].iov_base = "Hello";
    vector[0].iov_len = 5;
    
    vector[1].iov_base = " ";
    vector[1].iov_len = 1;
    vector[2].iov_base = "World\n";
    vector[2].iov_len = 6;
    
    if ((n = writev(1, vector, 3))< 0){
        perror("writev");
        return 1;
    }
    return 0;
}