1. 程式人生 > >一個活了 45 年的「愚蠢」 Bug!

一個活了 45 年的「愚蠢」 Bug!

轉自:CSDN,翻譯:彎月

英文:threadreaderapp

【CSDN編者按】微軟於近期推出了Windows 10作業系統。不斷壓縮的更新週期下,一般而言,系統Bug的存活希望會被很快掐滅,快速迭代。但是本文的作者在Windows 10上從一個USB 3.0 SSD向另一個SSD拷貝檔案時卻遭遇了一個44年前的bug,他把這個“愚蠢”的Bug分享到了部落格上,並且引起了開發者們的回憶熱潮。

640?wx_fmt=jpeg

以下為譯文:

現在都2018年了,而這個來自於1974年的錯誤資訊居然還在。最新版本的Windows 10依然有這個限制,而這個bug第一次出現的時候星球大戰還沒上映,都跟水門事件一樣老了。

640?wx_fmt=jpeg

這個bug出現時,超市裡的東西還沒有UPC條碼,因為UPC還沒發明。


這個bug出現時,世界上只有一家電話公司,因為他們還沒分家。Ted Bundy還沒被抓。Babe Ruth的本壘打紀錄還沒有被打破。

這個bug出現時,幸運大轉輪還沒播出,也沒人看過Rocky Horror。斯皮爾伯格只是一系列小眾電視劇的導演,電影票房也十分糟糕。埃德蒙德·費茲傑羅號貨輪還是一堆鐵礦石。

這個愚蠢的bug出現時,教父2才剛剛在電影院中上映。

1、那麼,這個bug究竟是什麼?

因為Unix(當時才僅僅5歲)發明了一個很好的點子——“一切皆是檔案”,也就是說,你可以用同樣的命令和指令讀寫套接字、管道、控制檯等等。

這個點子是由Gary Kildall在1974年想出來的。用這個方法有很多方便之處,比如可以從串列埠拷貝資料到文字檔案,或者直接從命令列列印文字檔案。

在Unix中,這個點子是通過特殊目錄下的特殊檔案實現的,比如/dev/tty表示控制檯,/dev/lp0表示第一個印表機等。/dev/zero可以提供無限的零,/dev/random可以提供隨機位元組,還有很多!

但有個問題:CP/M是為8位計算機設計的,這些計算機記憶體很小,也沒有硬碟,最多也就有個8寸軟碟機。目錄是什麼?還要目錄幹啥。你換個軟盤就行了。

但沒有目錄,就沒辦法把所有特殊檔案都放在/dev/目錄下了。所以這些檔案實際上被放到了“所有地方”。所以,如果你要列印FOO.TXT,可以執行“PIP LST:=FOO.TXT”,就能把foo.txt拷貝到“檔案”LST,而實際上這個就是印表機。

這個命令在任何地方都可以使用,因為根本沒有目錄!非常簡單。

2、那副檔名怎麼辦?

這裡就有問題了:程式喜歡給自己的檔案加上正確的副檔名。

所以如果你執行一個程式,它問你“請輸入要儲存程式碼的檔名”時,你可以輸入LST讓它直接打印出來,或者輸入PTP讓它輸出到磁帶(別忘了現在是1974年!)

但是!程式可能會自己在檔名後面加上.TXT!LST.TXT不是印表機,對吧?

錯了,LST.TXT也是印表機。這些特殊裝置存在於所有副檔名中,這樣上面的問題才不會出現。所以,如果“CON”被用來指代鍵盤,那麼CON.TXT、CON.WAT、CON.BUG都是鍵盤。

額……這確實是個hack,但就是好使,而且這只不過是隻有4k記憶體的微型計算機,誰在乎呢?

3、IBM、微軟等巨頭的加入

結果70年代末到80年代初CP/M廣泛流行。

