#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; }
Month: June 2016
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; }
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; }