d.sunnyone.org
sunnyone.org

ページ

2012-01-07

GNOME ShellのFavorites Barに好きなプログラムを追加する(2)

以前 GNOME ShellのFavorites Barに好きなプログラムを追加するとして手でデスクトップファイルを作る方法を書いたが、「lxshortcut」というコマンドを使うと、GUIで簡単に作れる。その方法は、以下のとおり。

<準備>
# apt-get install lxshortcut
名前のとおり、LXDEの一部だが、Gtk+関連くらいしか依存していないので、お気軽にインストールできる。

<使い方>
$ cd ~/.local/share/applications
$ lxshortcut -o example.desktop

これで編集ウィンドウが開く。↓みたいな感じ。

画面のとおり入れれば.desktopファイルができる。あとは同じようにアクティビティー・オーバービューから検索して、Favorites Barに乗せればよい。

2012-01-04

SheevaPlugを使ってScanSnap fi-5110EOXをネットワーク対応スキャナにする

タイトルはかなり大げさ。

うちにはfi-5110EOXがあるが、あまり使われていない。その理由は、いちいちWindows PCを立ち上げて作業をしないといけないからだと考えた。そうなのであれば、もっと手軽にスキャンできればよい。そこで、常時起動しているSheevaPlug (Debian入り)でスキャンし、共有フォルダに保存させることにした。
(なぜ「ScanSnap fi-5110EOXをDebian/Ubuntuで使う」をしたかというと、これがしたかったため。)

ベストな方式は、ScanSnapについているSCANボタンを押せば自動的にスキャンしてくれる方式。しかし、頓挫したためやめた(実装としては、scanbuttond, scanbdなどがあるようだ)。

そこで、スマートフォンのWebブラウザを使ってスキャンの指示をすることを考え、Web画面を適当に実装したところ、うまくいった。
スクリーンショットはこんな感じで、スキャンボタンを押すと、scanimageコマンドを起動してスキャンしてくれる。


副作用として、カラー/白黒や両面などのパラメータも指定できるようになった。

せっかくなので公開しておく。ダウンロードはこちらから:
https://code.launchpad.net/~sunnyone41/+junk/scanweb
bzr branch lp:~sunnyone41/+junk/scanwebするもよし、Browse the codeして全部同じディレクトリに
ダウンロードするもよし。ただし、HTMLが適当だったり、OSコマンドインジェクションできたりするので、使うときは適当に直して使うのが推奨。

ScanSnap fi-5110EOXをDebian/Ubuntuで使う

ScanSnap fi-5110EOXをLinux (Debian/Ubuntu)で使う方法。
ご想像のとおり、saneを使うだけ。

<準備>
scanimageがあれば良い。したがって、
# apt-get install sane-utils
これでOK。あとはつなげばスキャンできる。ただ、あとの準備として以下を入れておく。
# apt-get install imagemagick poppler-utils

<スキャン>
xsaneを入れてあれば、それでも良いし、上述のsane-utilsであればscanimageが使える。
使い方は以下。
/usr/bin/scanimage --batch --source "ADF Duplex" --mode Color --resolution=190 --y-resolution=190 --format=tiff
これでカレントにout1.tif, out2.tifという感じででてくる。ADF Frontで表だけにしたり、Grayで白黒にできたりするが、そこはscanimage --helpを参照。resolutionを190としたのは、これ以上大きくすると紙をフィードしてる途中でスキャンが止まってしまうから。
ここはちょっと残念だが、実用範囲なのでOKとする。

<画像変換>
1枚1枚の無圧縮TIFFファイルができるので、ImageMagickでJPEG圧縮してPDFに収める。
convert -compress JPEG -quality 85 -adjoin `ls -1 *.tif | sort -t t -k 2 -n` out.pdf
これでout1.tif, out2.tif, out3.tif... がout.pdfにくっつく。

sort -t t -k 2 -nは順番に並べるためのものだが、少々トリッキーなので説明しておくと、
outN.pdfのNが桁数固定でないので、ただのsortでは順番に並ばない。
普通の1,2,3,...10,11,...であれば-nを使えば数値順に並べられるが、out10.pdfなどという形なので、
それもできない。しかし、ou「t」の「t」をフィールドセパレータと見立てて、2番目のフィールドを数値から始まるようにした後、数値順でソートすればソートできるというわけだ。

