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アプリケーションに限らず,一般的なアプリケーションに言えること.

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