它是最主要的商用作業系統之一。它定義了一套介面,你可以用這套介面在NorthStar Horizon上寫CP/M程式碼,然後放到Seequa Chameleon上執行(注:兩者都是計算機的型號)。

由於它缺少圖形標準,所以無法進入遊戲市場(雖然有一些Infocom的東西),所以主要是用於商用。但它實在太流行了,於是IBM很自然地希望在80年代早期的“個人電腦”專案上使用它。

於是IBM計劃在IBM個人電腦釋出時支援幾種作業系統,其中CP/M是最主要的那個。但CPM的x86版直到IBM個人電腦釋出六個月之後才出現……而且價格是感人的$240,相比之下DOS只要$40。

所以絕大部分使用者選擇了微軟的PC-DOS,這個產品曾經是由Seattle Computer Products開發的一個劃時代的新作業系統。微軟買下了Tim Paterson的這個專案,並在其基礎上開發了PC-DOS(後來改名為MS-DOS)。

Tim Paterson的作業系統叫做“QDOS”,意思是“Quick and Dirty Operation System”——“快速、骯髒的作業系統”。原因基本上是因為CP/M還沒有x86版,QDOS就是為了解決CP/M的一些問題而出現的。所以,很多方面都借鑑了CP/M。

其中主要的一點就是借鑑了不使用目錄來操作特殊檔案的點子,因為在CP/M中這個功能很有用。於是QDOS和PC-DOS 1.0中也有AUX、PRN、CON、LPT等等!

4、結果問題來了

1983年隨著IBM XT一起發行的PC-DOS 2.0中的大部分被微軟重寫了。因為IBM XT帶硬碟,所以PC-DOS需要支援目錄。顯然,一個10MB的硬碟需要目錄來組織檔案!

但問題來了:使用者在兩年前PC DOS 1.0時就開始使用這些特殊檔名了。許多軟體都用了這些特殊檔名!各種批處理檔案也需要它們。所以,儘管有了目錄之後微軟可以建一個C:DEV目錄,但他們沒有這樣做。

這種犧牲可用性來滿足向後相容性的事情絕不是最後一次。特殊檔案依然適用於所有目錄,所有副檔名。所以“DIR > LPT”來列印目錄的技巧不會由於你從A:切換到了C:DOS就不能用了。

但是,我們現在早就不用DOS 2.0了……Windows 95是基於DOS的,所以很自然地繼承了這一行為。(當然Windows 1/2/3也繼承了,但與它們相比,Win95才是真正意義上的作業系統。)

但是,我們現在早就不用Windows 95了!現在的Windows是基於Windows NT的,不是Win95。

但Windows NT想要與DOS/Windows程式相容。而XP合併了兩條產品線,所以這些特殊檔案依然存在——這時距離這個bug出現已經過去44年了!

你可以自己試試看!開啟檔案管理器,新建一個文字檔案,命名為con.txt、aux.txt、prn.txt。

但Windows不會讓你這麼幹的:

640?wx_fmt=png

這都是因為Gary Kiddal說“特殊檔案表示硬體裝置!Unix的這個點子很不錯。我要把這個點子實現在我的玩具作業系統中”……那一年出生的人的孩子都長大成人了,但我們仍然不能建con.txt……

微軟給出的官方列表是:

CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9

https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file

更有意思的是,在Win95上訪問C:concon(或C:auxaux)會直接導致藍屏。即使在1995年這也非常荒謬,因為這個bug已經21歲了!你能想象一個錯誤的設計會如此長壽麼?

640?wx_fmt=png640?wx_fmt=png

福利:下面這張圖是Tim Paterson在今年8月的VCF:W上介紹DOS的歷史。

640?wx_fmt=jpeg

至於為什麼我發現了這個無法拷貝檔案的bug……這些特殊檔名是在作業系統級別實現的,而不是檔案系統級別。所以這些檔名完全是合法的NTFS檔名,而我在Linux下使用這些NTFS檔案系統。

