libiconvを通して楽しようかと思ったけど、なんか小回りが利かないように見える。
UTF-8→UCS-2の範囲でデコードして、そこからwchar16_tにデコードするテーブルを用意した方が良いんじゃないかなあ。UCS-4になるものは対応しない(〓にする)方針で。
テーブルの作成はlibiconvを使って、なんか適当にこしらえることにすれば良いかなと。
あまり頭の良い方法ではないのだけど、「とりあえず動かす」のにwchar16_tをごちゃごちゃ書き換えるのはかなり荷が重い。
OpenBSD(uaa@), Ham(JG1UAA), Ingress(Lv14, RES), Japanese(Sagamihara-city, Kanagawa)
Another side: https://social.tchncs.de/@uaa
npub1rarr265r9f9j6ewp960hcm7cvz9zskc7l2ykwul57e7xa60r8css7uf890
Messages from this Mastodon account can read via mostr.pub with npub1j3un8843rpuk4rvwnd7plaknf2lce58yl6qmpkqrwt3tr5k60vfqxmlq0w
libiconvを通して楽しようかと思ったけど、なんか小回りが利かないように見える。
UTF-8→UCS-2の範囲でデコードして、そこからwchar16_tにデコードするテーブルを用意した方が良いんじゃないかなあ。UCS-4になるものは対応しない(〓にする)方針で。
テーブルの作成はlibiconvを使って、なんか適当にこしらえることにすれば良いかなと。
あまり頭の良い方法ではないのだけど、「とりあえず動かす」のにwchar16_tをごちゃごちゃ書き換えるのはかなり荷が重い。
なるほどね、wchar16_tだと、
0x00-0x7f : ASCIIと同じ
0x8ea1-0x8edf: 半角カナ
それ以外においては
(code & 0x0080) ? 普通のEUCコード : (SS3修飾されたもの & 0xff7f)
という手法で、16bitの範囲にEUC-JPを押し込んでる。
あと、eucmessages.c、現状のままだとデバッグが非常に困難になるからソースコードの文字コード(UTF-8)でメッセージを記述して内部ではEUC-JPにするとかいうのはどうなんでしょうかね。
SJ_read()
current_locale == LC_TYPE_云々→io_locale == LC_TYPE_云々
UTF-8/EUC-JP/sjisに分けて処理
UTF-8の場合のみ、mbstowcs()の前にiconvでUTF-8→EUC-JP(mbs)変換
SJ_write(), SJ_print()
io_locale = UTF-8の場合のみ、wcstombs()の後にiconvでEUC-JP→UTF-8(mbs)変換
mbstowcs(), wcstombs()自体には手を入れない(影響範囲が広くなりすぎるため)
あとはwrite_stdout()の対応か。コードを見るに、1文字を構成するようなmulti-byte characterが揃うまで(という日本語で意味が通じるだろうか?)標準出力への対応を遅らせるというもののように見える。ここのIsknj2(), Isknj1()がEUC-JP向けなので、これはそのままになるんだろうけどUTF-8化にあたって何かケアが要るかもしれない(とはいえ、Shift-JISはそのままスルーになるのは何故)?
細かい問題が多少残ってはいるのだけど、現状のsj3(tty client)の作業は一旦ここで止めて、ブランチ切ってUTF-8化の検討に移ろうかなあ。何しろ画面に文字がちゃんと出ない方が面倒で…
なんとなくだけど、sj3捨ててkinput2とかuim越しにsj3serv使おうと言っている人達の気持ちは分かってきましたよー…
この辺の動作の詳細はstat_conv.cのstat_conv()に全部書かれてるな。
always_buffが真なら常にbufferモード(設定方法は後で調べないといけない)。
決定キー→unbufferに切り替え
変換キー→bufferに切り替え
半角決定キー(?)→unbufferに切り替え
という動作に見える。
やっぱそうだよなあ、stat_conv.cのChangeBuffMode()を見るに、buffer/unbufferの動作はトグルになってる。ということはbufferモード切替キーを押すごとにbuffer/unbufferが切り替わらないといけないんだけどそれ以前に.sjrcに.key.bufferの設定がコメントアウトされてる。(じゃあ何故全角かな入力モードにしたらbufferモードになったままになる?)
うえぇぇええ?(ktermだけCtrl-L時にステータスラインを保持、xterm, mlterm, rxvtは保持しない…というかrxvtはウィンドウサイズが取れないのかステータスラインの表示位置がおかしい)
sj3原典をVine 2.5上のktermで動かしちゃみたんだけど、Ctrl-Lで画面クリアしても一番下のステータス行はクリアされずに表示されてる。mltermだと消えてしまうので端末エミュレータの問題かも。
Bufferモードで、未確定文字列に対して適当にカーソルキーを叩いた場合の移動処理(とでもいうのかなあ)とそれに対する表示がなんかあってない感じはOpenBSD/amd64上での動作でもそうだったのでこれは元からアレだったっぽい。
ssh越しにsj3を起動して、未確定文字列がある状態でBSを叩くと確定してしまう(Ctrl-Hでは確定しない)というのはssh越しでの現象で、kterm上では起こらない。
うーむ、色々と怪しげな感じですなあ。
Buffer modeにおけるカーソルキーの挙動が怪しい
Buffer modeにおけるCtrl-Hの挙動も怪しい
なんだろね、表示だけがおかしいのか編集結果がおかしいのかを調べないといけないんだけど…
そもそもBuffer mode/Unbuffer modeとかその辺の使い方も分からないというのが、なんとも。
ふーん、Beepyって保護フィルムが出るくらいには知られてるものなのか。楽天で売られてるみたいだし。 https://product.rakuten.co.jp/product/-/581d4fe3f3fb6215dde28da22ad6c80a/ (2023/10/30)
やっぱこーゆうPDA(Xが動かなくてttyだけしか表示しないような奴)でfbtermとか使って日本語表示して…というのは、自分は欲しいかも。
このアカウントは、notestockで公開設定になっていません。
あー、T-TWR(じゃないとWiFiが載ってるので技適警察が一緒になって大騒ぎするから遊べない)売り切れか…
https://www.lilygo.cc/products/t-twr
LILYGOで売ってる無線機のキット。WiFi搭載のT-TWR Plusはまだ売ってるけどさあ…
https://www.lilygo.cc/products/t-twr-plus
やっぱこの手のキットは見たら買えするのが正解なのか。
とりあえず、sj3(tty client)に関する、対処が必要なwarningで残ってるやつはscreen.cとedit.cのみ、かなあ。他のは-Wno-format-securityで無視させたい。
むしろそれ以外で多発してる-Wincompatible-pointer-typesをどう潰すか考えないといけないような。
clangでwarningが出ないからといって、gccで出ない保証も無いっていうのも考えないといけないよなあ…
ん-、でも参照されてない、メモリ喰うだけーなオブジェクトを残したまんまというのが適切かというのもあるよね。stringsで中身見られた時に/export/work/contribうだうだ/ほげふが.cな文字列が出てきて嬉しいかというと…多分嬉しくないような。
そもそも、大概のは$SonyRCSfile:で管理されている(ようで管理されていない)のに、これに加えてrc_conv.cとsj3dic.cはrcsid[]で$Header:~な文字列が定義されている。
__attribute__((unused))の方が((used))よりも適当なのかもなあ。
rcsidについては__attribute__((used))の追加が良さそうなんだけど、どうなんだろう?
https://gcc.gnu.org/legacy-ml/gcc-help/2013-09/msg00109.html
edit.cについては今朝呟いた通りなので省略(実はまだ答え出てない…assert突っ込んでも良いんだけど)。
eucmessage.cの-Wunused-variableについては__sony_news絡みなのでばっさり削っても良い気がする。UTF-8対応とかその辺の時に対処すればいいだろうから現状は放置?
sjrc2.c: sjset_code()のchar *loc;は削って大丈夫。
rk_conv.cのrcsidが-Wunused-variableに引っかかるのはどうしたもんだろう。他でも確かRCSのidは引っかかってたはずなので、引っかかりにくい記述法に置き換えないといけないのかも。
toroku.c: sprintf()の-Wformat-secutityについては不問かなあ。eucmessages.cに定義されてるのが書式付きのメッセージでありこれを参照してる、というのが理由。etc.cについても同様。
sj3:toroku.c getkstr()のfor (i = 0 ; i < plen && i < lim ; i ++)のplenが未初期化かもよーのwarning、これは流石にplen=0の初期化で良い気がする。plenだけでなく、コピーする実体の入ってるtmpだって初期化されてない(からっぽのままだ)し。
Mastodon上のアマチュア無線クラスタが存在するのかどうかは知らないのですが(とはいえmastodon.radioとかありますよねえ)、こちらではお互い平和に暮らしたいものです。
どこかの違法局狩り/不法局狩りの人みたいに、気に食わない発言なり引用RTなりするとすぐブロックするような人はXに是非ともとどまって頂き、他SNSへの進出は控えて頂ければと。
あんまりこっちで迂闊にアマチュア無線の話とかすると、X上で刺されそうな悪寒。
そうそう、アマチュア業務って「金銭上の利益のためでなく、もつぱら個人的な無線技術の興味によつて行う自己訓練、通信及び技術的研究その他総務大臣が別に告示する業務を行う無線通信業務をいう」
その他総務大臣が別に告示する業務、が昨年から追加されているので注意が必要です(これに対しては結構反発が強いです…Xのアマチュア無線クラスタとかでは)。
気軽に電波でおしゃべりを楽しむなら、今だとむしろフリラ(特定小電力とかの、免許不要なトランシーバー)の方が良さそうに見えるけどどうなんだろうなあ。
AliExpressとかで売ってる怪しげな無線機(とかモジュール)で遊ぶならアマチュア無線しかないんだけど、現状の免許申請に絡むシステムがシステムなのでなんかもうどうでもいいや…
同一コール間の通信ができないことの問題点として…たとえば無線LANみたいなものを想像してほしいんだけど、無線機とホットスポット(スマホとWiFi-アクセスポイントみたいなもの)間の通信を行う場合に別々のコールサインを用意しなければいけないってことを意味するんです。
ホットスポット側は社団局(クラブ)で免許を申請せよ、というのが今の流れなんだけど…クラブ作るのに人間集めろっていうのは、ぶっちゃけ「ぼっち排除」なんですけど…正直これってどーなのって思うんですよね。
新しいプロトコル開発のために免許を申請するにしても、通信相手も一緒に免許を申請してね♡(ぼっちは絶対に許さん)という現状なので、「何がワイヤレス人材の育成だよ💢」というのが自分の正直な感想。
分かる。とはいえM2Mな通信用途とかはあんまり考えてくれてなくて、同一コールサイン間の通信(自分の配下にあるノード間の通信、とでも言えば良いか)は一切認めないと総合通信局が言ってるんですよね。(※)
なーにが「ワイヤレス人材の育成」だよ!💢
(※)以前は移動する局・移動しない局間なら別の無線局として扱わるから黙認されてる部分もあったんだけど、昨年明確にこれを否定するコメントが出てしまったんですよね。
このアカウントは、notestockで公開設定になっていません。
同意。とはいえ今回は自分の書いたコードじゃなく随分昔に書かれて埃まみれ(と敢えて書く)なコードなので、迂闊にassert()突っ込んで良いものかという判断も必要…。バグった時に落としてるような箇所が大量にあれば遠慮なく入れるんだけど、どこにもないという。
まあ、どう動くか信用できんし遠慮なく入れとくか♪で良いのかも。
私は assert 入れまくってじゃんじゃんクラッシュさせろ派なんだけど ( https://blog.cardina1.red/2019/12/19/dont-fear-the-panic/ )、まあユーザには不評だろうなというのもわからんでもない。
狂ったまま何が悪いのか明かされず動き続けて困るよりもマシではと思ってしまうが……
C++って使いやすくなってるよなーというのがC屋の率直な感想(その分難解な箇所もあるけど)。
switchに与える値については他の関数がしっかり設定しているので問題は無いはず(むしろswitchを通した後に未初期化の値が出るかもー?ってコンパイラに怒られてるのをなんとかしようとしてるところでして)
assertで落としちゃうのが良いのかもなあ。変数の初期値を適当に書いちゃうとして。
意味のない(そのパスを通る可能性のない)default節は削りたいと思う反面、万が一そのパスを通った場合にどうするのという不安もあったりする。落とすのが良いのか、不安定でも何となく動いているのが良いのか…
超絶自明ならこいつらを使うけど、そうでないなら素直にメッセージ吐いて abort すべきなのかもしれん。
unreachable - cppreference.com
https://en.cppreference.com/w/c/program/unreachable
こういうのは assert(false && "should never reach") なり unreachable() なりを挿しておくのが定石かと思ったが、 assert() は debug build でしか効かないし unreachable() は C23 からだった……
common.cのGetConversion()でcv->BuffModeの初期値はBUFFに設定済。コード中ではBUFFかUNBUFFしか設定しないので、screen.cのdisp_mode()内にあるswitch(cv->BuffMode)のdefault節は通らない。なのでこれによりBmodeが未設定になるかもよーというwarningは正しくない。
default:
/* NOTREACHED */
break;
でもwarningは出るけど、default節そのものを取り払うと出なくなるので取り払うのが適当か。取り払ったところでBmodeが未設定のままになるという状況は変わらないのだし。
やっぱ二種とか一種(情報処理技術者試験)は有効期限切れという扱いで良いのか。
このアカウントは、notestockで公開設定になっていません。
問題のコードはcase 'h':, case BS:で出てくるんだけど、他のcase('x'とかDELなど)だと
if (Zcol >= len && Zcol >= 1) {
backspace(2);
Zcol -= 1;
}
という形になっているので、おそらく{}の付け忘れという可能性は高いと思う。
とはいえ、確信が持てないからもう少しコードを読まないといけない。
思い出せなかった「何か」、見つけた。kinput2とSj3を使いこなすためのページ http://www.tk2.nmt.ne.jp/~artrec/ar-sj3.shtml にBSD256倍本くらいでしかsj3が紹介されていない、という記述を見たからだ。
@redbrick 現状のコードだと、for()の後にあるbackspace(2);しかループの対象にはならないんです。最近のコンパイラってちょっと気が利いてるのかは分からないんですが、その後にあるZcol -=1;のインデントから「そのコードもループ対象になってたりしませんかね?」と警告してくれるので、これはどうしたもんかな…と。
確かに何の処理をやっているか理解しないと、安直にループに含めて良いかどうかの判断はつかないです(この処理の周辺が結構ぐちゃぐちゃで追うのも結構大変だったりします)。
Ctrl-CじゃなかったCtrl-Lに対するシグナルってなんかあるのかなあ。
sj3、Ctrl-Lを押して画面を消去するとステータスライン(ファンクションキーの状態表示)もまるっと消えてしまうんだけど…これで良いのかなあ。原典でもこれは起こるんだけど。
ファンクションキーを叩くとか、xtermのウィンドウリサイズで復活はするんだけどね。
edit.cのwarningが出る、exec_edit()の
for (i = 0 ; i < num && Zcol >= 1 ; i ++)
backspace(2);
Zcol -= 1;
Flush ();
このコード、どう扱ったもんかね。
for (i = 0 ; i < num && Zcol >= 1 ; i ++) {
backspace(2);
Zcol -= 1;
}
Flush ();
とするのが良いのかどうか…
Linuxだとncurses.hとcurses.hのdiffとっても同じもんなのね
とーこーろーがー、NetBSDはcurses.hが標準なのでしたー💢💢💢💢💢💢💢💢
DragonFlyBSDの場合、-I/usr/include/priv/ncursesが必要、libtermcapが無いのでそれに代わる何かをリンクする必要があるけど…うーん、一旦DragonFlyBSD対応は置いとく。FreeBSDのコードのままでコンパイルが通ることは確かなので(リンクとincludeのパスの問題だし)。
とはいえ、curses.hではダメなので、ncurses.hへの切り替えは考えとかないといけない。
uaa@dragonfly-vm:/usr/include % find .|grep curses
./priv/ncurses
./priv/ncurses/ncurses_dll.h
./priv/ncurses/unctrl.h
./priv/ncurses/panel.h
./priv/ncurses/term.h
./priv/ncurses/ncurses.h
./priv/ncurses/curses.h
./priv/ncurses/termcap.h
uaa@dragonfly-vm:/usr/include %
これはどうしろと…?
display.c:43:10: fatal error: curses.h: No such file or directory
#include <curses.h>
^~~~~~~~~~
compilation terminated.
gmake: *** [<builtin>: display.o] Error 1
uaa@dragonfly-vm:~/sj3 %
ぐあああああああ><
このアカウントは、notestockで公開設定になっていません。
「しげき」、「刺激」読みしてたんだけど多分これって「茂樹」みたいな人名のアクセントで読むやつですよね?
このアカウントは、notestockで公開設定になっていません。
utmp周りの動作確認用に、グループutmpに自分自身を入れることに。セキュリティ面からはどうなんだろうこれ…(テスト用なのでテストが終わったら外せば良いんだけど、忘れることもあるだろうというか多分忘れる)。
sj3、Linuxは<utmp.h>ではなく<utmpx.h>を使ってutmpx越しに操作を行う方向に。おそらくこれでDragonFlyBSD/FreeBSD対応もできるはず(現状では未対応)。OpenBSD/NetBSDは従来通り<utmp.h>越しに。
とはいえ、login_tty()のためにLinuxは<utmp.h>が必要になるという…openpty()ではなくposix_openpt()使った方がヘッダ周りはすっきりするんだろうけど、現状ではここに挙げた全てのOSで共通して使えるという理由によりopenpty()のみ使うことにします。
https://github.com/jg1uaa/sj3/commit/5ea54ad11d6908d147008f4edd3c5c3c6bcdca60
sj3のutmp周り、これFreeBSD/DrgonFlyも<utmp.h>前提のコードになっているからイマドキの<utmpx.h>だと動かないですね…
古いコードのモダナイズって将来的には(今すぐでも良いですよ?)AI様にお任せしてヒトはもう少しぐーたらできるのではないかということに期待したいんだけど…
sj3原典のsj3.cを今作業中の奴に挿げ替えてutmp周りの動作が変わるかどうかのチェックが必要なんだろうなあ。それもVine2.5/Slackwareの両方で。
コード自体は原典からいじってない(そのまま抜き出しただけな)はずなんだけど。とりあえずutmp周りはLinux/それ以外と曖昧にしてたけど、これはOSごとに厳格な#ifdefにするのが良いのかも 。未対応なOSでもutmp周りは動かないけどsj3自体は動く、という方が良いはずだし。
あの辺に手を出すと、「デーモン君のソース探検」とか「386 BSDカーネルソースコードの秘密」あたりも必読と言われそうなんだけど(欲しいけど)結構お高いんだよねえ…
うーん…「何か」については「BSDを256倍使うための本」に書かれてるというのでメルカリでちょっと発注してみたけど(以前からLinux/BSDの256倍本は買わなきゃと思っていたけど今までずっと放ったままでいた)、その「何か」が一体何かが思い出せない…
「UNIX」を「ちゃんと知ってる」人だと、この辺は「知ってて当然」なんだろうなあ…うぅぅぅぅぅぅ
ん?FROMの項目はこれで良いのかな?なんか違う気もするんだが。
とりあえず、sshでrootに化けるんじゃなくて、rootでコンソールからログインしてsj3を動かさないとutmp周りのテストには全くならないことだけは分かった。収穫。
uaa@slackware-vm2:~$ w
06:05:42 up 14 min, 4 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 - 06:04 3.00s 0.16s 0.07s ./sj3
uaa pts/0 192.168.0.144 06:03 1.00s 0.01s 0.00s w
root pts/1 - 06:04 3.00s 0.00s 0.00s top
uaa@slackware-vm2:~$
(Slackware/after)
uaa@slackware-vm2:~$ w
06:04:25 up 12 min, 4 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 - 06:04 9.00s 0.11s 0.02s ./sj3
uaa pts/0 192.168.0.144 06:03 0.00s 0.01s 0.00s w
root pts/1 - 06:04 2.00s 0.00s 0.00s Jbash[root on s
uaa@slackware-vm2:~$
なるほどこれじゃあutmp周りのコードを面倒くさいから削除するぜという考えは間違いだってことになるわなあ…
uaa@framboise:~/z/sj3$ w
5:56AM up 45 mins, 3 users, load averages: 0.00, 0.02, 0.02
USER TTY FROM LOGIN@ IDLE WHAT
uaa p2 :0 5:41AM 0 ssh -Y 192.168.0.88
uaa p1 :0 5:55AM 0 ./sj3
uaa p3 sj3 on ttyp1 5:56AM 0 top
uaa@framboise:~/z/sj3$
sj3の動かしたksh上でtopを動かせばVine 2.5と同様にこうなるので…多分ちゃんと動いてるってことで良いのかな。
(Vine 2.5/after2)
[uaa@localhost uaa]$ w
午後08時55分 稼働 2分間, 4 ユーザ, 負荷平均率: 0.02, 0.02, 0.00
ユーザー 端末 場所 ログイン時刻 待機 JCPU PCPU 現プロセス名
uaa pts/0 192.168.0.144 午後08時52分 0.00秒 0.01秒 0.00秒 w
root pts/1 :0 午後08時52分 4.00秒 0.01秒 0.00秒 ./sj3 -H 192.168.0.88
root ttyp0 - 午後08時54分 4.00秒 0.00秒 0.00秒 top
[uaa@localhost uaa]$
(Vine 2.5/after)
[uaa@localhost uaa]$ w
午後08時54分 稼働 2分間, 4 ユーザ, 負荷平均率: 0.04, 0.03, 0.00
ユーザー 端末 場所 ログイン時刻 待機 JCPU PCPU 現プロセス名
uaa pts/0 192.168.0.144 午後08時52分 0.00秒 0.01秒 0.00秒 w
root pts/1 :0 午後08時52分 4.00秒 0.01秒 0.00秒 ./sj3 -H 192.168.0.88
root ttyp0 - 午後08時54分 2分07秒 0.00秒 0.00秒 Jbash[root on sj3]
[uaa@localhost uaa]$
(Vine 2.5/before)
[uaa@localhost uaa]$ w
午後08時53分 稼働 1分間, 3 ユーザ, 負荷平均率: 0.06, 0.03, 0.01
ユーザー 端末 場所 ログイン時刻 待機 JCPU PCPU 現プロセス名
uaa pts/0 192.168.0.144 午後08時52分 0.00秒 0.01秒 0.00秒 w
root pts/1 :0 午後08時52分 21.00秒 0.01秒 0.01秒 bash
[uaa@localhost uaa]$
uaa@framboise:~$ w
5:50AM up 39 mins, 3 users, load averages: 0.07, 0.07, 0.05
USER TTY FROM LOGIN@ IDLE WHAT
uaa p2 :0 5:41AM 0 ./sj3
uaa p1 :0 5:12AM 0 w
uaa p3 sj3 on ttyp2 5:50AM 0 Jksh[uaa on sj3]
uaa@framboise:~$
sj3 on ttyp2をやらせたかったのかな、utmp周りの操作を行う意図としては。suでrootに化けた上でsj3を動かしてるんだけど。
uaa@framboise:/usr/src$ ls -l /var/run//utmp
-rw-rw-r-- 1 root utmp 7296 Jan 23 05:41 /var/run//utmp
uaa@framboise:/usr/src$
rootかグループutmpじゃないと勝手に書けないのでは…?(あるいは何らかの手段使うとか??)
w(1)が2BSDか3.0BSDかの詳細については、CVSのログ見てくれって言われた(引用したリプライを頂きました)。
https://marc.info/?l=openbsd-misc&m=170593542104492&w=2
あと、個人的に送られてきたメールだとwはfingerを呼び出すスクリプトであった、という話もあって。
やっぱりUNIXは歴史を知らないと困る場面がありますね…うぅ。
(そしてutmpは何のためにいじっているかは未だに分からず…uumのソース見れば良いのかなあ)
とりあえずopenbsd-misc@に質問投げてみた。そのうち返事が来るかもしれないし来ないかもしれない。
なんか一つのコマンドの話からとんでもない真実が明らかになっているような気がするんだが…(怖
NetBSDもwは3.0BSDからって書いてある。
https://man.netbsd.org/w.1
OpenBSDのmanだと、OpenBSD-2.2のwは3.0BSDって書いてある。
https://man.openbsd.org/OpenBSD-2.2/w
どうも5.1のmanから2BSDになってるけど…これは質してみる必要があるのかなあ。
https://man.openbsd.org/OpenBSD-5.1/w
このアカウントは、notestockで公開設定になっていません。
中学生の頃にASCIIの長期ロードテスト見て、UNIXマシン使う人達ってって天上人だよなーと見ていたMSX少年の限界ってやつにぶち当たってるって訳だ。まあ、今となってはオッサンだし指くわえて見てるのはカッコ悪いので自分なりに足掻くだけ足掻いてみっかという意地はあるんだけど…正直言ってあの頃の天上人な人達がどうにかしてくんないかなーという気持ちも無くはない。
wって2BSDの頃からあるってOpenBSDのmanに書いてある。
この辺の話って、「UNIX」なるものを「きちんと」知っている人じゃないと分からない領域だと自分は思っている(自分は該当しないから、今ものすごく困っている)。
むーん、uumでもutmpを触ってるのか(とports/japanese/Wnn/patches/patch-Wnn_uum_setutmp_cから推測)。何故utmpをいじる必要があるのか辺りから調べないと分からんな…
ん-むぅ、utmpdump -f /var/run/utmpしたところでsj3を起動しようが落とそうが何も変化がない(xtermを起動すれば変化はある)。
@hadsn @omasanori
> "正しい動作" ができているかの検証ができていないと、アレンジなのかエンバグなのか判らんという問題があるかと‥‥
ほんこれ、なんですよ。
古いLinux上でSj3をいじり倒して「何が正しいか」を把握しないとダメなのかも。
utmpへの操作をサボった場合は何が起こるのか、と比較してみる必要があるのかなあ。特段何もしなくたって、
uaa@framboise:~$ w
9:21PM up 1:24, 2 users, load averages: 0.03, 0.05, 0.04
USER TTY FROM LOGIN@ IDLE WHAT
uaa p5 :0 9:18PM 0 top
uaa p6 :0 9:19PM 0 w
uaa@framboise:~$
みたいに実行中のプロセスは出るんだし…
ふーん、
[uaa@localhost uaa]$ w
午後12時20分 稼働 1時10分, 4 ユーザ, 負荷平均率: 0.00, 0.00, 0.00
ユーザー 端末 場所 ログイン時刻 待機 JCPU PCPU 現プロセス名
uaa pts/0 192.168.0.144 午後12時15分 0.00秒 0.03秒 0.00秒 w
uaa pts/1 - 午後12時15分 1分04秒 0.01秒 0.01秒 bash
uaa pts/2 - 午後12時15分 59.00秒 0.00秒 0.00秒 ./sj3 -H 192.168.0.88
uaa pts/4 - 午後12時19分 1分08秒 0.01秒 0.01秒 bash
[uaa@localhost uaa]$
誰が何してんのかを示すために使うのか。
Twitter(当時)のこのツイートと https://twitter.com/s50/status/17099516453 (2010/6/27)
これをRTして付いたコメント
https://twitter.com/yojiro/status/17101672957 (2010/6/27)
がちょっと気になるところ。
あと、
https://twitter.com/yojiro/status/812019343 (2008/5/16)
とかも。
@hadsn @omasanori Sj3の大きな問題って、
- 当時物の環境を用意するのが大変(NEWS-OS上のSj3を用意するのが不可能である以上古めのLinux上のSj3で代用してる)
- ドキュメントがほぼ無い
- コードからはコメントが全部削られている
- sj3servは原典から少しはメンテされているけどtty frontend(sj3)は完全に放置…?
と自分は捉えていて、完全なる正(当時の動作との完全なる同一性)を確保することは不可能と考えています。
ましてや当時においてEUC/Shift-JIS以外の文字コードが出てきてそちらが主流になるなんてことは一切考えていませんから…
どの程度の部分まで達成できれば良しとするかによってこの部分は大きく変わるはず。
確かomsasanoriさんが、かな漢字変換について興味を持ちSj3がシンプルで扱いやすいからという理由でFUJIMIが始まったような気がするので(違ったらすみません)、令和のSj3というアレンジも許容されるのではないかと自分は思います。Google code版だって原典から比べれば結構アレンジ入ってますし。
@hadsn @omasanori
記法だけ変える、というのは多分K&R→ANSIだと思うんですが、ANSI化も地味に厄介です。 戻り値の型が定義されていない関数は無条件でintという扱いにすることもできず(戻り値が無い場合はvoidにしないとエラーになります)、こういうコードの場合
sj_han2zen(c)
unsigned short c;
{
unsigned short cc;
(略)
return(cc);
}
本当に戻り値がintで良いのかという問題があります。そして戻り値の型が不適切な場合はエンバグするとか…(やりましたw)。
将来的にはAI様がこの辺の作業を楽にしてくれると期待したいところですが、現状ではまだまだヒトが頑張るしかなさそうです…
@omasanori 自分は置かれた状況に合わせてもがいちゃうので、どちらを選ぶかというのはなかなか決めきれないです。コードの歴史を重視するならオリジナル(のディレクトリ構造)に戻るとして、未来に向けて作り変えていくのであれば今のmainブランチからという気がします。
他の方の意見も聞いてみたいですね…
@omasanori sj3が動き出しているんですが、如何しますか? https://github.com/jg1uaa/sj3/tree/dev (今までPR出していたfix, sj3ブランチの内容をすべて含んでいるのと、FreeBSD/DragonFlyBSDのutmpx非対応という制限があります)
今更K&R本、それも初版なんか読んでも…というのはあるんだろうけど、K&Rスタイルの意図していたところってなんなのかなーというのがちょいと気になって。
流石に「プログラミング言語C」の初版(第2版のANSI対応版じゃない方)を探すのは困難か…
getsjrk()では
if ((i = sj3_rkinit2(DEFRKFILE, erase)) != TRUE) {
if (i == 1) {
fprintf(stderr, "Warning cannot open rule file %s\n\r",
DEFRKFILE);
(void)sj3_rkinit2("/dev/null", erase);
} else
done3();
}
なのに、getsjrc()は
strcpy(RCfile, DEFRCFILE);
if (setrc2(RCfile) == TRUE)
return;
RCfile[0] = '\0';
とか、なによ?💢
てーかこれに気づかず4日以上の時間使ってるじゃないですかーもうー💢
ああ、sjrcを置くデフォルトのパスが違っていて、原典版はそこにsjrcがあるけどFUJIMI版は置いてないとかそういう話ね。それじゃあ確かにおかしくなる。
(FUJIMI版)
(gdb) b setrc2
Breakpoint 1 at 0x805ba4f: file sjrc2.c, line 190.
(gdb) run
Starting program: /home/uaa/sj3/sj3
Breakpoint 1, setrc2 (file=0x80c5b80 <RCfile> "/home/uaa/.sjrc") at sjrc2.c:190
190 if (vflag > 1)
(gdb) s
193 if ((fd = fopen(RCfile, "r")) == NULL)
(gdb) s
194 return(FALSE);
(gdb)
~/.sjrcを置けば動くってことらしいけど、この条件分岐の違いが分らぬ。
(原典)
(gdb) b setrc
Breakpoint 1 at 0x8058d50: file sjrc.c, line 200.
(gdb) run
Starting program: /home/uaa/sj3-2.0.1.20/sj3/sj3
Breakpoint 1, setrc (file=0x80c1720 <RCfile> "/home/uaa/.sjrc") at sjrc.c:200
200 if (vflag > 1)
(gdb) s
203 if ((fd = fopen(RCfile, "r")) == NULL)
(gdb) s
getsjrc () at sjrc.c:182
182 strcpy(RCfile, DEFRCFILE);
(gdb)
set_init_mode()のブレークポイントすら抜けるからもっと前に何か起きてんのか
Hardware watchpoint 1: Direct
Old value = 0
New value = 1
0x0805931d in set_init_mode (word=0xbfffb340) at sjrc.c:567
567 Direct = 1;
(gdb) backtrace
#0 0x0805931d in set_init_mode (word=0xbfffb340) at sjrc.c:567
#1 0x08058e08 in setrc (file=0x80c1720 <RCfile> "/usr/local/lib/sj3/sjrc")
at sjrc.c:213
#2 0x08058ef9 in getsjrc () at sjrc.c:183
#3 0x0804a6ad in main (argc=1, argv=0xbffff454) at sj3.c:131
(gdb)
FUJIMI版だとDirectを設定せずにウォッチポイントすり抜けてる
ん゛っ?
(原典)
Breakpoint 1, inputprocess () at conv.c:105
105 if (Direct) {
(gdb) n
106 set_guide_line (KEY_CONV);
(gdb)
(FUJIMI版)
Breakpoint 1, inputprocess () at conv.c:107
107 if (Direct) {
(gdb) n
111 set_guide_line (KEY_NORMAL);
(gdb)
sj3(tty client)が死んだときに、/tmpにcore吐かせるのは良いのかどうか…sj3を動作させたカレントディレクトリで良いじゃんよという気がしなくもないんだけど(確実に残すという意味で/tmpなのかなあ)
うむむ…openpty()化したsj3.c, sjgetchar.cを原典に戻してもファンクションキーの表示は問題ないから、それ以外に原因があるような気がしてならないんだけどなあ。
uaa@slackware-vm2:~/sj3$ ls *_
conv.c_ etc.c_ funckey.c_ stat_conv.c_
display.c_ eucmessage.c_ screen.c_ term.c_
uaa@slackware-vm2:~/sj3$
この辺のコードを原典に置き換えても起動時のステータスライン(ファンクションキーの状態)表示がおかしいのは何故なんだろう…他に原因があるか、それ以外の何かか…丹念に追わないとダメなのかも。
なので、SJ_getchar()をうっかり直しそうになって元のままにして、inkey()の戻り値の型だけ直すことにします(助言感謝です!)。
sjgetchar.c: wchar16_t SJ_getchar()が原典(sj3-2.0.1.20)の時点からこうなってるというのがなんとも…
まあ c を int にしたらしたで、今度は wchar_t からの変換で符号拡張がされなくて云々みたいなトラブルの種はあるので……
でも一番嫌らしいのって
if ((c = SJ_getchar ()) == (wchar16_t) EOF)
/* ここの空白 */
return ((short) c);
sj3ってなんかコメントを全部取っ払ってる感じで、あの空白はコメントがあったと思しき箇所なんですよねえ。多分何か意図があるんだと思うんだけど…ああ、もうっ💢
その後の(short)のキャストをうっかり削ると大怪我するとか、SJ_getchar()自体wchar16_tにする必要あるの?(intじゃダメなんですかねー)とか、頭痛いですこれ
あー、そういうことならまあ素直っちゃ素直なのかな。
「SJ_getchar() が EOF のとき」を (c = SJ_getchar()) で wchar_t にキャストされてしまうので両辺揃えて比較の右辺にも (wchar_t) を付けてやったと。
とりあえずK&R→ANSI化した際に関数の戻り値の型が正しくない箇所を見つけたから直しちゃおう
@lo48576 すみません、ここのcはwchar16_tです
conv.c: inkey()
if ((c = SJ_getchar ()) == (wchar16_t) EOF)
return ((short) c);
このコード凄くいやらしくないですか?
EOFは(-1)、typedef unsigned short wchar16_t、wchar16_t SJ_getchar()なので、SJ_getchar()の戻り値が0xffff(EOF)だったらこれをshortにキャストしてさらにintで返す。
なのでEOF(-1)で帰ってきそうなはずなんだけど、いまいち確信が持てない。ちょいとコード書いて試せばいいか。