settimeofday

#include < sys/time.h >

#include < time.h >
#include < stdio.h >

int main(){
    struct timeval tv;
    struct tm tm;
    
    tm.tm_sec = 0;
    tm.tm_min = 0;
    tm.tm_hour = 0;
    tm.tm_mday = 1;
    tm.tm_mon = 0;
    tm.tm_year = 138;
    tm.tm_isdst = 0;
    tv.tv_sec = mktime(&tm);
    tv.tv_usec = 0;
    
    if (settimeofday(&tv, NULL) < 0){
        perror("settimeofday");
        return 1;
    }
    return 0;
}

現在時刻を取得

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

int main()
{
    struct timeval tv;
    
    if (gettimeofday(&tv, NULL) < 0){
        perror("gettimeofday");
        return 1;
    }
    printf("%s", ctime(&tv.tv_sec));
    return 0;
}

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;
}

brk

ヒープ領域に新たにメモリを割り当て、そのメモリ上に文字列をコピーして、その文字列を標準出力に出力する例です。

#include 

#include 
#include 

int main(){
    char *s;
    
    if ((s = sbrk(7))== (void *)-1){
        perror("sbrk");
        return 1;
    }
    strcpy(s, "hello\n");
    write(1, s, 6);
    
    if (brk(s) < 0){
        perror("brk");
        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;
}