コアダンプの数だけ強くなれるよ

見習いエンジニアの備忘log

errno一覧

Linuxでerrno一覧

#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(void)
{
    for(int i = 0; i <= EHWPOISON; i++) {
        char str[64] = {0};
        strerror_r(i, str, sizeof(str));
        printf("%d:%s\n", i, str);
    }

    return 0;
}

実行結果

0:Success
1:Operation not permitted
2:No such file or directory
3:No such process
4:Interrupted system call
5:Input/output error
6:No such device or address
7:Argument list too long
8:Exec format error
9:Bad file descriptor
10:No child processes
11:Resource temporarily unavailable
12:Cannot allocate memory
13:Permission denied
14:Bad address
15:Block device required
16:Device or resource busy
17:File exists
18:Invalid cross-device link
19:No such device
20:Not a directory
21:Is a directory
22:Invalid argument
23:Too many open files in system
24:Too many open files
25:Inappropriate ioctl for device
26:Text file busy
27:File too large
28:No space left on device
29:Illegal seek
30:Read-only file system
31:Too many links
32:Broken pipe
33:Numerical argument out of domain
34:Numerical result out of range
35:Resource deadlock avoided
36:File name too long
37:No locks available
38:Function not implemented
39:Directory not empty
40:Too many levels of symbolic links
41:
42:No message of desired type
43:Identifier removed
44:Channel number out of range
45:Level 2 not synchronized
46:Level 3 halted
47:Level 3 reset
48:Link number out of range
49:Protocol driver not attached
50:No CSI structure available
51:Level 2 halted
52:Invalid exchange
53:Invalid request descriptor
54:Exchange full
55:No anode
56:Invalid request code
57:Invalid slot
58:
59:Bad font file format
60:Device not a stream
61:No data available
62:Timer expired
63:Out of streams resources
64:Machine is not on the network
65:Package not installed
66:Object is remote
67:Link has been severed
68:Advertise error
69:Srmount error
70:Communication error on send
71:Protocol error
72:Multihop attempted
73:RFS specific error
74:Bad message
75:Value too large for defined data type
76:Name not unique on network
77:File descriptor in bad state
78:Remote address changed
79:Can not access a needed shared library
80:Accessing a corrupted shared library
81:.lib section in a.out corrupted
82:Attempting to link in too many shared libraries
83:Cannot exec a shared library directly
84:Invalid or incomplete multibyte or wide character
85:Interrupted system call should be restarted
86:Streams pipe error
87:Too many users
88:Socket operation on non-socket
89:Destination address required
90:Message too long
91:Protocol wrong type for socket
92:Protocol not available
93:Protocol not supported
94:Socket type not supported
95:Operation not supported
96:Protocol family not supported
97:Address family not supported by protocol
98:Address already in use
99:Cannot assign requested address
100:Network is down
101:Network is unreachable
102:Network dropped connection on reset
103:Software caused connection abort
104:Connection reset by peer
105:No buffer space available
106:Transport endpoint is already connected
107:Transport endpoint is not connected
108:Cannot send after transport endpoint shutdown
109:Too many references: cannot splice
110:Connection timed out
111:Connection refused
112:Host is down
113:No route to host
114:Operation already in progress
115:Operation now in progress
116:Stale file handle
117:Structure needs cleaning
118:Not a XENIX named type file
119:No XENIX semaphores available
120:Is a named type file
121:Remote I/O error
122:Disk quota exceeded
123:No medium found
124:Wrong medium type
125:Operation canceled
126:Required key not available
127:Key has expired
128:Key has been revoked
129:Key was rejected by service
130:Owner died
131:State not recoverable
132:Operation not possible due to RF-kill
133:

C言語で簡易メモリ管理

Linux Kernelのリスト構造を参考に作成。

環境:CentOS 6, gcc version 4.4.7

mempool.h

#ifndef _MEMPOOL_H_
#define _MEMPOOL_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <stddef.h>

#define EASY_ELECTORIC_FENCE (0x123456789)

#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

#define GET_ENTRY(ptr,type,member) \
    ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

#define Malloc(size) \
    __Malloc(size, __FILE__, __LINE__)

#define Free(ptr) \
    __Free(ptr)

struct mem_list {
    struct mem_list *prev;
    struct mem_list *next;
};