これでコマンドラインでのスキャン作業はおしまい。結構簡単であった。
参考:sasasin.net/diary
OpenCVが面白そうなので、そのうちチャレンジしてみようかな。

<おまけ:画像取り出し>
もしPDFに入ったJPEGが欲しくなったら、convertで取り出せるかと思ったが、普通に
convert out.pdf out.jpgとすると、画像サイズが小さくなってしまう。
そこで、poppler-utilsに付属しているpdfimagesを使う。
pdfimages -j out.pdf image
こうすると、image-001.jpgなどという形で、JPEGファイルを切り出せる。

参考:Extract images from a PDF document | Stefaan Lippens' webface

2011-11-30

Solaris/x86のスタック領域がなぜ低位に確保されるのか?

藤原さんの「理解した気分になる Solaris Internals "Chapter 9: Virtual Memory" 総ざらえ」の疑問
x86 のスタック領域がアドレス低位に確保されるのは、 Solaris 固有の話?それとも他の OS でも共通の、CPU 固有の話?
の答え、ちょっと調べた感じだと、どうも歴史的なもののようです。
(質問の回答としては、Solaris固有ではないが、CPU固有といえば固有、他のOSでも共通かどうかは不明というところでしょうか。)

まず話を聞いていない人向けに書くと、Solaris/SPARC(32bit,64bit)やSolaris/x64はそんなことないのに、
Solaris/x86だけ、スタックが妙に低いアドレス(0x8048000)から伸びているけどなんぞ、というお話です。
cf. Solaris Internalsの図

このアドレスがキーなのかと思って検索してみたらどうもそうのようで、このアドレスは
ELFのエントリポイントの模様。

リンカとかローダの話ですかと思って手元の「Linkers & Loaders」を調べてみたら、まさにそれっぽい記述を見つけました。
ELFがa.outと異なるのは、オブジェクトを0番地付近ではなくアドレス空間の中程にロードして、スタックがテキストセグメントの下位から成長し、ヒープがデータセグメントの終端から成長するようにすることによって、全体として利用するアドレス空間が比較的小さく済むようにしている点である。386システムでは、テキストのベースアドレスは0x08048000で、テキストの前の0x08000000以降の部分に十分に大きなスタックを確保できると同時に、ほとんどのプログラムでは第2レベルのページテーブルは1つだけで済む(386においては、1つの第2レベルテーブルで0x00400000のアドレスをマップできる)。
決めた時代的には、ここに置くとアドレスがいい感じだったということのようですね。

なおこれを決めたのは「Re: is not 0x8048000 too wasteful?--about virtual address layout」によると、
There is folklore that 0x08048000 once was STACK_TOP (that is, the stack
grew downwards from near 0x08048000 towards 0) on a port of *NIX to i386
that was promulgated by a group from Santa Cruz, California. This was
when 128MB of RAM was expensive, and 4GB of RAM was unthinkable.
ということで、1983年のSCOでしょうか。

ちなみに、Linux/x86 (2.6)は上記場所にスタックはできないようです。


なお、もっと詳しい方がいればブログなりでフォローいただければ修正します :)

ちなみにこの「Linkers & Loaders」、ひさびさに読み始めてたのですが、本を見ると2001年初版。出た当初に買ったはず(だいぶ色あせてる)なので、10年後にまた読むとは。前知識なしで読むと全然わからない(10年前がそうだった)ですが、最近のx86やらOSやらの勉強でようやくわかるようになってきました。
Amazonの評価はよくないですが、これだけ一通り書いてあってもし読みやすい本があれば是非知りたい感じです。

2011-11-11

GNOME ShellのFavorites Barに好きなプログラムを追加する

GNOME Shellのアクティビティ・オーバービューの左側にあるバー(Favorites Bar?)に、
メニューにでてこないアプリケーション(~/binに入っているやつとか)を登録するには、
手で.desktopファイルを作って(!)メニューに出せばいいようだ...

手順。ここではV2Cというアプリを例にする。

1. 適当な.desktopファイルを/usr/local/share/applicationsからコピる
cp -p /usr/share/applications/firefox.desktop ~/.local/share/applications/v2c.desktop
(Firefoxはいろいろ書いてあってあまりいい例ではないかも)