而且顯然OS/2也沒有實現這些特殊檔名,因為IBM在OS/2 devcon磁碟上釋出的一些opengl標頭檔案中有個檔案叫AUX.H。

640?wx_fmt=png

所以我今天想把這個NTFS盤備份到主PC上然後驚喜地發現,我沒辦法拷貝所有檔案,而造成這個問題的bug的年齡比所有讀者都大……

5、內容糾錯

抱歉我這幾天要麼在醫院裡,要麼在睡覺,好不容易才有機會上來更新一下:

1.CP/M對於特殊檔案的處理方式其實不像我說的那麼簡單,所以我一直也沒學會,也有可能學會了然後忘了。其實特殊檔案後面要有個冒號,就跟碟符一樣。比如PRN:是印表機,而PRN不是。

2.CP/M並不像DOS那樣在作業系統層次實現!CP/M中是在PIP(檔案複製)命令中實現的。所以沒辦法像DOS那樣讓程式直接儲存到PRN.TXT進行列印。我可能沒說清楚,我想說的是DOS,沒有暗示CP/M也能這樣做。

3.PC DOS 1其實沒有重定向或管道,所以沒辦法像我說的那樣做重定向。我忘記了。這些功能是1983年在PC DOS 2.0中加入的。但PC DOS 1的確支援從特殊檔案中拷貝或拷貝到特殊檔案,所以我說的大方向是對的,雖然例子搞錯了。

不論如何,感謝大家的回覆!我沒想到這篇文章能這麼火,其實它只是我在遇到一個44年的bug之後感到很無力而已。

而且我想重申,這篇文章並不是想說“Windows很垃圾”。一般來說,向後相容是很好的。實際上我希望看到更多向後相容。

我只是覺得,在Windows 10上從一個USB 3.0 SSD向另一個SSD拷貝檔案時,遇到個44年前的bug很奇妙。

就像你在宇宙空間站中被馬踢了一樣。

6、開發者的看法

Hacker News上的很多開發者對於這個45歲的bug發表了自己的看法。

評論1:

好懷念那時的網際網路……當時我們經常搜尋21埠,就能找到很多開放了匿名FTP許可權的機器,其中很多機器都是Windows的。

我們在這些匿名FTP上經常使用的“技巧”是:用這些特殊檔名建立一些巢狀的目錄。在FTP伺服器上,你可以建立這些目錄,也可以訪問它們(只要你知道正確的路徑),但Windows下這些目錄會導致錯誤,或者訪問時會造成系統崩潰。再加上你可以建立檔名中只有空格的目錄,所以可以在匿名FTP上放很多東西而不被管理員發現。

評論2:

我們高中的實驗室中用的是Windows For Workgroups 3.11,我們用Alt+255(這個字元在DOS下像個空格,但在Windows下是隱藏的)來隱藏Doom、Descent還有很多其他DOS遊戲的安裝檔案。

實驗室管理員禁用了Ctrl+C和Ctrl+Break來防止有人退出DOS下的登入提示符直接進入C:,但我不知怎麼發現了Alt+3也能輸入同樣的字元,起到同樣的作用。

只有一次有個老師對我喊“在實驗室裡待了太長時間”,但我從來沒被抓到過。我覺得管理員(上了點年紀的程式設計和數學老師)應該知道我們在幹什麼。

評論3:

好玩的是那些“COM”、“LTP”等後面加數字的……或者至少加上個像是數字的Unicode,所以COM²跟COM2一樣不能用。

這種裝置對映是在Win32層進行的,而不是NT核心上,所以你可以使用“verbatim path syntax”來越過這些規則。例如,“C:TempCOM2.TXT”是特殊裝置,而“\?C:TEmpCOM2.TXT”就是個普通檔案,完全可以正常讀寫……但像檔案管理器這種沒使用verbatim path syntax的程式就會報錯。

精彩回顧

640?wx_fmt=gif