typedef struct {
    struct mem_list head;
    int32_t         entry_count;
} MemListHead_t;

typedef struct {
    struct mem_list list;
    int64_t         fence;      /* electoric fence */
    char            file[64];   /* ファイル名 */
    int32_t         line;       /* 行数 */
    struct timeval  tv;         /* 取得時刻 */
    int32_t         size;       /* memory size */
    void*           address;    /* dataのアドレス */
    uint8_t         data[0];    /* ユーザに渡すポインタ */
} MemListEntry_t;

static inline memlist_init(
    struct mem_list *head)
{
    head->prev = head;
    head->next = head;
}

static inline memlist_add_tail(
    struct mem_list *entry,
    struct mem_list *head)
{
    head->prev->next = entry;
    entry->next = head;
    entry->prev = head->prev;
    head->prev = entry;
}

static inline memlist_del(
    struct mem_list *entry,
    struct mem_list *head)
{
    entry->prev->next = entry->next;
    entry->next->prev = entry->prev;
    entry->next = (struct mem_list *)0xdeaddead;
    entry->prev = (struct mem_list *)0xdeaddead;
}

extern void* __Malloc(size_t size, char*  file, size_t line);
extern void __Free(void* ptr);

#endif /* _MEMPOOL_H_ */

mempool.c

#include "mempool.h"

extern MemListHead_t MngMem;

void* __Malloc(
    size_t size,
    char*  file,
    size_t line)
{
    void* ptr = NULL;
    MemListEntry_t* entry =
        (MemListEntry_t*) malloc(sizeof(*entry)+size);

    if (NULL != entry) {

        entry->fence = EASY_ELECTORIC_FENCE;
        entry->size  = size;
        snprintf(entry->file, sizeof(entry->file)-1, "%s", file);
        entry->line = line;
        gettimeofday(&entry->tv, NULL);
        entry->address = &entry->data[0];

        memlist_add_tail(&entry->list, &MngMem.head);

        ptr = &entry->data[0];
    }

    return ptr;
}

void __Free(
    void* ptr)
{
    MemListEntry_t* entry =
        (MemListEntry_t*)((uint8_t*)ptr - sizeof(MemListEntry_t));

    if(!(entry->address == ptr && EASY_ELECTORIC_FENCE != entry->fence)) {
        /* memory currupted or invalid address */
    }

    memlist_del(&entry->list, &MngMem.head);
    free(entry);
}


memtest.c (動作確認用のソースコード)

#include "mempool.h"

MemListHead_t MngMem;

typedef struct {
    int a;
    int b;
    int c;
    int d;
    int e[1024];
} testData_t;

int main(int argc, char *argv[])
{
    /* メモリ管理リスト初期化 */
    memlist_init(&MngMem.head);

    /* メモリ領域を確保 */
    testData_t *dat1 =
        (testData_t* )Malloc(sizeof(*dat1));
    testData_t *dat2 =
        (testData_t* )Malloc(sizeof(*dat2)+1);
    testData_t *dat3 =
        (testData_t* )Malloc(sizeof(*dat3)+2);

   
    /* dat1,2,3がメモリ管理リストに追加されているか確認 */
    struct mem_list *p;
    printf("##### BEFORE #####\n");
    printf("file:line, size, fence, address\n");
    printf("-------------------------------\n");
    list_for_each(p, &(MngMem.head)) {
        MemListEntry_t *gp = GET_ENTRY(p, MemListEntry_t, list);
        printf("%s:%u, %d, %#llx, %p\n",
               gp->file, gp->line, gp->size, gp->fence, gp->address);
    }

    /* dat2の削除 */
    Free(dat2);

    /* メモリ管理リストからdat2のエントリが消えているか確認 */
    printf("##### AFTER1 #####\n");
    printf("file:line, size, fence, address\n");
    printf("-------------------------------\n");
    list_for_each(p, &(MngMem.head)) {
        MemListEntry_t *gp = GET_ENTRY(p, MemListEntry_t, list);
        printf("%s:%u, %d, %#llx, %p\n",
               gp->file, gp->line, gp->size, gp->fence, gp->address);
    }

    /* dat1, dat3の削除 */
    Free(dat1);
    Free(dat3);
    
    /* メモリ管理リストからエントリがすべて消えているか確認 */
    printf("##### AFTER2 #####\n");
    printf("file:line, size, fence, address\n");
    printf("-------------------------------\n");
    list_for_each(p, &(MngMem.head)) {
        MemListEntry_t *gp = GET_ENTRY(p, MemListEntry_t, list);
        printf("%s:%u, %d, %#llx, %p\n",
               gp->file, gp->line, gp->size, gp->fence, gp->address);
    }

    return 0;
}


