1 ポイント 投稿者 GN⁺ 3 시간 전 | 1件のコメント | WhatsAppで共有
  • Windows には一時ファイルの場所を示す TMPTEMP の両方が残っており、両者が異なる場合にどちらが使われるかはプログラムの実装によって異なる
  • CP/M には環境変数がなかったため、一時ファイルの保存場所はプログラムごとに設定する必要があり、WordStar のようなプログラムでは実行ファイル内の特定のバイトをパッチして動作を変える方式が使われていた
  • MS-DOS は CP/M との互換性を強く意識しつつ 環境変数 を追加したが、初期の MS-DOS プログラムは従来の CP/M の慣性により TEMPTMP をほとんど使わなかった
  • MS-DOS プログラムが環境変数を設定保存手段として使い始めると、TEMPTMP が競合し、DISKCOPYEDIT のような一部のプログラムは TMP より TEMP を先に探した
  • MS-DOS 2.0 のパイプ実装は一時ファイルの場所として TEMP を選んだが、Windows の GetTempFileNameTMP を先に確認するため、2 つの変数はそのまま共存し続けることになった

TMPTEMP が両方残った背景

  • Windows の環境変数には、一時ファイルの場所を指定する変数として TMPTEMP の両方が存在し、両者が異なる場合にどちらが正しいかはプログラムごとに異なる
  • 特定のプログラムが一時ファイルをどこに作成するかは、そのプログラムの実装次第であり、Windows プログラムは GetTempFileName 関数を使う可能性が高く、その場合は TMP が優先される
  • 環境変数設定ダイアログに TMPTEMP が並んで表示される理由は、どちらか一方が標準として完全に整理されず、歴史的に異なる選択が共存してきたためである

CP/M には環境変数がなかった

  • 1973 年ごろ、マイクロコンピューターで一般的だった OS は CP/M であり、CP/M には環境変数がなかった
  • 環境変数がなかったため、TMPTEMP の環境変数も存在しなかった
  • プログラムに一時ファイルの保存場所を指定するには、プログラムごとの設定が必要で、実行ファイル内の特定のバイトをパッチして一時ファイルを置くドライブ文字を指定するような方法が使われていた
  • WordStar のようなプログラムは、どのバイトをパッチするとどの動作が変わるかをマニュアルに記載しており、プリンター対応のようなカスタムサブルーチンを組み込めるパッチ用領域も提供していた

MS-DOS と環境変数の登場

  • 1981 年に 8086 プロセッサと MS-DOS が登場し、どちらも CP/M の強い影響を受けていた
  • MS-DOS の初期設計目標の 1 つは、8080 プロセッサ向けの CP/M プログラムを 8086 プロセッサ向けの MS-DOS プログラムへ機械翻訳できるようにすることだった
  • この翻訳器は、自己書き換えコード、命令の途中へのジャンプ、コードをデータとして使う方式のような変則を使わないことを前提としていた
  • 8080 の H レジスタと L レジスタは 8086 の BH レジスタと BL レジスタに対応しており、8080 では計算済みアドレスへのアクセスに使えるレジスタが HL だけだったことが、8086 で AX、BX、CX、DX のうちメモリアクセスに BX しか使えなかった理由になっている
  • MS-DOS は CP/M 互換性に加えて環境変数も追加したが、既存の CP/M プログラムは環境変数を使っていなかったため、初期の MS-DOS プログラムも環境変数を使用しなかった
  • ユーザーが TEMPTMP を設定することはできたが、初期のプログラムはそれを気にしていなかった

市場で TEMPTMP が競合した

  • 時間がたち、MS-DOS を主な対象とするプログラムが書かれるようになると、プログラムは環境変数を設定データの保存手段として利用し始めた
  • 一時ファイルの場所を指定する環境変数として TEMPTMP がそれぞれ使われ始め、両者が主要な候補として浮上した
  • どの変数を先に確認するかは、プログラム実装上の選択に依存していた
  • 多くのプログラムは両方に対応するため TEMPTMP の両方を確認したが、どちらを先に見るかは実装ごとに異なっていた
  • 昔の DISKCOPYEDITTMP より TEMP を先に探していた

MS-DOS 2.0 のパイプと TEMP

  • MS-DOS 2.0 は、あるプログラムの出力を別のプログラムの入力に渡すパイプ機能を導入した
  • MS-DOS は単一タスク OS だったため、パイプは最初のプログラムの出力を一時ファイルにリダイレクトして最後まで実行し、その後で 2 番目のプログラムをその一時ファイルを入力として実行する方式で実現されていた
  • この機能により、MS-DOS 自体が一時ファイルを作成する場所を必要とするようになった
  • その一時ファイルの場所を制御する変数として TEMP が選ばれた
  • COMMAND.COMTEMP を選んだとしても、ほかのプログラムが TEMPTMP のどちらを使うかは依然として各プログラムの判断に委ねられていた

