2006/06/26(月)ncurses

パスワードの変更コマンドを作成するためにいろいろ実験中。

CUIの管理は、やはり、ncursesが無難そうだ。

パスワード変更コマンドに必須だと思われる機能

  • ローカルエコーさせずにキー入力を受け付ける \ncursesのnoechoを使えばできる模様
  • 暗号化した状態で、メモリにデータを読み込む (dump対策) \乱数を用いてメモリをかき混ぜること位はしたいが...

2006/06/25(日)多段make

ソースファイルとプラグインを一括コンパイルするために,多段makeに挑戦.

とりあえずのメモです.きちんと出来るようになったら,詳細を書きます.

ディレクトリ構造

album3.1/
  src/
    plugin/
      plugin1/
      plugin2/
      plugin3/
  plugin/

ターゲットとなるMakefileは,{album3.1,src,plugin,plugin{1,2,3}}/Makefile

makeファイル

album3.1/Makefile

CC = gcc

all:
	$(MAKE) -C src

album3.1/src/Makefile

INCLUDE += -I .

all: here plugins
here: 
	# このフォルダでコンパイルする内容

plugins:
	$(MAKE) -C plugin

album3.1/src/plugin/Makefile

INCLUDE += -I ../..
 SUBDIRS = $(shell find * -type d)

all:
	list='$(SUBDIRS)'; for subdir in $$list; do \
	$(MAKE) -C $$subdir || exit 1;\
	done

clean:
	list='$(SUBDIRS)'; for subdir in $$list; do \
	$(MAKE) clean -C $$subdir;\
	done

album3.1/src/plugin/plugin1/Makefile

# 各プラグインにおまかせ
# ただし,INCLUDEを上書きしないように注意

all:
	# 適当にコンパイル

album3.1/src/plugin/MakefileにおいてENTRIES = $(shell find * -type d)をしてるけど,現在のフォルダにあるディレクトリ一覧を取り出す手段は無いのでしょうか?

誰か分かるかた教えてください.

2006/06/23(金)va_start

64bit FreeBSDgcc*1において,なぜかvsnprintfが動作しなかったのですが,ようやく原因がなんとなく判明しました.

どうやら,64bit FreeBSDgccでは,vsnprintfの引数va_listが指しているポインタをいじっている模様.va_listを使う必要がある場合は,毎回va_startva_endを実行した方が無難そうです.

ダメな例

char *test(const char *format, ...)
{
    int size;
    int len;
    char *buf;

    va_list ap;
    va_start(ap, format); // ここで ap を初期化

    while(1){
        buf = (char *)malloc(size);

        // vsnprintfが複数回呼ばれるが,
        // apは最初に初期化されたきり
        len = vsnprintf(buf, size, format, ap);

        if(0 <= len && len < size) break;

        if(0 <= len) m_BufferSize  = len;
        else         m_BufferSize += BUFFER_SIZE;
        free(buf);
    }

    va_end(ap);
    return buf;
}

安全な例

char *test(const char *format, ...)
{
    int size;
    int len;
    char *buf;

    va_list ap;

    while(1){
        buf = (char *)malloc(size);

        va_start(ap, format); // ここで ap を初期化
        // vsnprintfが複数回呼ばれても,
        // 毎回きちんとapが初期化されている
        len = vsnprintf(buf, size, format, ap);
        va_end(ap);

        if(0 <= len && len < size) break;

        if(0 <= len) m_BufferSize  = len;
        else         m_BufferSize += BUFFER_SIZE;
        free(buf);
    }

    return buf;
}

ちなみに,32bitLinux*2FreeBSD*3ではダメな例でも問題ありませんでした.おそらく,va_listに関しての実装が変わっているのでしょう.

*1 : gcc (GCC) 3.4.4

*2 : gcc (GCC) 3.3.1

*3 : バージョン不明

2006/06/20(火)flockにおけるロック解除のタイミング

日本のLinux情報JM Projectによると,flockのアンロックは,

ロックの解放は、上記の複数のファイル・ディスクリプタのいずれかに対して明示的に LOCK_UN 操作を指示した場合か、これらのファイル・ディスクリプタがすべて閉じられた場合に行われる。

らしい.

fflush(fp);
flock(fileno(fp), LOCK_UN);
fclose(fp);

の場合,

fclose(fp);

だけで十分なようだ.

2006/06/12(月)zziplib

zziplibを使うにあたってのメモ。関数一覧は、こちら

分かりやすさのために、意図的に正確性に欠ける表現をしています。

使い方

  1. zzip_dir_openで zipファイル を開く
  2. zzip_dir_readで ファイルエントリ を順次読み出す
  3. zzip_file_readで ファイル を読み出す
  4. zzip_dir_closeで zipファイル を閉じる

関数リスト

ZZIP_DIR *zzip_dir_open \ (zzip_char_t *filename, zzip_error_t *e)

filenameで指定された zipファイル を開く。eには、エラー時のエラー番号が入るが、必要ない場合は、NULLを渡すこともできる。

int zzip_dir_read \ (ZZIP_DIR *dir, ZZIP_DIRENT *d)

dirで指定されたzipファイルからファイル/フォルダ情報を取り出し、dにファイル/フォルダ情報を入れる。dirは、zzip_dir_open等で開かれたzipファイルのポインタである必要がある。

int zzip_dir_close \ (ZZIP_DIR *dir)

dirで指定されたzipファイルを閉じる。

ZZIP_FILE *zzip_file_open \ (ZZIP_DIR *dir, zzip_char_t *name, int o_mode)

dirで指定されたzipファイルの中のnameエントリをo_modeで開く.\以下未確認ですが、o_modeには、ZZIP_CASELESSZZIP_NOPATHSのどちらか、あるいは両方を指定できる。{ZZIP_CASELESS}: ファイル名の大文字・小文字を区別しない{ZZIP_NOPATHS}: 圧縮ファイル中のフォルダ名を無視する** zzip_ssize_t zzip_file_read \ (ZZIP_FILE *fp, char *buf, zzip_size_t len)

fpが指すファイルエントリからbufへ、最大lenバイト読み出す。返り値は、実際に読み出されたバイト数となる。

int zzip_file_close \ (ZZIP_FILE *fp)

fpが指すファイルエントリを閉じる.

型リスト

ZZIP_DIR

ZZIP_DIRENT

ZZIP_FILE

zzip_char_t

zzip_error_t

zzip_ssize_t

2006/06/03(土)アプリケーションのインターフェース

http://www.atmarkit.co.jp/fwcr/rensai/usability01/01.html:@IT%20Web%e3%82%a2%e3%83%97%e3%83%aa%e3%82%b1%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%81%ae%e3%83%a6%e3%83%bc%e3%82%b6%e3%83%bc%e3%82%a4%e3%83%b3%e3%82%bf%e3%83%bc%e3%83%95%e3%82%a7%e3%82%a4%e3%82%b9

Webアプリケーションに限らず,一般的なアプリケーションに言えること.

自作プログラムのインターフェース,仕様について疑問を感じることも多々.プログラミングに関しての知識はあっても,ユーザーインターフェースに関しての知識はほとんど無い.ユーザの利便性を考えれば分かることかもしれないが,一度きちんと勉強してみたいところ.