初期設定
.profileを作成して、". .bashrc"行を追加

PATH=$PATH:/usr/ucb:/opt/sfw/bin:/opt/sfw/sbin/
export PATH

TERM=vt100
export TERM

alias cp='cp -i'
alias emacs='TERM=linux emacs -nw'
alias ls='ls -F'
alias l.='ls -ld .*'
alias ll='ls -l'
alias la='ls -lA'
alias mv='mv -i'
alias rm='rm -i'

PS1='[\h@\u \w]$ '
export PS1


ネットワークファイル
/etc/netmasks


バイス関係
/etc/driver_aliases
・ドライバエイリアス


システムコマンド
pkginfo
・パッケージ一覧(時間かかる)


sys-unconfig
・設定の初期化


inetadm
・inetdで起動されるサービスの情報


# inetadm -d svc:/network/telnet
telnetの停止


netstat
−P"protocol"

swap
スワップリソースの監視


システムファイル
・言語、タイムゾーン
/etc/TIMEZONE

・マウント情報
/etc/vfstab


Solarisコンテナ
Solarisゾーンの作成

sysconf()

POSIX では、アプリケーションがコンパイル時や実行時に、特定のオプションがサポートされているかや、設定可能な特定の定数や制限がどんな値かをテストすることができる。


以下が使用例

#include 

#define dprintld(expr) printf(#expr " = %ld\n", expr)

int
main(void)
{
     dprintld(sysconf(_SC_OPEN_MAX)); /* プロセスが同時にオープンできるファイル数の上限 */
     dprintld(sysconf(_SC_PAGESIZE)); /* バイト単位でのページサイズ */

     return 0;
}


実行結果

# ./a.out
sysconf(_SC_OPEN_MAX) = 1024
sysconf(_SC_PAGESIZE) = 4096

mmap

mmap()は、ファイルやデバイスをメモリにマップする。mmapを使用するとread()を使用しなくともwrite()が可能となる。つまり、バッファが不要となる。以下はファイル全体をマップする場合の例。


マッピングしたいファイルのサイズを取得する

     if (!(size = file_stat->st_size))
          return (0);

     if (size > SIZE_T_MAX) {
          err(0, "%s: %s", fname, strerror(EFBIG));
          return (1);
     }


mmap()をcallする。これにより、start番地からsize分のメモリ領域に、ファイル全体の内容が存在するとみなされる。

     /*
      * NULL      : NULLを指定すると、カーネルによってマッピングを作成するアドレスが選択される
      * size      : マッピングする長さ
      * PROT_READ : ページは読み込み可能である
      * MAP_SHARED: このマッピングを共有する
      * fileno(fp): マッピングするファイルのファイルディスクリプタ
      * (off_t)0  : マッピングを開始するするオフセット
      * 返り値    : 成功すると、マップされた領域へのポインタを返す。
      *             失敗すると、値MAP_FAILED (つまり(void *) -1) を返す。
      */
     start = mmap(NULL, (size_t)size, PROT_READ, MAP_FILE|MAP_SHARED, fileno(fp), (off_t)0);

     if *1;
          return (1);
     }

*1:start) == (caddr_t)-1) { err(0, "%s: %s", fname, strerror(EFBIG

ド・モルガンの法則

1. !(P || Q) = !P && !Q
2. !(P && Q) = !P || !Q


ド・モルガンの法則は多項でも成立するので、以下のような書き換えが可能。

(P || Q) && R → ( (!P && !Q) || !R))


以下理由。
まず、全体を否定する。

!( (P || Q) && R)


すると、法則2より、以下の書き換えが出来る。

!(P || Q) || !R


更に、法則1より、左項は以下の書き換えが出来る。

(!P && !Q) || !R


最後に全体の否定を否定して戻す。

!( (!P && !Q) || !R)

可変引数

関数は呼び出しに際して、個数や型が可変な引数をとることができる。インクルードファイル ではva_list 型が宣言されており、3つのマクロが定義されている。これらを用いると、呼び出された関数側では個数や型を知らない引き数のリストを、順に一つづつ読み込むことができる。


以下はサンプルコード

#include 
#include 


void
foo(char *fmt, ...)             /* ... は可変引数を表す */
{
     char     c;
     char    *s;
     int      d;
     int      n = 7;
     va_list  ap;

     /*
      * va_start()は、apを初期化し、va_arg() とva_end() で用いることができるよう
      * にする.
      */
     va_start(ap, fmt);

     /*
      * whileループでは、引数fmtから一文字ずつ読み込んで処理を行う.
      */
     while (*fmt) {
          switch (*(fmt++)) {
          case 's':              /* 対応する引数は文字列である. */
               /* 可変引数をchar*として取得する */
               s = va_arg(ap, char *);
               printf("%-*s: \"%s\"\n", n, "string", s);
               break;
          case 'd':              /* 対応する引数は整数である. */
               /* 可変引数をintとして取得する */
               d = va_arg(ap, int);
               printf("%-*s: %d\n", n, "int", d);
               break;
          case 'c':              /* 対応する引数は文字である. */
               /* 可変引数をintとして取得し、charにキャストする. */
               c = (char) va_arg(ap, int);
               printf("%-*s: '%c'\n", n, "char", c);
               break;
          }
     }

     /*
      * va_start() が実行される毎に、同じ関数内で対応するva_end() が実行されなけ
      * ればならない.
      */
     va_end(ap);
}

int
main(void)
{
     foo("sdc", "foo", 100, 'Z');
     return 0;
}

実行結果
 =====
 # ./a.out
 string : "foo"
 int    : 100
 char   : 'Z'

プリプロセッサの#記号

プリプロセッサ用の置き換えテキストの中で、パラメータ名の前に#記号が付いていれば、引用符付文字列に展開される。


つまり以下の文は、

#define dprintd(expr) printf(#expr " = %d\n", expr)
dprintd(n);


以下のように展開される。

printf("n" " = %d\n", n);


ANCI Cにおいて、隣り合う文字列リテラルは結合される為、最終的には以下のように評価される。

printf("n = %d\n", n);