Windows では TMP が優先される経路が生まれた

  • Windows でも似たような経緯をたどったが、初期の GetTempFileName 実装は TEMP より TMP を先に確認するように作られていた
  • Windows プログラムが一時ファイルを作る際に GetTempFileName を使うと、TMP をより優先することになる
  • したがって、「どの変数が正しいのか」に単一の答えはなく、プログラムがどの API や独自ロジックを使うかによって変わる
  • 現在でも環境変数設定ダイアログには TMPTEMP の両方が残っており、2 つの変数は一時ファイルの場所をめぐって共存し続けている

1件のコメント

 
GN⁺ 3 시간 전
Hacker Newsのコメント
  • 面白いな。自分の時代より前の話なので、CP/Mプログラムをパッチで設定していたなんて聞いたことがなかった

    • その通り、実際にそういうやり方があって、パッチコードは Z80/8080の機械語である必要があった
      この機能で自分のWordStar向けに、より高速なキーボード・画面出力ルーチンを直接書いたことがある
    • その通り、実際に存在していたし、もともとCP/Mプログラムだった一部のソフトは DOS用WordStar 7.0 に至るまで長く生き残っていた
      WordStar 7のドキュメントには、DOSの debug.exe でプログラムの動作を変えるために使えるパッチ位置が載っていた記憶がある
    • 今でもある程度は残っている。suckless の作るものはたいてい config.h を変更して再コンパイルすることで設定する
      https://suckless.org/
      付け加えると、このページの別のサブスレッドですでに触れられていたのを後から見つけた
    • その方式が必要だったのは、RAMとディスク容量が極端に限られていて、ほぼすべてのコンピューターにアセンブラが付属していたからだ
      多くのCP/Mプログラムは、32K RAMと低速な130Kフロッピー、ひどい場合はカセットテープ上でも動かなければならなかった。64K RAMと360Kディスクがあればかなり特別な部類だった
      当時は今日とは違って、プログラムは市場の上限ではなく下限に合わせて最適化されていた。より多くのシステムで動くほど多く売れたし、顧客にハードウェアのアップグレードを押しつけることもしなかった
      外部設定ファイルや、その設定ファイルを作るプログラムを置く余地自体がなく、コマンドライン引数の処理ですら貴重なバイトを消費していた
      今ではMacBook NeoのRAMがたった8,000,000,000バイトしかないと不満を言う人もいるが、1978年には 2,048バイトの基本IDE すら作れた
  • Raymondのブログは好きだが、1973年にマイクロコンピューターでCP/Mが一般的だったというのはおかしい
    1973年のマイクロコンピューターは、Intel Intellecのような開発システム級の試作機に近く、OSもなかった。KildallがCP/Mの開発を1973年に始めたのは事実だが、その時点では PDP-10メインフレームのシミュレーター 上でしか動いていなかった
    1979年ならまだしも、1973年はさすがに早すぎる

    • WikipediaにはCP/Mは 1974年に作られた とあるので、ここの時系列は確かにずれている
    • 1979年と1973年の差が、今でいう2020年と現在の差と同じだというのは面白い
      そう考えると、2020年にはChatGPTがなかったのだと思わされる
  • 初期の開発者が深く考えずに下した決定が、何十年も残り続ける ことの好例だ

    • 少しだけ関わったS&P500製品の中核テーブルの1つは、今後も永遠に attornies という名前のままだろう。初期に誰もスペルミスに気づかなかったからだ
    • TMPoraryな決定 ほど永続的なものはない
  • プログラムが TMP を選んだのは、MS-DOSのファイル拡張子が最大3文字で、テンポラリファイル名に .TMP 拡張子 を使う慣習があったからかもしれない

  • Unixプログラムが http_proxy を見るのか HTTP_PROXY を見るのか一貫していなかったのと似ている
    今では多くのプログラムが両方を見るが、確認する順番は同じとは限らない

  • CP/Mへの言及がやや混乱する。筆者は後で重要になるように振っておきながら、結局 CP/Mや8080 CPUとは関係なかった と説明しているように見える

    • 同意する。この話はCP/Mも、8080/8086へそれていく脇道も、どちらもあまり関係ない
      要点は、Microsoftが自分たちで使っていながら 標準化しようとしなかった ということだけだ
    • CP/Mが設定に環境変数を使っていたなら、 TMPTEMP のどちらを使うかはすでに標準ができていて、DOSはそれに従ったはずだ
      ただ本当の障害は、CP/Mにはディレクトリがなく、DOS 1.0にもなかったという点だ
    • どの文を指しているのか引用してもらえる?
  • 1995年ごろ、Telstra、つまりAustralia Telecomには組織全体でデスクトップが約5万台あった
    ある日、全員のネットワークホームディレクトリに null という小さなファイルが現れ、おそらく Unixユーザー.bat ファイルを書いてみたのだろうと思った
    既存の標準になぜ従う必要があるのか、という話だ。「なぜ標準化しなければならないのか」と言いたいところだったが、北米の人たちを混乱させるかもしれないとも思った

    • たぶん最初は /dev/null を試して失敗し、それでただ null に変えたのだと思う
      そうでなければUnixプログラマーがやったというのは筋が通らない。むしろDOSプログラマーが NULnull と書き間違えた可能性の方が高い
    • 捨てようとしていたテキストが何だったのか気になる
    • Logitechのドライバーインストーラーでも似たようなことがあった
      ハードディスク上の NULL というファイルを探していて、当然ながら .BAT ファイルの中に > NULL のような構文があった
  • 正直、多くのプログラムでホームディレクトリに ドットファイルをまき散らす方式 より、CP/M式のパッチ設定の方が良かった気もする

    • みんなが XDG Base Directory Specification さえ守れば、設定ファイルの乱立は問題にならない
      Firefoxのように抵抗していたプロジェクトまで含めて、採用するプロジェクトは徐々に増えている
    • 少し変わったsuckless側の哲学の1つとして、プロジェクトはたいてい ソースコードを変えて再コンパイル して設定するというものがある
      現代のオープンソース的な感覚では似たアプローチと言える。とはいえ、全体的な禁欲主義のせいで好みは分かれそうだ
    • 本来なら全部 .config の中にあるべきだ
      問題は、多くのアプリ開発者が自分のアプリだけは特別で、専用ディレクトリ を持つ資格があると思っていることだ
    • 中央のバイナリレジストリのあちこちに散らばった設定より、 grep できてテキストエディタで管理できるドットファイルの方がましだと思う
      もしかすると単に慣れているだけかもしれない
    • こういうのは標準化されていてほしい。何らかの形で .config フォルダーを強制できるディストリビューションがあるなら、自分にとってはそれが勝者だ
      ただ、もうタイミングを逃してしまった気もする
  • こんなに混乱しているとは思わなかった
    教訓はたぶん、常に同じパスを指すようにしろ、さもないと大変なことになる、ということだ

  • Microsoftのこういういら立たしい点は何十年も指摘してきた
    昔は、そこでは何でも知っているかのような「シニア開発者」がいつも答えを持っていたものだ。「temp は temporary で tmp は troubleshoot my pc、デバッグログ用なんだ。だから俺がシニアでお前は違うんだよ」みたいな調子だった
    自分がもっとシニアになってみると、疑問を呈したのは正しかったし、今では当時のMicrosoft開発者と話すと ミスだったが下位互換性のために維持した と説明される
    だが、その言い訳がなぜ有効なのかと問いたくなる。下位互換性を理由にする一方で、New Outlookのように中核的な互換性や実際の業務フローをしばしば壊す変更は平然と押し通すからだ。そうなると「自分は悪い開発者じゃないから、新しい人たちに聞いてくれ」と逃げる
    その新しい人たちにはそもそも聞くことすらできず、彼らはLeetCode式の選考障壁の向こうに隠れている。だからこうした現実の問題が直らず、New Outlookのようなものが出てくるのも不思議ではない。昔のあのシニア開発者が今そこで働いていて、本当の開発者たちはもう引退してしまったのだ
    ユーザーのホームのDocumentsフォルダーを勝手なプログラムが不適切に使ったり、OneDriveが誤って強制的に消してしまったりする問題についてMicrosoftからもっともらしい説明を受けても、6か月もしないうちにMicrosoftがランダムな変更を押し込んで挙動を悪い方向に変え、その中核ロジックを台無しにする
    Notepadも似たようなものだ。開発者インタビューでは、リスクはゼロであるべきだから非常に単純なプログラムでなければならないと言っていたのに、後になって MicrosoftアカウントのログインとCopilot が付いた
    LeetCode式の開発者の姿勢とMicrosoft文化が業界全体を壊していると自分は思う。落ち着いた議論ができず、「お前はMicrosoftで働いていないのだから、その主張は無効だ」という流れになる
    Google Chromeが管理者権限を回避するために AppData にインストールされていた件は強く印象に残っている。その機能の本来の意図が、第三者が管理者権限なしでインストールするために使えというものではなかったのは明らかだ
    だが当時のChromeは優れていたし、ロックされた企業PC数百万台に第三者の例外プログラムを配布する混乱に対処しなければならなかったので、開発者たちは今ではそれを意図された機能だったかのように言い換えている