2025
01
18
2012
06
24
自己参照型双方向リスト(C言語)
現在ゲーム中のユーザ管理するのにリスト構造使おうとちょっと作ったので置いておく。 自己参照型双方向リストです。
ソースコード
/* nex2t_list.c */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <netdb.h> #define RET_SUCCESS 0 #define RET_NO_ENTRY 1 #define RET_NO_MATCH_ENTRY 2 #define RET_NO_EXIST 0 #define RET_EXIST 1 #define DEBUG_LINE "------------------------------------------\n" typedef struct client_info { pid_t pid; char ip[NI_MAXHOST]; char port[NI_MAXSERV]; } cli_info_t; typedef struct client_info_node { struct client_info_node *next; struct client_info_node *prev; cli_info_t ent; } cli_info_node_t; typedef struct client_info_list { struct client_info_node *head; struct client_info_node *tail; } cli_info_list_t; void test(void); void create_info(cli_info_t *info, pid_t pid, const char ip[], const char port[]); void list_init(cli_info_list_t *list); void list_exit(cli_info_list_t *list); void list_add(cli_info_list_t *list, const cli_info_t *info); int list_del_head(cli_info_list_t *list); int list_del_tail(cli_info_list_t *list); int list_del_match_pid(cli_info_list_t *list, pid_t pid); int list_del_match_ip(cli_info_list_t *list, const char ip[]); int list_del_match_port(cli_info_list_t *list, const char port[]); int list_del_match(cli_info_list_t *list, const cli_info_t *info); int is_exist_cli_info_pid(const cli_info_list_t *list, pid_t pid); int is_exist_cli_info_ip(const cli_info_list_t *list, const char ip[]); int is_exist_cli_info_port(const cli_info_list_t *list, const char port[]); int is_exist_cli_info(const cli_info_list_t *list, const cli_info_t *info); void list_show(const cli_info_list_t *list); void list_show_match_pid(const cli_info_list_t *list, pid_t pid); void list_show_match_ip(const cli_info_list_t *list, const char ip[]); void list_show_match_port(const cli_info_list_t *list, const char port[]); void list_show_match(const cli_info_list_t *list, const cli_info_t *info); int main(void) { test(); return 0; } void create_info(cli_info_t *info, pid_t pid, const char ip[], const char port[]) { info->pid = pid; strcpy(info->ip, ip); strcpy(info->port, port); } void list_init(cli_info_list_t *list) { list->head = NULL; list->tail = NULL; } void list_add(cli_info_list_t *list, const cli_info_t *info) { cli_info_node_t *node; cli_info_node_t *node_tmp; node = (cli_info_node_t *)malloc(sizeof(cli_info_node_t)); node->ent.pid = info->pid; strcpy(node->ent.ip, info->ip); strcpy(node->ent.port, info->port); if (list->head == NULL) { /* first add */ list->head = node; list->tail = node; node->prev = NULL; node->next = NULL; } else { node_tmp = list->head; while (node_tmp->next != NULL) { node_tmp = node_tmp->next; } node_tmp->next = node; node->next = NULL; node->prev = node_tmp; list->tail = node; } } int list_del_head(cli_info_list_t *list) { cli_info_node_t *node_next_keep; if (list->head == NULL) { return RET_NO_ENTRY; } else if (list->head->next == NULL) { free(list->head); list->head = NULL; list->tail = NULL; } else { node_next_keep = list->head->next; free(node_next_keep->prev); list->head = node_next_keep; list->head->prev = NULL; } return RET_SUCCESS; } int list_del_tail(cli_info_list_t *list) { cli_info_node_t *node_prev_keep; if (list->tail == NULL) { return RET_NO_ENTRY; } else if (list->tail->prev == NULL) { free(list->tail); list->head = NULL; list->tail = NULL; } else { node_prev_keep = list->tail->prev; free(list->tail); list->tail = node_prev_keep; list->tail->next = NULL; } return RET_SUCCESS; } int list_del_match_pid(cli_info_list_t *list, pid_t pid) { int i = 1; cli_info_node_t *node; if (list->head == NULL) { return RET_NO_ENTRY; } node = list->head; do { if (i != 1) { node = node->next; } if (node->ent.pid == pid) { if ((node->prev == NULL) && (node->next == NULL)) { list->head = NULL; list->tail = NULL; } else if (node->prev == NULL) { list->head = node->next; node->next->prev = NULL; } else if (node->next == NULL) { list->tail = node->prev; node->prev->next = NULL; } else { node->prev->next = node->next; node->next->prev = node->prev; } free(node); return RET_SUCCESS; } i++; } while (node->next != NULL); return RET_NO_MATCH_ENTRY; } int list_del_match_ip(cli_info_list_t *list, const char ip[]) { int i = 1; cli_info_node_t *node; if (list->head == NULL) { return RET_NO_ENTRY; } node = list->head; do { if (i != 1) { node = node->next; } if (!strcmp(node->ent.ip, ip)) { if ((node->prev == NULL) && (node->next == NULL)) { list->head = NULL; list->tail = NULL; } else if (node->prev == NULL) { list->head = node->next; node->next->prev = NULL; } else if (node->next == NULL) { list->tail = node->prev; node->prev->next = NULL; } else { node->prev->next = node->next; node->next->prev = node->prev; } free(node); return RET_SUCCESS; } i++; } while (node->next != NULL); return RET_NO_MATCH_ENTRY; } int list_del_match_port(cli_info_list_t *list, const char port[]) { int i = 1; cli_info_node_t *node; if (list->head == NULL) { return RET_NO_ENTRY; } node = list->head; do { if (i != 1) { node = node->next; } if (!strcmp(node->ent.port, port)) { if ((node->prev == NULL) && (node->next == NULL)) { list->head = NULL; list->tail = NULL; } else if (node->prev == NULL) { list->head = node->next; node->next->prev = NULL; } else if (node->next == NULL) { list->tail = node->prev; node->prev->next = NULL; } else { node->prev->next = node->next; node->next->prev = node->prev; } free(node); return RET_SUCCESS; } i++; } while (node->next != NULL); return RET_NO_MATCH_ENTRY; } int list_del_match(cli_info_list_t *list, const cli_info_t *info) { int i = 1; cli_info_node_t *node; if (list->head == NULL) { return RET_NO_ENTRY; } node = list->head; do { if (i != 1) { node = node->next; } if ((node->ent.pid == info->pid) && !strcmp(node->ent.ip, info->ip) && (!strcmp(node->ent.port, info->port))) { if ((node->prev == NULL) && (node->next == NULL)) { list->head = NULL; list->tail = NULL; } else if (node->prev == NULL) { list->head = node->next; node->next->prev = NULL; } else if (node->next == NULL) { list->tail = node->prev; node->prev->next = NULL; } else { node->prev->next = node->next; node->next->prev = node->prev; } free(node); return RET_SUCCESS; } i++; } while (node->next != NULL); return RET_NO_MATCH_ENTRY; } void list_show(const cli_info_list_t *list) { int i = 1; cli_info_node_t *node; if (list->head == NULL) { printf("NO ENTRY.\n"); return; } node = list->head; do { if (i != 1) { node = node->next; } printf("[%d] pid:%d, ip:%s, port:%s\n", i++, node->ent.pid, node->ent.ip, node->ent.port); } while (node->next != NULL); } void list_show_match_pid(const cli_info_list_t *list, pid_t pid) { int i = 1, match_flag = 0; cli_info_node_t *node; if (list->head == NULL) { printf("NO_ENTRY.\n"); return; } node = list->head; do { if (i != 1) { node = node->next; } if (node->ent.pid == pid) { printf("[%d] pid:%d, ip:%s, port:%s\n", i, node->ent.pid, node->ent.ip, node->ent.port); match_flag = 1; } i++; } while (node->next != NULL); if (!match_flag) { printf("NO MATCH ENTRY pid:%d\n", pid); } } void list_show_match_ip(const cli_info_list_t *list, const char ip[]) { int i = 1, match_flag = 0; cli_info_node_t *node; if (list->head == NULL) { printf("NO_ENTRY.\n"); return; } node = list->head; do { if (i != 1) { node = node->next; } if (!strcmp(node->ent.ip, ip)) { printf("[%d] pid:%d, ip:%s, port:%s\n", i, node->ent.pid, node->ent.ip, node->ent.port); match_flag = 1; } i++; } while (node->next != NULL); if (!match_flag) { printf("NO MATCH ENTRY ip:%s\n", ip); } } void list_show_match_port(const cli_info_list_t *list, const char port[]) { int i = 1, match_flag = 0; cli_info_node_t *node; if (list->head == NULL) { printf("NO ENTRY.\n"); return; } node = list->head; do { if (i != 1) { node = node->next; } if (!strcmp(node->ent.port, port)) { printf("[%d] pid:%d, ip:%s, port:%s\n", i, node->ent.pid, node->ent.ip, node->ent.port); match_flag = 1; } i++; } while (node->next != NULL); if (!match_flag) { printf("NO MATCH ENTRY port:%s\n", port); } } void list_show_match(const cli_info_list_t *list, const cli_info_t *info) { int i = 1, match_flag = 0; cli_info_node_t *node; if (list->head == NULL) { printf("NO ENTRY\n"); return; } node = list->head; do { if (i != 1) { node = node->next; } if ((node->ent.pid == info->pid) && !strcmp(node->ent.ip, info->ip) && (!strcmp(node->ent.port, info->port))) { printf("[%d] pid:%d, ip:%s, port:%s\n", i, node->ent.pid, node->ent.ip, node->ent.port); match_flag = 1; } i++; } while (node->next != NULL); if (!match_flag) { printf("NO MATCH ENTRY pid:%d, ip:%s, port:%s\n", info->pid, info->ip, info->port); } } int is_exist_cli_info_pid(const cli_info_list_t *list, pid_t pid) { int i = 1; cli_info_node_t *node; if (list->head == NULL) { return RET_NO_EXIST; } node = list->head; do { if (i != 1) { node = node->next; } if (node->ent.pid == pid) { return RET_EXIST; } i++; } while (node->next != NULL); return RET_NO_EXIST; } int is_exist_cli_info_ip(const cli_info_list_t *list, const char ip[]) { int i = 1; cli_info_node_t *node; if (list->head == NULL) { return RET_NO_EXIST; } node = list->head; do { if (i != 1) { node = node->next; } if (!strcmp(node->ent.ip, ip)) { return RET_EXIST; } i++; } while (node->next != NULL); return RET_NO_EXIST; } int is_exist_cli_info_port(const cli_info_list_t *list, const char port[]) { int i = 1; cli_info_node_t *node; if (list->head == NULL) { return RET_NO_EXIST; } node = list->head; do { if (i != 1) { node = node->next; } if (!strcmp(node->ent.port, port)) { return RET_EXIST; } i++; } while (node->next != NULL); return RET_NO_EXIST; } int is_exist_cli_info(const cli_info_list_t *list, const cli_info_t *info) { int i = 1; cli_info_node_t *node; if (list->head == NULL) { return RET_NO_EXIST; } node = list->head; do { if (i != 1) { node = node->next; } if ((node->ent.pid == info->pid) && !strcmp(node->ent.ip, info->ip) && (!strcmp(node->ent.port, info->port))) { return RET_EXIST; } i++; } while (node->next != NULL); return RET_NO_EXIST; } void list_exit(cli_info_list_t *list) { cli_info_node_t *node_tmp; cli_info_node_t *node_keep; if (list->head == NULL) { return; /* no entry */ } node_tmp = list->head; do { node_keep = node_tmp->next; free(node_tmp); node_tmp = node_keep; } while (node_tmp != NULL); } void test(void) { cli_info_list_t list; cli_info_t info; list_init(&list); printf("first list state.\n"); create_info(&info, 1003, "192.168.1.3", "10003"); list_add(&list, &info); create_info(&info, 1004, "192.168.1.4", "10004"); list_add(&list, &info); create_info(&info, 1005, "192.168.1.5", "10005"); list_add(&list, &info); create_info(&info, 1006, "192.168.1.6", "10006"); list_add(&list, &info); printf(DEBUG_LINE); list_show(&list); printf(DEBUG_LINE "\n"); printf("list_show_match test\n"); printf(DEBUG_LINE); list_show_match_pid(&list, 1005); list_show_match_pid(&list, 1007); list_show_match_ip(&list, "192.168.1.10"); list_show_match_ip(&list, "192.168.1.6"); list_show_match_port(&list, "10009"); list_show_match_port(&list, "10003"); create_info(&info, 1003, "192.168.1.5", "10003"); list_show_match(&list, &info); create_info(&info, 1003, "192.168.1.3", "10003"); list_show_match(&list, &info); printf(DEBUG_LINE "\n"); printf("is_exist_cli_info test (equal param list_show_match test)\n"); printf(DEBUG_LINE); printf("%d\n", is_exist_cli_info_pid(&list, 1005)); printf("%d\n", is_exist_cli_info_pid(&list, 1007)); printf("%d\n", is_exist_cli_info_ip(&list, "192.168.1.10")); printf("%d\n", is_exist_cli_info_ip(&list, "192.168.1.6")); printf("%d\n", is_exist_cli_info_port(&list, "10009")); printf("%d\n", is_exist_cli_info_port(&list, "10003")); create_info(&info, 1003, "192.168.1.5", "10003"); printf("%d\n", is_exist_cli_info(&list, &info)); create_info(&info, 1003, "192.168.1.3", "10003"); printf("%d\n", is_exist_cli_info(&list, &info)); printf(DEBUG_LINE "\n"); printf("list_add test\n"); printf(DEBUG_LINE); create_info(&info, 2003, "192.168.2.3", "20003"); list_add(&list, &info); create_info(&info, 2004, "192.168.2.4", "20004"); list_add(&list, &info); list_show(&list); printf(DEBUG_LINE "\n"); printf("list_del test\n"); printf(DEBUG_LINE); list_del_head(&list); list_del_tail(&list); list_show(&list); printf(DEBUG_LINE); list_del_match_pid(&list, 1003); list_del_match_pid(&list, 1004); /* del */ list_show(&list); printf(DEBUG_LINE); list_del_match_ip(&list, "192.168.1.5"); /* del */ list_del_match_ip(&list, "192.168.1.7"); list_show(&list); printf(DEBUG_LINE); list_del_match_port(&list, "10006"); /* del */ list_del_match_port(&list, "10005"); list_show(&list); printf(DEBUG_LINE); create_info(&info, 1003, "192.168.1.5", "10003"); list_del_match(&list, &info); create_info(&info, 2003, "192.168.2.3", "20003"); /* del */ list_del_match(&list, &info); list_show(&list); printf(DEBUG_LINE); list_exit(&list); }
コンパイル例
gcc -W -Wall -o nex2t_list nex2t_list.c
実行結果
./list first list state. ------------------------------------------ [1] pid:1003, ip:192.168.1.3, port:10003 [2] pid:1004, ip:192.168.1.4, port:10004 [3] pid:1005, ip:192.168.1.5, port:10005 [4] pid:1006, ip:192.168.1.6, port:10006 ------------------------------------------ list_show_match test ------------------------------------------ [3] pid:1005, ip:192.168.1.5, port:10005 NO MATCH ENTRY pid:1007 NO MATCH ENTRY ip:192.168.1.10 [4] pid:1006, ip:192.168.1.6, port:10006 NO MATCH ENTRY port:10009 [1] pid:1003, ip:192.168.1.3, port:10003 NO MATCH ENTRY pid:1003, ip:192.168.1.5, port:10003 [1] pid:1003, ip:192.168.1.3, port:10003 ------------------------------------------ is_exist_cli_info test (equal param list_show_match test) ------------------------------------------ 1 0 0 1 0 1 0 1 ------------------------------------------ list_add test ------------------------------------------ [1] pid:1003, ip:192.168.1.3, port:10003 [2] pid:1004, ip:192.168.1.4, port:10004 [3] pid:1005, ip:192.168.1.5, port:10005 [4] pid:1006, ip:192.168.1.6, port:10006 [5] pid:2003, ip:192.168.2.3, port:20003 [6] pid:2004, ip:192.168.2.4, port:20004 ------------------------------------------ list_del test ------------------------------------------ [1] pid:1004, ip:192.168.1.4, port:10004 [2] pid:1005, ip:192.168.1.5, port:10005 [3] pid:1006, ip:192.168.1.6, port:10006 [4] pid:2003, ip:192.168.2.3, port:20003 ------------------------------------------ [1] pid:1005, ip:192.168.1.5, port:10005 [2] pid:1006, ip:192.168.1.6, port:10006 [3] pid:2003, ip:192.168.2.3, port:20003 ------------------------------------------ [1] pid:1006, ip:192.168.1.6, port:10006 [2] pid:2003, ip:192.168.2.3, port:20003 ------------------------------------------ [1] pid:2003, ip:192.168.2.3, port:20003 ------------------------------------------ NO ENTRY. ------------------------------------------
検索用タグ C言語 双方向リスト 自己参照型
PR
2012/06/24 (Sun.) Comment(0) C言語
2012
05
30
可変長引数を使ってログメッセージ作成(C言語)
syslogに出力するのに、可変長引数使ってログメッセージ出力してやろうと 思って少しやったのでメモ。以下ソースはエラー処理とか細かいところはやってません (C言語でsyslog()に出力するのはまた別の記事でやろうかと思います)
ソースコード
/* nex2t_syslog.c */ #include <stdio.h> #include <stdarg.h> #define LOG_MESSAGE1 "[20000]: system info\n" #define LOG_MESSAGE2 "[20001]: system error(%d, %d)\n" #define LOG_MAIN 1 /* where? */ void nex2t_syslog(char *fmt, ...); int main(void) { nex2t_syslog(LOG_MESSAGE1); nex2t_syslog(LOG_MESSAGE2, LOG_MAIN, 0); /* ~hogehoge~ */ nex2t_syslog(LOG_MESSAGE2, LOG_MAIN, 7); return 0; } void nex2t_syslog(char *fmt, ...) { char *p; int ival; va_list ap; va_start(ap, fmt); for (p = fmt; *p; p++) { if (*p != '%') { putchar(*p); continue; } p++; ival = va_arg(ap, int); printf("%d", ival); } va_end(ap); }
コンパイル例
gcc -W -Wall -o nex2t_syslog nex2t_syslog.c
実行結果
./nex2t_syslog [20000]: system info [20001]: system error(1, 0) [20001]: system error(1, 7)
検索用タグ C言語 可変長引数
2012/05/30 (Wed.) Comment(0) C言語
2012
05
28
initrdの展開・編集・再構築
「ubuntuのLANドライバ変更してー」と言われ、e1000eの最新ドライバをmake, make installみたいな よくあるやり方で入れたつもりで再起動したが変更できてない!ってことが起きました。 どうやらinitrdをいじる必要があるようです。。ということでまとめ。 ※initrd はLinuxカーネルのブート時によく使われる一時的なファイルシステムの一種。 "initial ramdisk" の略。 真のルートファイルシステムをマウントできるようになる前にファイルシステムを 必要とする場面で使用される。
initrdの展開
su # とりあえずrootになる cd mkdir sagyou # /root/sagyouを作る cp /boot/initrd.img~ /root/sagyou/ # コピーしてくる gunzip < initrd.img~ | cpio -i # ←ここが肝 rm initrd.img~ # 展開した元のファイルは削除 # 以上でinitrdは展開されました。
initrdの編集
# たとえば、e1000eのドライバを変えるなら /root/sagyou/lib/modules/`uname -r`/kernel/drivers/net/e1000e/ の中のe1000e.koを変更するとかします。
initrdの再構築
find . | cpio -o -H newc | gzip -c > ./initrd-new # initrd-newの部分は自由 (※再構築したinitrdで立ち上げたいなら、展開時と同じファイル名にして、 /boot/に置いてあげればOK)
検索用タグ initrd 展開 編集 再構築
2012/05/28 (Mon.) Comment(1) Linux
2012
05
27
パイプで双方向プロセス間通信(C言語)
ファイル整理してたら出てきたのでメモ
ソースコード
/* pipe.c */ #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #define BUF_LEN 256 int main(void) { int fd[2], ret; char buf[BUF_LEN]; pid_t pid; if ((ret = pipe(fd)) == -1) { perror("pipe"); return -1; } if ((ret = fork()) == -1) { perror("fork"); return -1; } else if (ret == 0) { pid = getpid(); printf("[pid:%d] I'm child\n", (int)pid); write(fd[1], "child wrote", 13); read(fd[0], buf, BUF_LEN); printf("[pid:%d] from parent:[%s]\n", (int)pid, buf); } else { pid = getpid(); printf("[pid:%d] I'm parent\n", (int)pid); write(fd[1], "parent wrote", 14); read(fd[0], buf, BUF_LEN); printf("[pid:%d] from child:[%s]\n", (int)pid, buf); wait(&ret); } return 0; }
実行結果
./pipe [pid:13330] I'm parent [pid:13330] from child:[parent wrote] [pid:13331] I'm child [pid:13331] from parent:[child wrote]
検索用タグ C言語 プロセス間通信
2012/05/27 (Sun.) Comment(0) C言語
2012
05
27
シェルスクリプトで指定回数実行
指定回数実行するシェルスクリプトのテンプレをメモ とりあえずいくつかのパターンを、 最後に指定回数Verを
for文 Ver1 (10回)
#!/bin/sh for i in `seq 1 1 10` do echo "$i" done exit 0
for文 Ver2 (10回)
(下記の書き方だと、bashじゃないとダメだった) #!/bin/bash for ((i=1;i<=10;i++)) do echo $i done exit 0
while文 Ver (10回)
#!/bin/sh i=1 while [ $i -le 10 ]; do echo "$i" i=`expr $i + 1` done exit 0
実行結果
1 2 3 4 5 6 7 8 9 10
指定回数実行 テンプレ
#!/bin/sh if [ $# -lt 1 ] then echo "usage: $0 [trial_num]" exit 0 fi for i in `seq 1 1 $1` do echo $i done exit 0
検索用タグ シェルスクリプト
2012/05/27 (Sun.) Comment(0) シェルスクリプト