トップ «前の日記(2010-08-09) 最新 次の日記(2010-08-11)» 編集

ヨタの日々

2001|08|09|10|11|12|
2002|01|02|03|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|12|
2024|01|02|03|04|

2010-08-10 :-)

_ ,

agumon さんがレースネタを構想している

_ [NetBSD][PDP-11][翻訳]hubertf's NetBSD blog - Of course it runs ... 2.11BSD (or: PDP-11 in a FPGA)

It's about time NetBSD gets the PDP11 port done: the PDP-11/70 CPU core is now available as implementation on a FPGA-board, and there's need for a newer operating system than 2.11BSD! Citing from the homepage:

NetBSD への PDP11 移植がようやく終わった。PDP-11/70 CPU core が FPGA ボードで実装されたのだ。2.11BSD より新しいオペレーティングシステムならば動くんだぜ!homepage より引用:

``The project contains a complete PDP-11 system: a 11/70 CPU with memory management unit, but without floating point unit, a basic set of UNIBUS peripherals (DL11, LP11, PC11, RK11/RK05), and last but not least a cache and memory controllers for SRAM and PSRAM. The design is FPGA proven, runs currently on Digilent S3BOARD and NEXYS2 boards and boots 5th Edition UNIX and 2.11BSD UNIX. ''

このプロジェクトの目的には PDP-11 を完全に実装することがある: 11/70 CPU でメモリマネージメントユニット( ただし浮動小数点演算ユニットは除く )、基本的な UNIBUS ペリフェラル(DL11, LP11, PC11, RK11/RK05) のセット、そして最後に、これが重要なのだが SRAM と PSRAM のキャッシュコントローラーとメモリーコントローラーだ。この設計で Digilent S3BOARD と NEXYS2 ボード FPGA で実装できたし、5th Edition UNIX と 2.11BSD UNIX で起動できた。

_ ,

うーさーのひとってたしか 10 年くらい前に獣姦ビデオ鑑賞オフなどというものをおこなってブルーになってたひとじゃなかったっけ

_ HTML の a href= で指定したファイル名を小文字に変えたいだけなんだよ

gsub イッパツというわけにはいかないのか。

#!/usr/pkg/bin/ruby

while gets
        if $_ =~ /(.*)(<a href=")(.*)(">)(.*)/
                puts "#{$1}#{$2}#{$3.downcase}#{$4}#{$5}"
  else
                puts $_
  end
end

_ ファイル名メンテナンス

メモ に置いてあるファイル自体の名前をすべて小文字にしてしまった割りに index.html に書いてあるファイル名はそのまま大文字小文字混在だったので書き直すなど。

_ 散歩

広角で遊ぶなど

IMG_4935

_ [リッジレーサー7]リッジレーサー7

オンラインバトルなど。B2ェ....

  • 走行距離 97318 km
  • RSGP 進行度 100.0 %
  • 名声 24885 FP
  • オンラインバトル勝利数 929/3387

_ [QuickML][コードリーディング][Ruby]QuickML を読む - 概要

QuickML とは、高林哲さんが書いたメーリングリストシステムである。うちでも使っている。ありがたいことである。

横着プログラミング 第5回: QuickML: 超お手軽なメーリングリスト

QuickMLは

  • メーリングリストを作るのが面倒
  • メーリングリストを管理するのが面倒
  • コマンドメールを覚えるのが面倒
  • Web上のフォームにあれこれ記入するのが面倒

といった面倒さを解決し、いつでも、どこでも、誰でもお手軽にメーリングリストを活用できるシステムである。

ソースコードはこちら→ quickmlサーバ: 超お手軽なメーリングリストシステム

なお手前味噌ながら作業ログはこちら 同一ホスト上で qmail と QuickML を動かす手順 同一ホスト上で Postfix と QuickML を動かす手順

_ [QuickML][コードリーディング][Ruby]QuickML を読む - quickml-ctl

QuickML の起動処理について読んでいく。

ソースコードをダウンロードし、展開すると configure や Makefile.in などがあることが分かる。QuickML のインストールは ./configure && make && make install すればよい。

起動させるときは quickml-ctl を実行する。quickml-ctl を読んでみる。

#! /bin/sh
start() {
        echo -n "Starting QuickML services: "
        /usr/local/sbin/quickml
        echo
}

stop() {
        echo -n "Stopping QuickML services: "
        kill `cat /var/run/quickml.pid`
        echo
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        sleep 1
        start
        ;;
  *)
        echo "Usage: quickml-ctl {start|stop|restart}"
        exit 1
esac

exit 0

起動だけでなく終了、最起動するときも quickml-ctl を使う。quickml-ctl start、quickml-ctl stop などして実行する。

quickml-ctl に渡された start, stop, restart に応じて各々処理する。

quickml-ctl start すると /usr/local/sbin/quickml を実行し、quickml を開始する。/usr/local/sbin/quickml の場所は configure したときに決まるのでこの PATH ではない場合もある。

_ [QuickML][コードリーディング][Ruby]QuickML を読む - quickml