Makefile

memtest: memtest.o mempool.o
        gcc -g -o memtest memtest.o mempool.o

memtest.o: memtest.c mempool.h
        gcc -g -c memtest.c

mempool.o: mempool.c mempool.h
        gcc -g -c mempool.c

clean: *.o
        rm -f *.o


動作確認

$ make
gcc -g -c memtest.c
gcc -g -c mempool.c
gcc -g -o memtest memtest.o mempool.o
$
$ ./memtest
##### BEFORE #####
file:line, size, fence, address
-------------------------------
memtest.c:18, 4112, 0x123456789, 0x6b7090
memtest.c:20, 4113, 0x123456789, 0x6b8130
memtest.c:22, 4114, 0x123456789, 0x6b91d0
##### AFTER1 #####
file:line, size, fence, address
-------------------------------
memtest.c:18, 4112, 0x123456789, 0x6b7090
memtest.c:22, 4114, 0x123456789, 0x6b91d0
##### AFTER2 #####
file:line, size, fence, address
-------------------------------

Gmailで不要なメールを定期的に削除する

Gmailで不要なメールを定期的に削除するスクリプトを書いてみた。

[仕様]

  • 指定ラベルのメールのうち30日経過したものを削除
  • 毎晩0時に実行(トリガーを時間主導に設定)

[手順]

  1. ドライブ-->Googleスプレッドシート新規作成し開く-->ツール-->スクリプトエディタ
  2. 既存のコードを削除して下記コピペ
  3. リソース-->現在のプロジェクトのトリガー-->イベントを時間主導に設定

スクリプトの内容

function deleteMailExpired30Days() {
  var day = 30;
  var label= [
     '親ラベル-001.子ラベル ',
     '親ラベル-002.子ラベル ',
     '親ラベル-003.子ラベル '
  ];
  
  for (entry = 0; entry < label.length; entry++) {
      var threads = GmailApp.search('older_than:' + day + 'd ' + 'label:' + label[entry]);
      for (var i = 0; i < threads.length; i++) {
          threads[i].moveToTrash();
      }
  }
}


labelのリストを手書きしている点が少々ダサい…
親ラベル配下の子ラベルを取得する方法とか無いのかな。

スター付きのメールを除外したい場合は検索条件に"-is:starred"を追加する。

[参考]Gmailで使用できる検索演算子
https://support.google.com/mail/answer/7190?hl=ja

Googleフォーム受信内容をメールで通知する

何かとお世話になってるGoogleフォーム。問い合わせや回答が来てないかイチイチ確認しなくてはならないかと思いきや、簡単なスクリプトを書いてあげれば投稿時に内容をメールで通知できるようなので試してみた。

[手順]

  1. フォーム作成画面 → その他 → スクリプトエディタでスクリプト編集画面へ移動。
  2. 既存コードを削除して下記コードをコピペ。
  3. 編集 → 現在のプロジェクトのトリガー → トリガーを作成して保存。

スクリプトの内容

function notifyInquiryMessage(entry){
  var inquiryItems  = entry.response.getItemResponses();
  var message = '';
 
  /* 入力内容の抽出 */
  for (var i = 0; i < inquiryItems.length; i++) {
    var inquiryItem = inquiryItems[i];
    var question = inquiryItem.getItem().getTitle();
    var answer = inquiryItem.getResponse();
    message += (i + 1).toString() + '. ' + question + ': ' + answer + '\n';
  }
 
  /* 通知内容を作成 */
  var address = '/* 通知先のメールアドレス */';
  var title = '/* メールの件名 */';
  var content = '以下の内容を受信しました。' +'\n\n' + message + '\n\n' +
                '下記で回答を確認する' + '\n\n' +'/* 回答のURL等 */';
 
  /* メール送信(通知) */
  GmailApp.sendEmail(address, title, content);
}