2. コピってきた.desktopファイルを編集する
vi ~/.local/share/applications/v2c.desktop


3. アクティビティ・オーバービューでNameに書いた名前を入力し、アイコンが表示されたらFavorites Barにドラッグアンドドロップ

これで登録できる。でてこなかったらAlt+F2と「r」でいったんGNOME Shellを再起動すればいいかも。

参考:http://askubuntu.com/questions/40382/how-to-add-a-folder-to-the-favorites-bar-in-gnome-shell

2011-11-01

strlen(...) > 0とstrlen(...) != 0はどちらが速いか?

うまい文にならなかったが、貴重な結果なので以下にまとめておく。

Loquiでtopicを空にしようとしてもできない、というバグを発見して対応を施した際、
strlen(str)は>0がよいか? != 0がよいか?という話になり、今のご時世問題になるわけのない、
「どちらが速いのか」が話題になった(というかした)
(バグは対策済み:対応内容はこちら https://bugs.launchpad.net/loqui/+bug/689164/comments/3)

結論としては、出力結果が同じになるので、速度は変わらない。しかし、変わらない理由が驚きであった。

話題となるのはこの部分:


上記の部分が入ったソース(irc_message.c)をgcc -Sでアセンブルし、if文のところを抜き出した結果がこちら:


前述の通り、strlen(...) > 0をstrlen(...) != 0にしても、出力結果は変わらないのだが、問題は
出力結果。strlenをコールしていないどころか、これではstr[0] != '\0'のようである。

strlen()の定義を追うと、eglibc-2.13/sysdeps/i386/i486/bits/string.hにあった:


このコードが使われている感じではないので、実際に使われているのはおそらくgccのbuiltin...
どうやらgccがstrlen(...) > 0自体を解釈しているようである。驚くべきgcc.

ちなみに、-O0でも一緒であるが、-fno-builtinをつけるとちゃんとstrlenをコールしてくれる:


まぁ、それでもsize_tがunsignedだったので、結局>0と!=0は出力結果は同じなのであったが。

2011-08-30

OpenIndianaでvirtionetドライバを使ってみる

KVM (CentOS 5.x)の上でOpenIndianaを動かしているが、どうもネットワークがおかしい。
KVMのpara virtualドライバであるところのvirtioドライバがあればきっといいのだろうと思って探してみると、それっぽいものを発見。
https://github.com/grigale/solaris-virtio

一昨日pkgコマンドを触ったばかりの人間には妙にハードルが高いが、さっそく入れてみる。
Linuxでいうところのmakeしてinsmodするくらいのノリでいけるんだろうと期待。

まずコンパイラがないので入れる。きっとSun Studioとやらが必要だ。

$ pkg search sun studio

sunstudio12u1というのが見つかったので、インストール。

$ pkg install sunstudio12u1

ccコマンドが使えるようになった。

そしてコンパイル。

$ tar zxvf grigale-solaris-virtio-07c22ec.tar.gz # Solarisのくせにzオプションが使える

$ cd grigale.../usr/src/uts/common/io/virtio/

$ make

$ make install


あっさり/usr/kernel/drv/amd64とかに入った感。

しかしドライバをシステムに認識させないといけない。
http://kohju.justplayer.com/Tips_Solaris_OpenSolarisOS_forlinuxuser_adddevice.html

virtioのNICのIDがなんだかわからなかった(prtconfの結果を読むのが面倒だった)ので
他のLinuxマシンでlspciするというチートを使った。
# lspci

~~

00:03.0 Ethernet controller: Red Hat, Inc Virtio network device

~~

# lspci -n

~~

00:03.0 0200: 1af4:1000

~~

きっとpci1af4,1000でいけるに違いない。
# sudo /usr/sbin/add_drv -n -v -i "pci1af4,1000" virtionet

Reboot client to install driver.

Driver (virtionet) installed.

リブートしろと言われたのでリブートする。

$ sudo dladm show-link

LINK CLASS MTU STATE BRIDGE OVER

e1000g0 phys 1500 up -- --

e1000g1 phys 1500 up -- --

virtionet0 phys 1500 unknown -- --


キター!

$ sudo ifconfig virtionet0 plumb

ifconfig: cannot plumb virtionet0: Could not open DLPI link


だめでした。

ちなみにprtconf -vの当該部分