/usr/local/sbin/quickml を読んでみる。

まずはスクリプト冒頭。

$KCODE = "e"
require 'quickml'

require 'quickml' で lib/quickml.rb を読み込んでいる。lib/quickml.rb はこうなっている。lib/quickml/* のファイルを読み込んでいる。

require 'quickml/utils'
require 'quickml/config'
require 'quickml/core'
require 'quickml/gettext'
require 'quickml/logger'
require 'quickml/mail'
require 'quickml/server'
require 'quickml/sweeper'
require 'quickml/version'

/usr/local/sbin/quickml に戻る。main() を読む。

def main (argv)
  config_file = if argv.length == 1 then
                  argv.first
                else
                  File.join("/usr/local/etc", "quickmlrc")
                end
  config = QuickML::Config::load(config_file)
  check_directory(config.data_dir)

argv には Ruby 定数 ARGV がそのまま入る。quickml-ctl を使った場合 ARGV は空である。よって config_file は /usr/local/etc/quickmlrc になる。/usr/local/sbin/quickml hogehoge.rc などとすれば別の設定ファイルを読み込ませることができる。

その /usr/local/etc/quickmlrc を QuickML::Config::load(config_file) により読み込み、config を作成している。config については後述する。

config.data_dir を check_directory() でチェックしている。check_directory() はこう。

def check_directory (dir)
  error("#{dir}: No such directory") unless File.directory?(dir)
  error("#{dir}: is not writable")   unless File.writable?(dir)
end

dir がディレクトリでないか、または書き込み可能でない場合は error() を呼んでいる。error() はこう。

def error (msg)
  STDERR.puts "#{$0}: #{msg}"
  exit(1)
end

標準エラー出力にプログラム名とメッセージを印字し、終了する。$0 は現在のプログラム名を表す Ruby 変数である。

check_directory() の次は be_daemon() と be_secure() を呼ぶ。

  be_daemon
  be_secure(config)

be_daemon() を見る。

def be_daemon
  exit!(0) if fork
  Process::setsid
  exit!(0) if fork
  Dir::chdir("/")
  File::umask(022)
  STDIN.reopen("/dev/null",  "r+")
  STDOUT.reopen("/dev/null", "r+")
  STDERR.reopen("/dev/null", "r+")
end

プログラム自身をデーモン化させる処理である。デーモン化させる手順は一般的にはこう。

デーモン ‐ 通信用語の基礎知識

1. fork()して、親プロセスを終了させる。こうすると、シェルに制御が戻る。
2. setsid()により、プロセスグループとセッショングループのリーダーになる。
3. 再びfork()し、親プロセス(セッショングループリーダー)を終了させる。
4. chdir("/")し、どのディレクトリも使用中でないことを明確にする。これを忘れると、ファイルシステムのアンマウントが出来なくなることがある。
5. umask(0)して、以降作成されるあらゆるファイルを支配下に置く。
6. ファイルディスクリプタの0、1、2をclose()する。親プロセスから引き継いだ、リダイレクト先不明の標準入出力は使用しない。
7. stdin、stdout、stderrは、自分で新しいディスクリプタとしてopen()する。

詳しいことは詳解 UNIX プログラミングを読むなどするとよい。

なお、Ruby 1.9 には Process.daemon が実装させているのでたんにこれを呼べばよい。

次に be_secure() を見てみる。

def be_secure (config)
  return unless Process.uid == 0
  uid = Etc::getpwnam(config.user).uid
  gid = Etc::getgrnam(config.group).gid
  touch(config.pid_file)
  touch(config.log_file)
  File.chown(uid, gid, config.data_dir)
  File.chown(uid, gid, config.pid_file)
  File.chown(uid, gid, config.log_file)
  Process.uid  = uid
  Process.gid  = gid
  Process.euid = uid
end

関連するファイルの UID と GID と 実効UID を config で設定した user と group に設定している。config については後述。

main() の最後。

  server  = QuickML::Server.new(config)
  sweeper = QuickML::Sweeper.new(config)

ここで server と sweeper を起動している。server は QuickML のメーリングリストとしての動作を請け負う。sweeper はメーリングリストの有無やユーザーの有無などを処理する。

  trap(:TERM) { server.shutdown; sweeper.shutdown }
  trap(:INT)  { server.shutdown; sweeper.shutdown }
  trap(:HUP)  { config.logger.reopen }

プログラムに TERM シグナルまたは INT シグナルが送られたときは server と sweeper を終了させ、HUP が送られたときは logger を reopen する。この辺りは後述。

  t = Thread.new { sweeper.start }
  t.abort_on_exception = true
  server.start

sweeper スレッドを生成し、server も開始させる。abort_on_exception は以下のように働く。

真の時は、いずれかのスレッドが例外によって終了した時に、インタプリタ全体を中断させます。デフォルトは偽、すなわち、通常あるスレッドで起こった例外は、Thread#join などで検出されない限りそのスレッドだけをなにも警告を出さずに終了させます。