From cb3a3c9f6e60335fbc381daba42d9d02d8bf3954 Mon Sep 17 00:00:00 2001 From: Offihito Date: Tue, 19 May 2026 19:50:32 +0300 Subject: [PATCH 1/3] libc expansion --- .build | 2 +- Makefile | 1 + dsk/rd/emr/system/fm.elf | Bin 132224 -> 134304 bytes dsk/rd/emr/system/sysinfo.elf | Bin 134432 -> 141112 bytes dsk/rd/emr/system/template.elf | Bin 119384 -> 121464 bytes dsk/rd/emr/system/terminal.emx/app.elf | Bin 122768 -> 124840 bytes shared/ebuild.h | 2 +- shared/types.h | 2 + src/kernel/file_systems/vfs/commands.c | 27 ++ src/kernel/file_systems/vfs/vfs.h | 2 + src/kernel/user/syscalls.c | 6 + src/kernel/user/system/calls.h | 2 + .../apps/terminal/terminal.emx/app.elf | Bin 122768 -> 124840 bytes src/userspace/apps/terminal/terminal.o | Bin 9304 -> 9432 bytes src/userspace/apps/test_libc/Makefile | 27 ++ src/userspace/apps/test_libc/test_libc.c | 96 ++++++ .../apps/test_libc/test_libc.emx/app.elf | Bin 0 -> 25936 bytes src/userspace/apps/test_libc/test_libc.o | Bin 0 -> 6040 bytes src/userspace/libc/include/stdbool.h | 1 + src/userspace/libc/include/stdio.h | 50 ++- src/userspace/libc/include/stdlib.h | 34 +- src/userspace/libc/include/unistd.h | 2 + src/userspace/libc/src/_syscall.h | 4 +- src/userspace/libc/src/stdio.c | 294 +++++++++++++++++- src/userspace/libc/src/stdlib.c | 100 +++++- src/userspace/libc/src/unistd.c | 4 + src/userspace/libs/eXui/exui.o | Bin 0 -> 9352 bytes src/userspace/libs/eXui/libexui.a | Bin 0 -> 9538 bytes src/userspace/libs/libdesktop/libdesktop.a | Bin 0 -> 6808 bytes src/userspace/libs/libdesktop/libdesktop.o | Bin 0 -> 6664 bytes src/userspace/libs/libfont/libfont.a | Bin 0 -> 100242 bytes src/userspace/libs/libfont/libfont.o | Bin 0 -> 100040 bytes src/userspace/libs/libvad/libvad.a | Bin 6774 -> 6774 bytes 33 files changed, 632 insertions(+), 24 deletions(-) create mode 100644 src/userspace/apps/test_libc/Makefile create mode 100644 src/userspace/apps/test_libc/test_libc.c create mode 100755 src/userspace/apps/test_libc/test_libc.emx/app.elf create mode 100644 src/userspace/apps/test_libc/test_libc.o create mode 100644 src/userspace/libs/eXui/exui.o create mode 100644 src/userspace/libs/eXui/libexui.a create mode 100644 src/userspace/libs/libdesktop/libdesktop.a create mode 100644 src/userspace/libs/libdesktop/libdesktop.o create mode 100644 src/userspace/libs/libfont/libfont.a create mode 100644 src/userspace/libs/libfont/libfont.o diff --git a/.build b/.build index d1f0c9fa..db88a862 100644 --- a/.build +++ b/.build @@ -1 +1 @@ -2230 +2250 diff --git a/Makefile b/Makefile index 4c8f617f..445f5046 100644 --- a/Makefile +++ b/Makefile @@ -111,6 +111,7 @@ $(ISO): limine.conf $(LIMINE_TOOL) buildgen $(BUILD_DIR)/kernel.elf disk userspa @cp src/userspace/bin/ps/ps.elf $(DISK_DIR)/rd/bin/ @cp src/userspace/bin/meminfo/meminfo.elf $(DISK_DIR)/rd/bin/ @cp src/userspace/bin/dofetch/dofetch.elf $(DISK_DIR)/rd/bin/ + @cp src/userspace/apps/test_libc/test_libc.emx/app.elf $(DISK_DIR)/rd/bin/test_libc.elf # libs arent copied anymore due merge conflicts in prs #@echo "[MK] copying libs..." diff --git a/dsk/rd/emr/system/fm.elf b/dsk/rd/emr/system/fm.elf index f44f795e9b7fb78da59a8389bf2d779f6a04b4e8..29eb7224a909038e7254fb28134f51eee26bbe47 100755 GIT binary patch delta 9192 zcmbVSdstOf+TVM_Hbk5w$dQXEcLed8rJ{n|j%^iGbok6KMG#Oa1m%)ApLj5|-0i$Q zYx308Q#8{wR#qmC9;;E%@{l*Aw6e@FXYBZai49X{X3+Ef-o4jBWt#cp+t0&Z@A|#h z^{%zvwf50E)u-WkpB?d1gYV9f6MeT_76p2CC%pUUn!y+GY2>h7TK3F@AuZWDFir*1oSyQsT|x?R+b$YVkN31esF38{+eaJn86 zgw0J=W<|3&56|J?6& zvn&2BVhm86oy>n zY|6u|VQ`4`iH8Le`S@6_qW(px?;ND4wJuGb7w9Eyo#)o%3=m02H<&az36yU20T7xz zhPtjG>jX`X28m%cxA#}%2&aTGVR(lrb>!$w293%+m}~zCLX*3w>l9V1d<7K6q$?@v z@gsW5e*>lC@<)_zXU1)}n+K@L`ysx$X+w=BzpYbMWtzDGlqSD~chb??7){;*>fgsR zU5}>}G6=w`%7wc2lAqJ*4aW~U&JS+6-AL6EJyn`K78-hrqCg-;Q#3gkl%66J2u<#f z_rJu^Ytx<%n{1-lEJa*p+2%-UR-2!c(gT>woLQLqrHFynWN7AzpfK=nBpRNdCdZ+# z%CDlYnO~x}#U&oqWE0?|qt*aTmO&+2TzVw6Bp|QFdvnt|Ux!=*iXKf~`VD(|NKoP| z07;gf+WwlQN0q0ccV{sKtF@gDOHZgSzsR3m9+E!z>r0X#o>eW~^|jqX%^*!~xx^+0 zO_10n_E=E3Bz()B2?~+&^4K4OM$wSY2hEV?=doeIQPfKdj+VC0VatOft+qLWaDs{)(B!>%V-(dRHMs*_V&IOO|HEHET$=oxgBt-0rvt(Grnp2(5AElZRC_BqQ5 zSs?9bXRn2flXiX1z6d!Wm3_u`gbs~K`V29it*>nt*7d{tcJ-pe{h)WG0%gEXfjYHp z)*3p=Z|!WP-Et8DT+e0!Lle_Yy5mYn zk8bz1G566t?XPc=M9bbR&D{J6MIvAAPa#~SclLfQ zcfVGRi1$8f1uuJdT29)$g=vRqg3|0yVdhmwn)?%_{=Fa!iLVN}*Ob<~OS=aC&>5px!e|VT=YhxqAhf8bQ*hAqF zQf?b736GOTx3Qh!6KL}t4<8p~RAozhhmYd0v{Mfw{P-*z81YN#h4ZX1VxqL-JbNJ` z!GH336o$<;IOEnQV~JdAW#=Pij-WG3Q8%vytjRg8*mb%H4kfG@b#sx9C$}<7HXqJY7iuF?mj_IAF&;L|grylK)-=iI*S)M~# z+PoeCAllGV>{VF$;UqhS=EOFeAotP|Rc4pr%pcK?d zMtO0_k4j$b-Pnu>Rh?w@hVNIOKH((EfS&xgWLNKqqL9t(_%o%dG}wO%!MqtVPi z&|7xmt$v2h=nad`KmLs}Mi`0{j?+t^=meC{gTNj;fo6;R5#EYs{>urb#x1kv=sn9> z)4^2V=Tv!yr+Xk(+#*jy4|)&k&0U){_Aa3MK9p}-lo0gu;1b`}Jp$k607%fq1+M_# zB3}}`0x*bA(ZLWF+;F>9x!=cZ{fI2{{uVl#HUw(&8=&+-ywbwH9x;5nct$ezVhtEr z%Md9e5xR^NgK+wO?{?SMp7O0isXR5XI!Ke}0LD2tP?IxT*p&EDv%hrX_Tma5-Byrr zJ{L-8%w44G5~`MJ@=b@Xm8;2ba`9OXOAF18!}1|DiZ<}07WQuZDCuPf`zHRusgvQy zef9`lNu94pqdL-U)cG<|bP;tvOBCH1of=Ve{d8_5s_QbFn-HFM={D|e$ec;h47&2wb1iJ0Xb!0%3*HHtTlk}sg z5AYuRU41Bb`dm|<1JP*@`U7ji)AK0CcWOn-c3xAihJ12#5kV^ zdmv$+)YBL~YPH{hk8WU6ES;L%bffV%lT)OGs_TZkbj`d5q$Zc+jqOP{W=jtxqGK4M z%D&FTsiPhY=hBlkISeG$(HKo0Vo)(SYJ(17x0z)C+Q5Hy>S^liY+N?=c~QEY(0FTF ztmxN}=Q&wNjbvj|hNkBSd!gVuZ;!a^1Z)^dGtw<=2+%Cu%5%r-NC^4urh`;JpzoMz zO<-C|Xn$^|Z3KHeWtiVSSThdO_>t`Ml*gs*BO2#UzaUC`^4Q3T6iWv`?M4t^g1;%de+GHxD|;#f<1%CN)0oiF~~?Z!pp13eh5CgZL! zDV9ZNBuL|<*_@1_eu2H3Psg(AjO1abNVChOYufeuK(D42!&);6{D();88fJAzY+W4 z7?ze9YQ6!?{|-$u=RdjmDI?R%)nwA-mkwmYbqX#bp=vG%Lf#M^(OCel8j9Zje`y4{R+ zuzf6b{p_jK$o56;jg<>O^|B86T3@OrYEVwY^x3@jXGDml|M!bPQ3SE`zb8_Yze8g> zAZ%)?ia_sz(K8)Bi!Y&e^)sq1+i^)HOHJS(@<>;kQC|Ll9zBMOjk*h~ybGv;Deee> zf=V63;RYh{1%T#`!xE!+kHc`oVHG)?*()7{-c&NNbsoYuj{|ue8+riZhyYCwVs^32 z#UsU?tbFmJBp>4o@-(>huJ8@_*>NJfJEAoCeIT%+n)iXgcafHh57EGn8sfc-donw+ zIBI&qSKwjTLk^SaBYt=}m%;#2H-lI>g)uObQs3UCV3i`eu>@n_C}lBUv4|z1F`*W>Ok?vx40@_{gUM^$rgXdb}kNO$CsptGnt$ho*RMh9ZenwgLJ4_ zdOBjUZ7EW3JxZ#nrh5?F`&add`q#>NW5Yb`W8CA7FPm2pNn>i>K#3*f53ydr2W0Pu zww|WtrW;MYNH8T%QLDSu+)gdGQ_-@!5H1k?$AK5`R{qbTYkpqT{Bve!u+;qNtS~>! z>SG)s7$5Fc_=fNhpQ-;)^z30QZY8os>3>#Ho7FCS??)Y@ZQqr_)&ha!wP8z2l zwHFA(kxfmrb5N|?D)1u|q0*RXLRER66#{oYLh~^OJI1hAQFC`IYIcKCU%OW{J$WDQ zNEpdpr41vrxUT&#mKOS$Bum$|lST&%%;LPZ+vqrzL~wDG!wL>^i(L^hdVF5eLcSZe z>NpBOE)@ar;Zv^!?lzo}WprDIMWG`d5~SS@L)g$;EUjFH0BC`i3-Scln=@tWy57;gZwYi(}8>w-elnI z`dBne3&w@~QC)Pmsg{fNwHJlzevoVLNF;ilFKC#A4?msKOCPM02NZ&erfmTg! z{#36nRrg^WP60m>>M8w|q3v)!{{s~oj9HUyBuV8oOE;on6uH2&;YHt$+q&Iul&J)R zI|xmeF(K2Es{`*=sXr=$(J@4+w_0329u8D@>&|;q7>pER8R@&s z7?;l@Nz{Lxy;v~Z`!%4fIXMu=4kZW%VPq=tUu9{_Li)`kGEXNL5IG&>a4|xEi!6Ux zoG3OvwM-JF#AlX)3gOTWPD-XD!MMc z(8)TBCrImWvdHCTpM8*W$UUc7%JR9=o2S|Kvfc3X&-OS&g?ScnNj5$q?YdYdF5C5B`LXdkfz8*g-ixE*lQ$ z*96E2f~3C%x~Y+4`b}6z#_4b2Su{FMH*!24$1ia_rVmb~l;p>8+>_C_2+sy1wU5HP zTp_a${zr~095?bK2+bUy8GLZc_u@n`bW5M1=R%Sq$O^VSeM20B9|CRf-4Ij6Z*70S zAx^q~9=At(ho0xS_``ktzsT{$!3URhiE)yYAAIoXAH-dvlpk-4>K11#+JegvS@2lO z@G>0JC5doEp+7kuJi)*{DO{@Km{Y!JJa&q0Vz(GnPzE-Bz7_W58tWT(Z~d9f@fMEL zey69B<2N`y)_{c?jt~DY!w$ZK^{3W0zFQ1W==ZPz_cb$`;~q1c^{B>stYs{^*V;Dj zWi7`uxR)1nHSu@4Gye;V?{)Tu&b97?vOlfFa4}WaYcjN(fd?Q3Z#-nEd5pGjyn+vP zm?18-aa>qp$Wv{l=K{xHccuRq@yxb2}IMgNfRxR8Cip-dH!p1<1G{3r%ldpJ8P z)L_#^l^!2VC&hR(!@z%Mz``Jozc|mpV>oW+_#^2C-oWu#j_>)Uf&Z4{qk#Jh-d5q& zKFjAib}~8MmSZS**2n$a(Cq~V{x&x>h2v2R4Lp(KX&i6o>%+`(h2w4WNj_Q-M)UPN zhcj%chN1Vl!a`fYPgu8koPBzl!Jf(4D>%NHPeLTe*KmA$pUJG@xL3Ae=l5LRYHNlY z>yw-v$%pS5&Nhz!$n);OcX51KvSBWln|qDp8c$0&$M6i9BA8kM`hw z@^L@MZ8Hsd#^tAQ{5r27I05x1o#Sul0|4ro_7i-Y&*7^vhAYg30%a(b7wc4x=Ws(m z@#$N{@kJbupKSy*oX>hb$1i0X_%kF=TXzL#{Ed&yb8wd03jQGmjj!VD8CizjFS(!p z;doY`ZLrC7XZ?z^XZK-W z=J=ThjVLy8b1sfAaHGL}ePX=xkWIhhhF>{M6tmTW!bDVhh zGb-|8esunxJMPc%gS_;JJey{YH}!G+HMf6U4-|`2;fB8VIOZb=;`mT*Xe8fW(>NZ* z@#(ze&fs_=$4mQc-|-w5`Lyd3L+}R_}_ljIvP*q%0Qnhq>by;Dh;OP~X zSC>@@OUsIDs%+o7#Uh{TvdZGB;5Ne7S%)N-E0BY-2=eOQ>$D z8n#vyuR@G)R8l5XRuq&K*_uV^!4byz5MFi3(vq^0DxtKrsN``YkQJrtR<8t5u&mPN zD@idj%$JthMoSX2{YjFdrMM-wZzXArFa2*C%6RH3Td0>b(cg1V@E9Bw1w<+mO(H~mQbOT5;@}}Xj$2b( z+O~5$iXQXYseD{i#`G$pF=!}gYHE6#b54C4#Y&5GEOhSgxAz)U?&qvO_V2g8zvp`W z)*7gL-?Q4{xjvRulMO=?y>-__0b6I(zIh+}iM?1*|2@+HG#sR`$F@kV(6m~sd zg6+EWP*4)J%kIzt&G((cNO>0eo z5-kOD(`Hj?V=tI86Rn0wpSi%H$#ND))sQX-5>0QHN%RnKir4+XNOU)Lox$b= ziT({(7}jySmxi@=y*ct>&SFwogF9F^H^{ib4FhFynfG1DS6hMW{5lco8XGUa~( zqh@OS2TZpk?V-!X6O`!FpkCX!yi%eg6s~-cq|pH<(FpjCYpT*qv_EkFIiK-LKDT_8 z1k4utZ{Q?)9lrn1raK)UuyGuD;BvuK%~YmJqIUmDbuVZO+L)2NiVWr5MiK|X_Dp=a4_(z1c&D%(Prpds2=)~ zCIY`kr`QDf06ebA93asTfr~dfl}sL70R?&wzO{`@y>0XcaM&dJ%@wvaC^-H!0OO2Z zRbG;@%R-Mp@6l!$XsNnoGjf0!d}Y2!6a@Xn=>%doG?)kj$!F=_yG4P zXn#vpS4~xyuvBNG3(vbx+5B#fdVAmigpM2~_ zAX3sC@RKeLnE}Kkg%`B3BjE|-r%JQ{q;O6_?+xI_8TXpUNqKuE<9^(#uOQU4JVv7V zitrP2n3VSk7iLhlEIdrFSA#`@0yqf*A|;(vupx(lK(NowLa;>h?q2*HZUY9qf_4LP zPlnu~3L)ecMfgNWNfmlKKDz62-5Aja*J*!EBN2^zGbK&o85|;=14>d-0e+|Km-6;Y z6_D}Xd1jDJ*_D!$lKo=JAzYvoYYeQs#g^haZ>l+|tEt*0l;^5d?W?f@)Jzdm)F@dz zF)KvP0#fYq!2F*`@diRo%e@^lFvT^!d5TnIw}D+B-Z=HlrPTFv8L=n6GX+32kRZx%oH|7XE+yD8mfF`8{Q4Y$(D36hMPp)A!dg9ISk z&zji|@bqpoYXvf|nRNn5ZDwIZ;)$l2O&k)9gCDJR(Vn27N!T8Mfl4g>*gS5WDPD)< zPNDo2iEdD>@+2D1)hF4EEx0;1<4GhY$+!3f+ZQ{GjBjG!#6I)fWw3CyAH&z3|b&V0|r=Y~DAm1~cc z=m)^UJ{lp>_f$>~S8c;yIBl9*03_c(qOL?2d|&_SbMK3!N?-rr`5~f@A>Vzow&>Z2 zJvc`unztojJQ@S1I z>Dac^0f93BfV|d5peKBJe5qqCsmbB90C#+F-{pdb#t|hM*iGtN;Y%$WoEAqOgtMt> zp+5F-w`H`BRiq__FF?!NPQ}uyya&21W3;R-t4P-yLkh4S z%KCe&l6WmEOP}EL$L^#PBG`%aNWVmIU@BGg|b)eNTl>KImCUqff zYQ}1kI*47(C?wy6)F(~o6v>GYmN4;}xSRE#v{}^De*~4mXNx~(e*xSK4rY~^Vd9%? zQ|55;RS-Lw87oHA|BxB%(d*e@L10-qVN9PrkL(SqU!R>Pl6+15_c_mrBy0fF=Niey z!20>QlF63&EYXq)ine{4?3hPZIi>%}-kP@p8lG#=rl6>n3B-5-0 zB$KU~NYbq@AxW~9AW5{og=D04C6ZXHj3m1TSISmhhorW#B1~D$8{a~Puz{B%3Pli3{vuVc1c={3;qAt99mw<5p5M`SlVr48 zE@5q12aiUF!T1Pw?TicmAMaKoC!c0g_edmA6%ictX? zJ!ibV#NS4@gC2s)*gK#WqaIy#k=4zdB7Vm<6bxdXvyw%LO_-$(!=k93yTu;r>stN2 zQ3$>I!?Sz|GZ#KpUtcVWVQP*sm?MR7YK=WM4*OT$Er}2>F>Oh#c!8OKe}|R8cQIQD z-)!YOnw>0(7Dv~2ln{{=wXvV(rV?!%ODNq*mYii@mnM;?&$2=Do(}x-9*!S|SySZ@ zDhAl-4`*26ydQ|`4$GdOpxpv*I}o>nxLv4#q6wO?6)u34jegR~w$INZGg{d%^9y60 zUl73yCjzo{b?879rct?+1dM@Qur`LNU8$fCwiU?1bK&dIH_B zB1~?)EjDhb9Vpk`5yzVGmPDog_<;tcP!NS)0^XU}cjLo3jyLGzI8Geu<9+%#4u9ZK zaJ*d~$Fn(JrsC%A00mr7%?$+nTL-k)+_;?>fQ3+MD+3}59)j*`HGmthY_ zzL(?f8T}OTDPZ2%!(bmbIN1X~!0{H2tMelW$2oo~pkezjVxl-Gw#U%(Koc`=4Um8C z6i2|1TRG}iFq}B@oNDMr+*cr39$z>{CrP*PbBsz zdG&oU!`~6*VL%UVPib<_eKEK&(*q|}6e_a?MGV)D(#CRpBggSjV$0$9VUCYfVc`Xi z-{d&F$&@xj-u9cQjoUs=b>Gv?DUQ3{6e(Gac6<9KS2c5cTfn0PPFL|X9%ZRwCazF| z`B%L7WUy6=)Vv;y{b8_mA)-OCYgDbb0v-TU@b?K%I^D_f54gK%RbAN4@l=i{aC|?< ze@|8YZ07h86_;bWME{T$t~Af6D)|ys>ztg^B?g`sB|1ihH zva6DZe{Sd-T=i(T? zjkH|+GRG@lP|b=s{wl|xnyTXcI6jx-29EzP94Bmx<>L@0jCc%OA5`vRTc6X*Z+8uidS*raTPZU(|XKl3pa@9F^)4FmnW)@71DJ_X@^K&`!@1TAy!1p7RqYx1 z4vLdOtP~f1p$mEHJjM(13J{C4<$XZRuXC+%z75@nZ9c~zWT^wz zbL%pWZ{q`o-ziFaljCpkm2p?7DvmpO79Vo`KdHD`Xh>26hpJE8p}a z!)3h}`E%ce#S51dmkSFEOBczXdy!`b6jxT1zEZlVv|KePS+KNht{mx2^zvkH@~&+6 zCOXpeqD=ad5#IQ3G)&H3B0t-gB>KDGHo6YJE9Dh^$;bfrn@x91g)d~tO`xuE_pAA) i>4B)^O3Gzx2q>>O4h=e30Gd%hm1{|{Ics3^49<*#~?=WH;%)eXYFeG!DCl8L3(=AJkAsFtRjgsy;ev38mDYR?<&TP4ic)@9bEo;f{t zw8bVa6C%9GYU!D3%}*X`-_@3O?(SMMxrb)|SzGY+rPebkgN7Y!i#@nhh}|*MlYG_9 zK6k{IciETQG{;Q*@S>&lx=-J5(em_qSbzV5mEL>Vz_xp8n5-mllJ|v`q4fC zhB{yM9XonHQ#*A!;&TS(m?_ogtxbLMlmAX;INF+V|97m5eQs1jFSZdn0HG6&){wNB z+9hjU+SnnNG*L6}no(0Dqfqk_O>a7%x!qU)$~Vx8uq?a=#P)+r)~U3#ocMJT8zQlS znD7=z8P^H-QjD5p%%Qnbt%>QqFzfvEH2VNWefn!s-Eh(RUV2*2aD{D=*vl8AcJ2Eo z)e{xtV#&DkqEvkjsxMmC($kV=DryU*(6oL0iIv@VO2PtwswNvJS!I3i(jWT7s_)xZ zU$xHqd*7*^3z{&U=X|yi7#zk5bsX6Ofly|Dfh^g76to`<`fTyUW$TE)$Xw^ZFTfGD z1%8Q};X8ih+1LzOi?F&wnBH4`S!|qS)a0HpotFQg^7!9U%m4f$&ppe$tWZTBuOq&nD1ZQ*g1eho`jxlZbNgz@^$S_k@Vhs1rTXC7c z)f%mLGfVMzTGmu8WNpp5sdEU_lp~?q=d;!&#DAb6-WN=p@j>m7VN>-%XVpa0&6KMc znzk$WYk&Tj&l#z6Hd6$`8L;QQv(}yw!){^b9Mkp$hTDUihnu#?)M(%w)ArQ6G*b-# zGto=Drp_VW>YHGOV&ZOy1`E#X+KH1=j&he!9FhHN4YYi^)2xJ;p|3nkvDlDoMF zl570r_?9hTLRc^RoXv+j!K5RtS|(>(>0{F4l$Kj>ux=fbk&p>xO4Ez>&*jd zKN@pZ(@(Cm4vn3l|2@n4a_lZWFU$I9OdsoK;~q$OJ7(35{jE{slY4#$0G15TBu&j2 zJ<;E~Yy7Pl4ZuT>(sHVCzA9~rHM=LWtlIH|^~d^Ie;%Knu(e-Q@=BIv%bAjKi6omM zQZjIuiYq1=$+VW|6m&N;;C3X*^`f$UXqI(4CoSb(n1E!+w4>N5KFygwoG>flA2FLd zW?Bm;^tb=9uUtx|^8$D_W!8Ep4AVMgRbpihv3@Y|Mm=k^_2-E>`U7uTsgp8$2QO<_ ztG3O*(_%Y?X{-31HFwg$KC=NDQ;5Tj6f_$@G4mq6M%!EFNY~!6 zHaZ6C_oP~nIc8+6meSbk>l|@ZbOuxyrXz`j=hS}V7^26$8l>_pJ8F%bk*@Cz*5=OG z)xneXx#noBfk0pojl48+U=+SDu#|4@z`b-U3*1k)Re=ZTmLJ$hw(b>DI>Fk=ie;opaKx*K=?6-2Np5rB8hJlfJZ`r?Pz2XrK!r z>oYhVM^?`CXJ)oiH0W!jMMPY8EHI^yyF>(ayB*oRz093ouS74 z>LFwd1r==+T5x)B1`G|}JI`Pkx(@b89E}3K*CaaTlpUkxG&blmoSGY;QG}<1gQOdv z2)$*8^KBL(08*gkVfYr&^j6X_9LnAX;B_`=QhJhef8~o9MU26;@SL6y7FopZosBHh z3zXN{M2t;957_U&iE@8>EnebqZn1Cgs+eNsOW{H;(bRl-2wU!fIX*aC=Zuia&;rca z6fT$gC>|6&ibh05gXc$-5O2bR3U83Un9h3mh4@kbY&q?7e&DVCK)5@BuOU2?#+%|X zhDywlAV;!gLOacX)=~L=S->%Kvt)&uwsXHhQDB*OhFhMHaCcUH<$Fq7U1;y;@ETeT z({_khsV&cuN=TSvUbk4rE{1pxXLP1ipuDM;(ZdOrYndt-bU6b^IkzYyRkD>+Sj7 zwI{5P=l9d@!QVce781`?ImAn(2xZZ*iyUesQ;?gSggTaKJ$~d)V$o{1EzmXnt7F!V zh12z4AG1y@9BIGrm?nCGDudTpWOZFsZ-4S=TWqKGmqmj{tv-@UI=-(m+JJ;N2zR>b z;uV;%&Nc^9t$Rz3H7RdchdM{Hm7kY6{1Of=au#^r5?+CN82B9OVS+Q{O2b2D^dS)s zY0p{D<_+__fJTf>MR`yc`V12zlCjh|kbpCYGnzqOJyuK*76pYX1-CQ8)eW~(Le^!y zaK|g>QdI8=nvOWsOIK*dFahPu^e^F{0y}yeJQ{dX=&{a`K)aLD@s8p-MXd+ZV$rlN zQkX-fPFitDbPb0MA>q17B8IAHd3eZc^1Zc#o}oG!`fx&VMyOZNS_@SbVH7gf4#lHd z%d}Roo%!fJ@sj!qq2j*@;fmQ89*zezE?JCC=$bHxT0zJdd`h-~3CF6W&p29=KOjX8 z$=R>CPgzZQW38mcw`+#Abn!UPNUCn1`y66>Mg=rcIn&8oeNK2dUe75lXIkTlVVijF zjL{KK3MWov&NFSp87_;yT#X?TZPj-}$b%JyKH1_Lij314DX-ZmgcI;ZJB4%7jwDdy zT}gO9$H@b)gZCW^cifGpOGk@n6T-`L8!4RCNIq6Rs)JF2z%Pq(A<)&;ZcZV2yZ;-X{QfS45RNap*Nb*=)4gP-vFet&e$zlAj0#Rwl%+^_E#6$46<6~ zZCV9l+az3wZF7sXW*FAUV3=<|NKQBT=25XU!5+>VhVtz|vIMP1?lSbuE7srcTG8)? zPh`WTe$*gaEJm`$V(OoLWfd)1=fS2;T@Q0cgsT@ABghDRkp;nu+nn)apObOwV$=nt zb5kJ{GKGo&NkX~pE1sD0=8mya=jNc=4DVW0x%K$0ULLtHXwyIs;fPW7hA2Xnm;(z* z8mPj7Xixwe5Pd9(B)Je{iA<8tpv^0XNNH0{X*$H33{!3ss@COZ;|b}oI;KKaJ6cJD zFYg10x0b|hWK-KR5GFXx+y=E4H98-Eo28JE`S~_WY1MV7pvl%x4sU?NR#s_>N9N^v z87fowEH^PUxrXbhZGA@pb(SuMZHLG^!$e3h*(;(W9x%VROlC6*8e zyhbzN-tMh#ZQ(a#1wcc+Nj3Kd;%{|ZR31McJ(!k8*s#98Xox2Rj}(G%@|Nl=1@3O> zG4!>BQ4`Gsy+$5}WH>{&MViTWWa^xiJSUtV=ODF1Eoxm{a1cp&3=oD|g zv!p_Q{#d54_mzt0}j`q-oc->*z;vp$tiZu)j6R%N64?POM4hzIa zWosj~TKK}6wq6h#-bjqrPxg;e15uBMpMoqo-ScnJ6Boa&Nh|JeAUqL7lw+4Q-Bm}sRDl5@LOr*-uC3rPqEq=#6Z& zZ~Fu_LW5mPK=XJbZu_=@5^~#j%>v|&RN1#}Ls`;b*I0=Zy1IEIEA87lA+C)B072&t z6C5Kp45Xo9%8d??PrkpHc{|J=HM7y5@^<**!?c%x#}Q}L7!oslL_>4)IQN0pq(05$ zagg@ml;CXE8XxKKpPLBpOZWmfXbN5j1{hVPX8Vu|-*Er@Rw*9RA$M`#b!}KT}BR13dQmNY3E1-8yGI)<2sLgZ>Yu*GJ9$C(G-l#Ru5pWr!zO|E0zB z>EVA}tj+*T4wA*u*+;r>pdo#yq*QFAA7)w~?{dqQp+~t#Y@QGuPVmsFDQI|(Hgx=- z(iCjm(q_v1&EujrnqaQtm5WR6!+rY%PLv= zg#Ot#m?|Y3zg0z#XNGB8QbRiydV`r8VS!iZMZD{(pXy^HdNQ zy?64dh~_}_MHAnX@SD?~t$qFTzSQR5PCroLN~J%zM&O@@P~XKkk|VE)j4x}4Ph~v+ zs{j0#+NYzKEDzHlJ;~&Xc4AL6?z;MN{1xpcUAy}7=&M>MZS+3)0U9M+UI}PDn&=?N zKM61)BZ^1-_kOMI(!1#XYhP>5CHwI)p7^2$xFlakK_BS}r&9@C_eXIYV(2+K-)`1h z&#{W?dB{Kin%2AEXCUj)@w8J&G5l~PuM)=JV4S`W(e(u57Z|7T()Bds=`)p{TNEsw zlhgRKu4!?DI~a=AUe^%Dqq+`C8P8#;q)0`x9nI()j7PH{#ec^*RRhf)#oq%?F7D40 z5~ptlbbTQCb#VX(GlZ+PBaDB@Yb!;; z;yB|cr;{FhjUC3lpdSamBPZlV7C6BID{|GuA2a?A% zQ8+bay1Fs$<^pv{REQMDhj2m9V7wpWmxm}lJs8hsJiUT&9PP50FpLS``Hm7uk5`28 zjQ8UTh-P#u<6m&;MR9sPp%UA{6_CmLa~U7P5h^4c^NTzt2u?vy7Ffpkvs@a{Ua*4k zU)`z&DmxaD4eJSoGkDF;|qo=+`;&d z7=MyeM!yEogpU{haZ!t8cAI~JXQL$`_*(RUE)a)YkxazfPm z`)hjdK5w(wjqPgt5B~Wek1E32r?_vIYg>p>taUu&ceabyhyJak^&D&c(FEnK#bOuy zFM#a1%;cxq`7p7An(Yo=fdg6W8u-bFd_Jr=81KMVT;^;pVZ1Bj*^|`t{kXh(DBL67 zzeN!qWPv^`u#@Y06XRKo9~-IoquCkE_~-0?67vVxflo>le>D5Ung6iNK30;K1;#O< z;0`5_$CgfJe8yyjFJk@~jNjgFh0kH!al7K*%X$_tzK0#2O?qf0FJZ!>gzE+FVcgC2 z@LisGCF2LV5Td7=dl~;_yUoze`0cDGx*2ZkC#cUs+kOVR=QtBmJYh=ovGsT$Qf!(o!Ms?ov^? zmP9Ly3Z#nS;!=0jYEfEMRJ2AEtRN$lfGEba73EdnEGt-B_q(~kg_+<|No9E% z@f8-h;E%gRtgomnDRUKz!quc4qD5=`II}G1RJ^jhqNvROSr>g^K3h;KiU}j{Fa-=R zDHFx6A~LbEplqd7xO_v&O4n*pSc;gzYf)TST3%HoD732!Dh0{Qi70xo5jlX7en-4M zcmTz)P^hFUT_t5D2yKNMaB1nvlJ)+L@%o7A>x)$aR5(R(Ws$V1w6tJF6@{E44u4Ao zWf%EdPE|xs8u5=?VI{l<4zF-kebD;%x~>2K delta 7084 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 T^WJRc6Z>SJ7t3)B9S`^)3wK;< delta 3482 zcmaJ^eNa@_6~Fhv^8*of7ZwEND?#K_P@_N$NRYK#)2eCfBxF*B;0CG4Qdlj{h?o-o z*m)YIx9JO-Dz-J9DWiO>qtA?m1*bv`HcVm^)Bb^(I3@LCOhfD@p|$6{d)AK3w0CCj zIrn$Y`JMC5yZ7#H;LPmt-_1UpuDm$bp1CTlvyU?zSBH9k(iO@3M2w}^va*-6frmK8 zoSK@{`wMHdy)&1U^hbl|08XaiK@S?b(UAU_LG2Y8)`d!sX&*!T=Ev-Mk8oR^%E=ya z-nvMcohPna7u!2~ICFaKCqQWS<2b8t_6Vyj-QI|nHoqqlim5ieh9`H34Yrt9%V33L zSS@{|Jwux2n2zjr1O_J*uixn%p8U&V2K=fW2{bhV1#sqrn^&C!E6ow`sv)NGC~yco zKkF8kZ3!=5>E`Um7dJb-w>0%nk92429gDYl+Pf>@-8==($H9WM>syXHYjc1#tSvh`ML`LsWicgEZ(Z$L)r^JQmv^keg zVK+uk`TibVA3pD;6P$S+cQkeL37;#aSjm`sT&644?6W}C)KHisyNA4vz_4Q)J99e$ zs`~Vp7=1E(<(XsByFgQWL2dKzTdJvDQcL}wrq+V0*^l5n|1iuD`PwmGPHG2NDq?*j zix>0o=sZ?pAn#;XtoS-@q08ULOQ5-@>^LRNCXQrRTCYSx9|9K78CiCbO@!yf+xJ4c;1h>QON33V&iPLG#z*zWSj8JTDUoqN z;B`!Djyq7CX7%;w?e<>d2#Q_C zA5hd8Lnx|^Q4|%%1d4Lw9*Q3rtQW*{MmUNxV*!dHV+o2?Mm~yMV;zcg;{_Bc#tszm zMr*GfWR!6Tm*GYy3e`B@>q}YjQOM4bqvjqOMA7Eowa9GY=bu4^u(P@lZS`|FlAY48 z14QIm_PXDb40cVfBKzSAa!h!y;SoOcZ+IubeUZ-AiTh4?&5$Gn zVW=POhCqj~6vn5%jQ*<~_ZzLl>eUX;ki_icZMY2`5U0M|AvP3#pWhN|3gX4t!eXw8 zuL_eE;k6`pwL63{ytf9h(#c9#`D&h?uZWzY<-W>iIbS5pTY^><(#czHpb*zL#OcyR zeob5{P3Kp|gVMw;Z$O9MGw(sT`{p>k%}^{9?7cMbLkw{LPxA|C-t_;?%S6N4G``H& zu~y;An?n4$tWeK7Rug`q@7#wYJWWyjedoTp%x7`MKcp+8e4TY<=y9eV{pR~Tw(>mmO##ZZ zY*vC?i*SN*lJHW(v4J@H39lhMSHkQf;cpTC6yYPfb(AM%Y+5SmXVUzP@F2~YtZE$C ztWa0QeHq65lJ0MS+o0MPpOpAo%5snJ1t}7ruSml`3BRjI95)z_5dDiQJho*XxFOvK zS<;*;t;_FUw+Ww`QN?co$EqvnER~Rd7x`CF7s?6u5q^!j zmPp;i?_1bKE$l!tGdT`Wz#s*zp~UcoYK}{UyHllqE8%}8d}@ire?<7lgqITkdcyxo z_->B=@VI?sxJd?(U|{CGit-NN=COkBVq6E0)dTYX2Ni^u9gcqy9!00LNWv^MM4p>; z;y;i0Huyx4p(9Zyc%1^02!Eei8axPbgm=w2fQf`}q|PM}PpaPj5xnUvGQUH01&>KA z)%zvU!Ot&qSg1FJF}_3Z0>_dJMgba^1QrcS?bou_8Gns(J}t*NW=NTTZ6 zJ@wmJrN>>vwz`@C1(I4<9dp;a>h#oc-mV+tJXtxItA8@imxkfL9DI__HM;EvUu6v* z*NH*7ll^-64W4W3r1Q`@B;ltl`Vnxq2iFB*vK{ziH($SXgJ;bhAC<07J?;~pKR0=d PB6aHskJ9gq^YH%wUaO3Q diff --git a/dsk/rd/emr/system/terminal.emx/app.elf b/dsk/rd/emr/system/terminal.emx/app.elf index c83895be6d830bab414a7411495937a8a8e5521f..d009b1307e356c8ad1c80d1b742224cc074c2f27 100755 GIT binary patch delta 6763 zcmbVQdw5jUwcqE!ApxS337Nb|LSlI&L>_@W0D%mN2M#Sz2&7l4n2aGvAPO-CC?o_;5G@3%2o@oF(K|G;1jXwVW9RW{&GV_|?v2!yFCUbd$^9#cPUQ;T z^ytcm4;uGc$648N$*!yY+B4evwlYm&$Bix4R4a>;2hi0(qm18MQys5ZpnP~W)Q^&l z);Ee}yMIL*gWaiQ-LyLmR8!kli>{=Ba{J-f7!bN*#rxJWlD&hx=wBs3zRKjNALs4` z)YN8q;v3W4)0mk?9tWY@9-+6=h&N1?p4HZ$Ez_hf)9-^(vs}}_n5p)<6#ozY5e(|e zU6{KArLL{IZIr2L9jv)?7iGZms(NvUtlR$f0GaQl_u})R6;|^VkdhtYx^fy!Goc+M zWqZTaIE**M@A$4qTSje9ntN1YtyZfw80^xOc!+t_{;R!aXd@pmMn`AKNba)eBpNnE zM^CipF}p|Y*42Raj9%3L-5AMHwnP1Jk#5^@#CSP6e>QiXZEv$Q%?<{GZna<1mDu|! z3;nKW-4+d!ilz&5%i~{BQfz^r0#k1O)VSLgm*Iayg1|+~eznijp(}p^5A==K;2}Hw z?z`^>J)QG{U7D_Z@P<)s`}^`=I zK1y=m-h|vK7|}YLx*!9J`2*99=i?^a-9H@*xCnS3l)K>y+ghosR}PbmS>uQ+C5QaJ z^EKl}T!#Fy&q$4rPHdeEmXxeHzGwKcV z6!8P|i-ZXUT@>Ye0Yp!3w|3L?Et;CPhublI6;uB;ymTeyki@i|i%%SmfUxE{g$R{Q z<9dP`EB}NdV5~#=X2pPO!|lf6(eV?`74bv47Dc8jConS)Wh)3>c@1yvnT|$m<<8O5 zavCt5^A8xZJQ-n%R{+?#RPxwLO+m}6MgOy7m%T)`>&miQs$Y$s?HWbXrZ%Sq1s6s% zy!)>Sv@`w8@lO{2jC{n?seCd(T@(}w5=9(1)-8M5$VAe33RU?d*f9Ju z4Ok?X>Q-sS45!Vb>|G(x0X3l64$^p}TsdUA)3|r4sB_X0z3mvK7YX ziE%l3!uSu#dHR6 zE&JO&YM@i?r~LFJA&y51j5jCUoxMUx&p_fqqD@cMl^=0x>>^z`xDQoon*~6>V=Bq& zN@_vNxXHUE`OUpFKkPaaeeCO{1S(3M{+(+pc8R}GTG^OBUA2%8*FQo zS*;z7Bt(^q&T(`YoNB#g<`0R+lFWqR!py-0qb4&c;%QjprbZ?izs}q!*Cw90PoF725ND)iJt@BvYrK~Ao9SZ*e0na9yfC}drey5pVXBd%)4+#U`(nr_wW@@8 zL(iToXWNZ;vg751IODVIbU8Z4u;z@8_}Uhds*E#cr z#TviNao8oOxC4>SgWTokV|l@DO*b_t-T{qn_<+4JYheTzuZ=aP=PrmS90+1djPYo0 zss$$=qJDI5czi9U<<;Ct(y&HI^-MI5%osnUkx4C4GwX)98rvlM)ty+yw}U7*QF}o3 z{HyOU4fVd0G*tOMq2Xa)FAXI=b_~Nx-<>oR`ci24k?(FA?)A-}VUBMB4LQDlp<#+| z4Gn3&pV5%&(`iWX?LB70ILf!5rV+k28Wi7!V=eJ>{yZdagWW8mavGZ2>J!bhUA;mX z(Us+d;#+`|sd2e^81RML-sVgJf4besn3r5QDg@TsaO@?_=;4;OaZ7!9u!OYsL_zJp zX~NB(CsJ3=V7O)Wc%Jd>yyOXc2f$c}JWZ15QJTm07|0Hsn~_*;OP52`A+20~SpgHSB0nHQr)}9)f9~Gl4|1Q_-bHPIn zVtALP?&~jx0YtxtSi0(m*A~s)-G@;8@X13kqC%h88j`?W$D{T^7(yMbrjZ0Pa*x_q zXYEv~;5&h4c6!i7Nlvjtdno9D5ji*3NG+Hu?KKJu?voZ8FBOa_O7S$Hp*#i|YUyf! z&o~?sieji4f!U6~g9N+WmHm==19+cT=Y8Rf(Up^btM|d7md^_Akd2qr7}tewgTa9d zshPqxmTPSTNE{_q^VIiwihA{;UQJ(2(E&L{E%&+GmH)YD&G(DizR&D@<1;nS7(PGI z74B*1_tXav-|nv)(7HmzInPbaOd?_lYN;o*;Yj>3PoH+IJH>O7&os{o9>#K9waGa@ z;^>C=er>n*bwf9H==KQ=T-Q9up{02~6xVbYlJ@`Crc1uAyzm%4=;dvdOFHIh%FL$Pd+3_yBmhgEAVNdLIAYDD*}0vc=9b)JMQ(T z0l3v}$<)3_ZLU2CDxjs)5mQ}$oScBg{X^_BzUvU|Bf&nP2P}_FpuIm+89*8W%+fTH z3k{Smr3-sm--dJ{ZHo^q@*v<&H9#)I3NW>=r`ohf`Jn7kHUc~wwEikTWeNEvyp7|i zAjG1pClD9%$Ft#4FS;8pvif0QboXQsy?F#^n8X?pCS~?KSf>@x4{Cp5%+sP>x-vS~ z>^#me#NlW4;?}-}Yj^s0e?d)%nu>Bghj*NwMWzuQQQ&H=FUBh7aeU%NFo+hG&bg5o z`uK*-o>L!vyNbJA0;4BJbGy_)c!&elX7f-Dq%aOCL>ZZb=y>GLY^(z^;Uv?k zZ2V`;mEX%G>qh$gZ`adLVH7=I2!}nOm7WkS4e_CoqJJ^J9sA2y}Xv|;DdZ>v@Hl5nkVSXpi^$6CD3Tk z(MFPHk))PMnk>n8WEq(Y^M}7ZUFIn<^0Zu|WnsFzd*Pw(h0-3kBt5lljJNBOG}Qat zpQJ1o{dmNJERtS$((xy;p^Sby(A>X--i)D1a2&sBL9!HqSAZt@loHtvk~GZ+zkp19 zY>8|KIe=5hB%f9y+dVnY~f=L?4nEfo0BK{%y}4AGAQkTfx$B9jE}@c!p1 z>2K3ChioSX?H4_V@JD(}1s+=Gb%C#N96EVg8ZXNwjzeFZk%mcfNsagBS!w>t9r!py zXu#4`Tr0>DeY6P=d4SI%$7^Lf!J!ovnfMUaEg}hdROmf+R*H4tXE&3fSa=UJ)e=b; z&p3fs37l$-o)UpSE$}HEW@Q3@Q{eb{Xg=$_*7u|_>A#=D%?~#7XMu;z)SBYft8>3A zzS(p(ej66C!rey3cZ;?0MRs{>-jiZ8ygedw)9ig7YVofK z_NNidPB7g|=sDs&1Geie!OqX&?6I87P71tm7RP@p@H4=zNdLY;8!-_(Lf&QNa`{lE zKY%>p`(|?dWnt$s$Me~V*_@Ff7@rA+M+J^cz4?4D@Sn}#@{>eue(80*k2r1$cJ`p` zNT_~V|HWxs?LUOMaDh)q=XjLBEduWp`3SicEAZzA;bS=NVwqyE#|T5?gu+im9CX;} z$q@MREWYra9A=pUcL@B5h;N3#Bc^hBRmj@~zGOP#-k5Vzlxu=mD^za_gv?{Y=}?f1 zfYT;64my1+gnZOwz80N(dhR#nhp-fJ%GPq2l?eGS`MM)mDEKwrZRc?ODg}R;@V!Ck zT^9Icv6qrror{*l&cLe>YRj*h+!F!0{+{O2n5e_UvVE%?CJoe-wJpifsvf4-R{u z2RpM}uzNGP+be|Gw*~&ipi(>QJws|21iN%NS381e=(!~DVv*E14znv>={%gd2DaH< z>|8C>UHc)Y+5it`?lzf<5TqTQJP!Gunnz^@OI zPv*FbJ(b4&+AbEz77B_u58~U%(gnVBP@|b5@MMv-vBFN4z+V!Z5NeyV1fFCT4N3<8 zc{HDSf+3489qJhK1-@p`0to`I5Dsa=PDW?}f#cs1=CerPT~m0#^z~-+S}qt-gUWTK zz+Vs!g|?tr;QxE5=7N+brxrV$Wt+;K#cS%TO6yo?R$5(Ohu2rt zl{w3*HhORTMapnJY|^Z(wzjI8Jycibs4ZQ~$~KjiZY*QqZ75&OYU-+MovgB~vUI~{ zR=2s%Syss^9TgSTrEE=gm9uy)t8>;mt1Bw_SYN?vD_57-vWmL0vh~dI5NUG>8eqSc zm2!25b42wT24Bi+tE;?K7p08}reHm6VLkYXh03c~U9F>PwfEXZY3#i`MtE3XUR+*P z?qn4etIIcXM;@-&ykRW>$3u0@;jAua#gq?Pw4$tvRd2uxa7Bf8?nly2Z`Vgsiky?@ z{o*5O@`%ut&HiKW#7k0+HFRTQXZex#duuL9Q=$fLZ~|`L@BIVBZGJIN6Wx3mwsVp9 d+e=c$h{%t*h1Em7(=JOnvh!2#y35k|{{zkPnTSw4f{POzpzbZZE&q0}C&^NyBI1b+UKL&qG6s{AcJl4wTewRZI*- z2m;hqtH=eQ)E4wkWSKHF3k%dhpYZF5 zwoKd>{^ zL0`Y)2V4}>CdA||h3pPfP~7%*3WW3ew{887E=A4*9mqG|g$PN3{bnB@vuLW9=Z>JjR8rUOnWGquYA~G%#60MEW)KS!LYf+rcI5=e9$TJc=9$ zJzTzH_U5MZ5YAEeGWOo2OsPMe{Wxi=^g}v}GzUqy5}3str@NH^S%xmXXA{_ZbC?vG z#CDpOhWT5F)%*Odp`mMQKx#_SGb~WFxVYdys-tVANWcNWz?9F)}b?AU>cYF#n{49>$2(g);ScEem zq)UFRU^ukbEG#cHc=`jN!$Y|Wl1!29(9;g(JP;H)9cugTu6o$Y=Fp^+pTIivXK$z837gnJ5Qh^}Hf?#v+3 zKV1(#8*2y1)-86p$v};zTV6RVJt!ndNJ!#=_dSxsjV`{LhEtX2phrcH#|8#T#k`ec zpa-YTAx|lgGC>-)JO z&hN&MH!V=)HUQx8)uvD2k6>9z4#~ikS zZrdQPPj5KPL&{iQ4gi!12av1CFJ?NY z#Xn1>hs{oR!ZfODA5PUb%%U2bgdahd8`-t_uroOGjNiO|i{Z6xZ9;DD)M4z zesP;)Vb9Nxm_B6~Gy}ziOt_=$4wFBKaL@LRhtYmaXP)`9X#q237qJ7`!R0H`fd@00 z#P3?XL%lD;B?oiJMwMdo!q|Fyqo*GN@`C3$gdsLK?U6nPe6cue{Xhm%SEuIWL3A?L z*1yrvEf1!#Svi4Yze&>^4zPeMGb_oNMK7~mIZLU+uIEe+3vkp9@?>7;M+koJ@rSY) zdd}hn6C^h6t|VvCJ(RNF=Z-hX;GW-9o#`0!IreI91pPbvFgJ#tW#5AQG}OVP??dG} zO<{_b(&i*~F2B4nqo6&bfWF+= z+7$H1Gc>IZKWl(Y;BaXr7HUdH5q#7T@aAJp2)wl%*GX0oNuJ$uQ(VnI>?Hz~Qyj3cLdvzgXb#8KRXOfwu^Jw!rP``W`wt)}F@Q zk94z6;668tG`gWl?5mHyL<=_fAsEB}!^0hA)%?5pD3xl|m(-kC18O782t;TZoOI%By6L|L=j!zZ%9>5K-2mNA2eS7eV;7cQx@^yii zrgA@V!p}jD8_DfL0k4x*Tdpfln9l!n>fAlL9{}+)Wnv8G-jC zb3eBU{G7nA2weO-Bp!~35Zx?pU=s#jVW3kR&Qo*I_ajo^JE1nlb2H3kEdK%AK>UbX zoPkvwCbtBC=ZJWz8g&77bF3fV&BY>$T4AOa_y;3~4^$h#EI3rCGZT0eOqfkk4}!Wl zPN@4v44MQu25A*HhgFza1b?|$q#}W53;a_NU4%Hm3)T5wLlldII#mqgyPyiy^`K5% zA=G_|JjnZn*HVF7W^nv&fmf)Xff=n*=|8~vW5Cjm0leB8!Odw+Y9grXb_gfq#o5Z_ zTEYY#spDqapE1z=N#Lz99N#AR`vrbnOx>5B`vm^dh;#84$Lq*lV$$$os}-j(2%pIZ zNEUd9z+Vu7`V#zAiSK-`7{Dy}oq~T#Y%Si#Sh@thUmF*WmoM{A2t|VAR+oEG?@ zcKS~`Pf}N2q&D@yMLHw7Y{Q1ib!1KP%8jIKQ(4KQWu&~Ux@vVPSzETYq-rx+TfAn? zx)So+b(Pf*ts)!Nmag8QS}xIWwe%9L84sk5Wz|4hU8#P5iB1hH+f=jqq1BbEtGPw_ zn$1nNe)-W$NMq8fIE G>i!R2QtWF0 diff --git a/shared/ebuild.h b/shared/ebuild.h index b465991b..e7dc3aed 100644 --- a/shared/ebuild.h +++ b/shared/ebuild.h @@ -1,4 +1,4 @@ #pragma once // this file will always be regenerated when building emexOS // if you want to disable it goto /tools/genbuild.sh -#define ___EMEX_BUILD "26MY.01.2230" +#define ___EMEX_BUILD "26MY.01.2250" diff --git a/shared/types.h b/shared/types.h index 638b9a44..55221fd9 100644 --- a/shared/types.h +++ b/shared/types.h @@ -18,6 +18,8 @@ typedef signed long i64; typedef unsigned long size_t; typedef long ssize_t; +typedef long off_t; + typedef u8 uint8_t; typedef u16 uint16_t; diff --git a/src/kernel/file_systems/vfs/commands.c b/src/kernel/file_systems/vfs/commands.c index 81b902e9..279ed2dd 100644 --- a/src/kernel/file_systems/vfs/commands.c +++ b/src/kernel/file_systems/vfs/commands.c @@ -119,6 +119,33 @@ ssize_t fs_write(int fd, const void *buf, size_t cnt) { return file->node->ops->write(file, buf, cnt); } +off_t fs_lseek(int fd, off_t offset, int whence) { + fs_file *file = fs_get_file(fd); + if (!file) + return -1; + + off_t new_pos = file->pos; + switch (whence) { + case SEEK_SET: + new_pos = offset; + break; + case SEEK_CUR: + new_pos += offset; + break; + case SEEK_END: + new_pos = (off_t)file->node->size + offset; + break; + default: + return -1; + } + + if (new_pos < 0) + return -1; + + file->pos = (u64)new_pos; + return new_pos; +} + int fs_mkdir(const char *path) { char ppath[FS_MAX_PATH]; char dname[64]; diff --git a/src/kernel/file_systems/vfs/vfs.h b/src/kernel/file_systems/vfs/vfs.h index b137ac61..c1fa2104 100644 --- a/src/kernel/file_systems/vfs/vfs.h +++ b/src/kernel/file_systems/vfs/vfs.h @@ -136,6 +136,8 @@ int fs_open(const char *path, int flags); int fs_close(int fd); ssize_t fs_read(int fd, void *buf, size_t cnt); ssize_t fs_write(int fd, const void *buf, size_t cnt); +off_t fs_lseek(int fd, off_t offset, int whence); + int fs_mkdir(const char *path); int fs_unlink(const char *path); int fs_listdir(const char *path, _emx_kdirent_t *buf, int max_entries); diff --git a/src/kernel/user/syscalls.c b/src/kernel/user/syscalls.c index 3d81ab59..ee9626ce 100644 --- a/src/kernel/user/syscalls.c +++ b/src/kernel/user/syscalls.c @@ -547,6 +547,11 @@ u64 scall_close(ulime_proc_t *proc, u64 fd, u64 arg2, u64 arg3) { return (u64)fs_close((int)fd); } +u64 scall_lseek(ulime_proc_t *proc, u64 fd, u64 offset, u64 whence) { + (void)proc; + return (u64)fs_lseek((int)fd, (off_t)offset, (int)whence); +} + u64 scall_getdents(ulime_proc_t *proc, u64 path_ptr, u64 buf_ptr, u64 max_entries) { (void)proc; @@ -991,6 +996,7 @@ void _init_syscalls_table(ulime_t *ulime_ptr) { // ulime->syscalls[READ] = scall_read; ulime_ptr->syscalls[OPEN] = scall_open; ulime_ptr->syscalls[CLOSE] = scall_close; + ulime_ptr->syscalls[LSEEK] = scall_lseek; ulime_ptr->syscalls[GETPID] = scall_getpid; ulime_ptr->syscalls[BRK] = scall_brk; ulime_ptr->syscalls[EXIT] = scall_exit; diff --git a/src/kernel/user/system/calls.h b/src/kernel/user/system/calls.h index e7ba301d..fcd348d3 100644 --- a/src/kernel/user/system/calls.h +++ b/src/kernel/user/system/calls.h @@ -6,6 +6,8 @@ #if X86_64 == 1 #define EXIT 60 +#define LSEEK 8 + #define WRITE 1 #define WRITEV 20 diff --git a/src/userspace/apps/terminal/terminal.emx/app.elf b/src/userspace/apps/terminal/terminal.emx/app.elf index c83895be6d830bab414a7411495937a8a8e5521f..d009b1307e356c8ad1c80d1b742224cc074c2f27 100755 GIT binary patch delta 6763 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 G>i!R2QtWF0 diff --git a/src/userspace/apps/terminal/terminal.o b/src/userspace/apps/terminal/terminal.o index 0246f2b112d5e2b9acdb9d8d5fce4ed17819e900..e025d3e72b81302bf55429d5aa1137798d9b1f27 100644 GIT binary patch delta 270 zcmccNal>tuFZ@};*6|LKpy*K zS!HP^1BS^~%5suXU_%*z7NLTI$%e}6x}iWpko69zk_-+C5P=U+aV{XuF}YP)TkrxO hL`VUo4G6d=A5_+7{4n{WvOSjp)Z-}(lXoe~0RX+&ByRu! delta 177 zcmccNdBbCZhIoV`0~|PjSq=<54BQ*-8F@Ds@G^@`Zc_}Jd{r@8@P{x&odger=G^S4 zB+kg{4&*UTj#ZYPyhB+**9pjD0b&OrMg{^35Z(u08jTAqyPW_ diff --git a/src/userspace/apps/test_libc/Makefile b/src/userspace/apps/test_libc/Makefile new file mode 100644 index 00000000..5e864d4e --- /dev/null +++ b/src/userspace/apps/test_libc/Makefile @@ -0,0 +1,27 @@ +CC := x86_64-elf-gcc +LD := x86_64-elf-ld +LIBC := ../../libc + +CFLAGS := -ffreestanding -nostdlib -fno-builtin -fno-stack-protector \ + -fno-PIE -fno-pic -m64 -march=x86-64 -mno-sse -mno-sse2 \ + -mno-mmx -mno-red-zone -Wall -Wextra -std=gnu11 \ + -I$(LIBC)/include + +LDFLAGS := -nostdlib -static -no-pie -T ../../user.ld + +all: clean test_libc.emx/app.elf + +test_libc.emx/app.elf: test_libc.o $(LIBC)/build/crt0.o $(LIBC)/build/libc.a + mkdir -p test_libc.emx + $(LD) $(LDFLAGS) $(LIBC)/build/crt0.o test_libc.o $(LIBC)/build/libc.a -o $@ + +test_libc.o: test_libc.c + $(CC) $(CFLAGS) -c $< -o $@ + +$(LIBC)/build/crt0.o $(LIBC)/build/libc.a: + $(MAKE) -C $(LIBC) + +clean: + rm -f *.o test_libc.emx/app.elf + +.PHONY: all clean diff --git a/src/userspace/apps/test_libc/test_libc.c b/src/userspace/apps/test_libc/test_libc.c new file mode 100644 index 00000000..7ca285ce --- /dev/null +++ b/src/userspace/apps/test_libc/test_libc.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include + +static void cleanup_test(void) { + printf("atexit handler called!\n"); +} + +int compare_ints(const void *a, const void *b) { + return (*(int*)a - *(int*)b); +} + +int main(int argc, char **argv) { + (void)argc; (void)argv; + printf("Testing extended stdio.h\n"); + + FILE *f = fopen("/tmp/test.txt", "w+"); + if (!f) { + perror("fopen"); + // fallback to / if /tmp doesn't exist + f = fopen("/test.txt", "w+"); + if (!f) { + perror("fopen (fallback)"); + return 1; + } + } + + fprintf(f, "Hello, world!\nThis is a test of fseek and ftell.\n"); + long pos = ftell(f); + printf("Current position after write: %ld\n", pos); + + rewind(f); + printf("Position after rewind: %ld\n", ftell(f)); + + char buf[128]; + if (fgets(buf, sizeof(buf), f)) { + printf("Read 1st line: %s", buf); + } + + fseek(f, 0, SEEK_END); + printf("Position at end: %ld\n", ftell(f)); + + long end_pos = ftell(f); + if (end_pos > 5) { + fseek(f, -6, SEEK_END); + printf("Position at end-6: %ld\n", ftell(f)); + if (fgets(buf, sizeof(buf), f)) { + printf("Read last 5 chars: %s", buf); + } + } + + printf("Testing ungetc:\n"); + rewind(f); + int c = fgetc(f); + printf("Got char: '%c'\n", c); + ungetc('X', f); + c = fgetc(f); + printf("Got char after ungetc('X'): '%c'\n", c); + c = fgetc(f); + printf("Next char: '%c'\n", c); + + fclose(f); + printf("Testing sscanf:\n"); + int val1; unsigned int val2; char str_buf[64]; + const char *input = "123 0xABC hello"; + int matched = sscanf(input, "%d %x %s", &val1, &val2, str_buf); + printf("Matched %d items. val1=%d, val2=0x%x, str_buf='%s'\n", matched, val1, val2, str_buf); + + printf("Testing tmpfile and remove:\n"); + FILE *tmp = tmpfile(); + if (tmp) { + fprintf(tmp, "Temporary data"); + rewind(tmp); + fgets(str_buf, sizeof(str_buf), tmp); + printf("Read from tmpfile: '%s'\n", str_buf); + fclose(tmp); + } + + printf("Testing stdlib features:\n"); + atexit(cleanup_test); + + srand(45); + printf("Rand: %d %d %d\n", rand(), rand(), rand()); + + int arr[] = { 42, 7, 100, 3, 25 }; + qsort(arr, 5, sizeof(int), compare_ints); + printf("Sorted array: %d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4]); + + div_t d = div(33, 10); + printf("div(33, 10): quot=%d rem=%d\n", d.quot, d.rem); + + printf("Test complete.\n"); + + return 0; +} diff --git a/src/userspace/apps/test_libc/test_libc.emx/app.elf b/src/userspace/apps/test_libc/test_libc.emx/app.elf new file mode 100755 index 0000000000000000000000000000000000000000..8e6df65fd1d1023b59ae2f7c8865074ea1044e15 GIT binary patch literal 25936 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 G|Njd@oeP-& literal 0 HcmV?d00001 diff --git a/src/userspace/apps/test_libc/test_libc.o b/src/userspace/apps/test_libc/test_libc.o new file mode 100644 index 0000000000000000000000000000000000000000..8f5e80c09906a5815166b86090dfcccc98311ef2 GIT binary patch literal 6040 zcmbtXe{3AZ6(0Y9fa_2mW$g|f~rUrqAH3~sTF^q2p1YBsx6zUR6t zH+RqD+k)uG-kJI4d*6FAZ)R@y2kHCoX>V&2y0nSAMYE?-A;xZQwue-6NNg0{V$=%X zy@>r8d@SMP%;7mity9ZAR(Rr?6;@ZQdiq+u2c9c+vF%Ucn}1e})W|{WJbwu)Lv9u|6{gg!Fui1*IG}i|Gr-04 z>)=dS)8|)k=S@%d;|fhb`*p19>DTWKS9AuNTO>@+*A=lI@gn1TdLG#8CS`ck`)UTV zGb4g=a5A&r1ES45jm}upQyAau5XP!EXN0xfI}KyQyXvYCF5U@Js-+&Oa9-8noT|PP zz8(H!-BcE*-hv>ugW=-TRcLKct#_c6Rjnmx!MTFbWoX?BEr=UU{s2w!Y9~BquS1k( zP``k@`gydgPoqx#S=6m7qg41os>OQFc7ejh+u@-iwZf^(%J7OZ#P+(ljYUw2v`)_B zjq`Bo(BV1IvID192xQ(aXN!&}Gj_4)WN+^hBaR;w%15MA3!HM+$x1)S7TjdMOB}yL z+!d56cLl&m2DL!s+=^2MY)xNo&4JW}ojJM$cpP1f`VI?HjI1nxK{|AL76CKyTtd_4tdV;LODxg z2OK*q2f#(KP)5Gb*nxzZtWm$xPn%e5Iimr&>PZ1ew7uvCj?E@SyBX zWO^}njZnN1b8GKd?>5cZ4@EdZ`=MBvkU7T=s-EM6!U4!0ERTvQ0eLy-dI3ae zd!9Yn#3MqN$QF)m-MO<*4)nu{JXUoBh+RT7P(_i-j9aP{oxs7puy1&HP;T9~e{`E1 z*p=Lo?8i00f@e#@KOQd_7VV<#5@Pscho#Nv>!0zq#}A0MT2I@S?hQAb0rHoDi~m?Q z<0Exb&yU-OH(vkX0x+VnZzB%ntN764hokX6fDR!JWeNk(JngzqM* znj5rnzO8h2#NgkG!Ba8#z8HLe3_cQrKNN#M8iOB+!OJmtH3mNsga0T7pNhesj=|5w z-~unyaX6WoWJY9)j$N)+#t{>EoNUh-FO&mclm=UM?_bZpeurYOoZ>jO&}ig;r!zMh6{9@j)Xr1AxD}G2d z@^6HH9p_I7*L>~ww1MAC{hw29`u(-RKS=$vjL-e5Hwzfke)T*T7$3)UoPT5ZXBhr3 z!nMu|)L*9BT<2>H?}oP4@1&~+`CPx7aIHT__L~`>=RL`Ayu-BqUPI@fq;o&xbDar> z-^6sv4CiqkGxXml{U;fp>z`&g*LjKI-0y1)=lnUs_4;g}{$ClN`+b+;e0@GJbZ(=5 zM|(68GmkeAuKn&J{-zlIR~XLozMbKCmUX_qY3ScW`YFce^E$wA{9VyHk1(9;A2syH zNWaSXT>m7)xz0}woySS%myFMKUS#;^Se(B#bn2w@GUIcd*9gbGfcN3Ai2s(M^E<-d zV>+9d-)=O9qVuS}@}a+(a5L{)4E{3dCt~>98UA_D)p@zw(7BP~yN~fPCe8mo!}EczJ_i3w4E}e*b$;)opx$PD9{+8aa45*XUbUjf0O44D5&m^NhZr9vA13`A<8%Eg z!|^v+>-@~nnIxU(7@zArZ}5LX{BtpU3BIr(ji{l-!U{63D zcu}3#Ezc?1N%$TPL{fbNB`17eBt19k!244PzC=Z`?7}z6k#aRz@!-qX3nqbsmQH>= z=h-EPJpX@{1amx^Jcp<_gbyeeXq}>7^Lt14w?G3aLmHquj~5P>p ztgjJH+YEY9`N;6Aak@rySA8F#=BKqE09(}LxmM!1iJ+V{26X(!}u;da0!HSO_T)65+};!Si2<(a5zJoUP10Po;d_A3;BRuic #define EOF (-1) +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 typedef struct { int _fd; int _flags; int _eof; int _err; + int _ungetc_char; + int _has_ungetc; } FILE; @@ -27,10 +32,25 @@ int fclose(FILE *f); size_t fread(void *buf, size_t sz, size_t n, FILE *f); size_t fwrite(const void *buf, size_t sz, size_t n, FILE *f); char *fgets(char *buf, int n, FILE *f); + +int fgetc(FILE *f); +#define getc(f) fgetc(f) +int getchar(void); +int ungetc(int c, FILE *f); + int fputc(int c, FILE *f); int fputs(const char *s, FILE *f); + +long ftell(FILE *f); +int fseek(FILE *f, long offset, int whence); +void rewind(FILE *f); + +int fflush(FILE *f); + int feof(FILE *f); int ferror(FILE *f); +void clearerr(FILE *f); + int fprintf(FILE *f, const char *fmt, ...); int vfprintf(FILE *f, const char *fmt, va_list ap); @@ -41,4 +61,32 @@ int printf(const char *fmt, ...); int vprintf(const char *fmt, va_list ap); int snprintf(char *buf, size_t size, const char *fmt, ...); int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap); -int remove(const char *path); // file or directory \ No newline at end of file + +int scanf(const char *fmt, ...); +int fscanf(FILE *f, const char *fmt, ...); +int sscanf(const char *str, const char *fmt, ...); +int vscanf(const char *fmt, va_list ap); +int vfscanf(FILE *f, const char *fmt, va_list ap); +int vsscanf(const char *str, const char *fmt, va_list ap); + +typedef long fpos_t; +int fgetpos(FILE *f, fpos_t *pos); +int fsetpos(FILE *f, const fpos_t *pos); + +int fileno(FILE *f); +FILE *fdopen(int fd, const char *mode); +FILE *freopen(const char *path, const char *mode, FILE *f); + +#define _IOFBF 0 +#define _IOLBF 1 +#define _IONBF 2 +#define BUFSIZ 1024 +int setvbuf(FILE *f, char *buf, int mode, size_t size); +void setbuf(FILE *f, char *buf); + +#define L_tmpnam 256 +char *tmpnam(char *s); +FILE *tmpfile(void); + +int remove(const char *path); // file or directory +int rename(const char *oldpath, const char *newpath); \ No newline at end of file diff --git a/src/userspace/libc/include/stdlib.h b/src/userspace/libc/include/stdlib.h index 8709ea8c..6dbc65ae 100644 --- a/src/userspace/libc/include/stdlib.h +++ b/src/userspace/libc/include/stdlib.h @@ -1,6 +1,10 @@ #pragma once #include +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +#define RAND_MAX 32767 + void *malloc(size_t n); void *calloc(size_t nmemb, size_t size); void *realloc(void *ptr, size_t n); @@ -8,16 +12,38 @@ void free (void *ptr); void exit(int status) __attribute__((noreturn)); void abort(void) __attribute__((noreturn)); +int atexit(void (*func)(void)); int atoi(const char *s); long atol(const char *s); +long long atoll(const char *s); +double atof(const char *s); + long strtol(const char *s, char **end, int base); +unsigned long strtoul(const char *s, char **end, int base); +long long strtoll(const char *s, char **end, int base); +unsigned long long strtoull(const char *s, char **end, int base); int abs(int x); long labs(long x); +long long llabs(long long x); -// for screen clear command -//int system(const char *cmd); +typedef struct { int quot; int rem; } div_t; +typedef struct { long quot; long rem; } ldiv_t; +typedef struct { long long quot; long long rem; } lldiv_t; -#define EXIT_SUCCESS 0 -#define EXIT_FAILURE 1 +div_t div(int numer, int denom); +ldiv_t ldiv(long numer, long denom); +lldiv_t lldiv(long long numer, long long denom); + +int rand(void); +void srand(unsigned int seed); + +void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); + +char *getenv(const char *name); +int setenv(const char *name, const char *value, int overwrite); +int unsetenv(const char *name); + +int system(const char *command); diff --git a/src/userspace/libc/include/unistd.h b/src/userspace/libc/include/unistd.h index afce1802..6e73c803 100644 --- a/src/userspace/libc/include/unistd.h +++ b/src/userspace/libc/include/unistd.h @@ -8,6 +8,8 @@ ssize_t read(int fd, void *buf, size_t n); ssize_t write(int fd, const void *buf, size_t n); int close(int fd); +off_t lseek(int fd, off_t offset, int whence); + // filesystem int chdir(const char *path); diff --git a/src/userspace/libc/src/_syscall.h b/src/userspace/libc/src/_syscall.h index c033e361..57ddb3c5 100644 --- a/src/userspace/libc/src/_syscall.h +++ b/src/userspace/libc/src/_syscall.h @@ -3,7 +3,9 @@ #define _SCAL_READ 0 #define _SCAL_WRITE 1 #define _SCAL_OPEN 2 -#define _SCAL_CLOSE 3 +#define _SCAL_CLOSE 3 +#define _SCAL_LSEEK 8 + #define _SCAL_BRK 12 #define _SCAL_GETPID 39 #define _SCAL_FORK 57 diff --git a/src/userspace/libc/src/stdio.c b/src/userspace/libc/src/stdio.c index d3d69e9e..336bc666 100644 --- a/src/userspace/libc/src/stdio.c +++ b/src/userspace/libc/src/stdio.c @@ -6,9 +6,9 @@ #include //#include -static FILE _stdin = { ._fd = STDIN_FILENO, ._flags = _FILE_READ, ._eof = 0, ._err = 0 }; -static FILE _stdout = { ._fd = STDOUT_FILENO, ._flags = _FILE_WRITE, ._eof = 0, ._err = 0 }; -static FILE _stderr = { ._fd = STDERR_FILENO, ._flags = _FILE_WRITE, ._eof = 0, ._err = 0 }; +static FILE _stdin = { ._fd = STDIN_FILENO, ._flags = _FILE_READ, ._eof = 0, ._err = 0, ._has_ungetc = 0 }; +static FILE _stdout = { ._fd = STDOUT_FILENO, ._flags = _FILE_WRITE, ._eof = 0, ._err = 0, ._has_ungetc = 0 }; +static FILE _stderr = { ._fd = STDERR_FILENO, ._flags = _FILE_WRITE, ._eof = 0, ._err = 0, ._has_ungetc = 0 }; FILE *stdin = &_stdin; FILE *stdout = &_stdout; @@ -49,6 +49,7 @@ FILE *fopen(const char *path, const char *mode) f->_flags = fflags; f->_eof = 0; f->_err = 0; + f->_has_ungetc = 0; return f; } @@ -75,12 +76,26 @@ size_t fread(void *buf, size_t sz, size_t n, FILE *f) if (!(f->_flags & _FILE_READ)) { f->_err = 1; return 0; } size_t total = sz * n; - ssize_t got = read(f->_fd, buf, total); + size_t done = 0; + unsigned char *p = (unsigned char *)buf; - if (got < 0) { f->_err = 1; return 0; } - if (got == 0 || (size_t)got < total) f->_eof = 1; + if (f->_has_ungetc && total > 0) { + *p++ = (unsigned char)f->_ungetc_char; + f->_has_ungetc = 0; + done++; + } + + if (done < total) { + ssize_t got = read(f->_fd, p, total - done); + if (got < 0) { + f->_err = 1; + } else { + done += (size_t)got; + if ((size_t)got < (total - (size_t)(p - (unsigned char *)buf))) f->_eof = 1; + } + } - return (size_t)got / sz; // full elements read + return done / sz; } size_t fwrite(const void *buf, size_t sz, size_t n, FILE *f) @@ -103,11 +118,9 @@ char *fgets(char *buf, int n, FILE *f) int i = 0; while (i < n - 1) { - char c; - ssize_t r = read(f->_fd, &c, 1); - if (r < 0) { f->_err = 1; break; } - if (r == 0) { f->_eof = 1; break; } - buf[i++] = c; + int c = fgetc(f); + if (c == EOF) break; + buf[i++] = (char)c; if (c == '\n') break; } @@ -116,6 +129,29 @@ char *fgets(char *buf, int n, FILE *f) return buf; } +int fgetc(FILE *f) +{ + if (!f) return EOF; + if (f->_has_ungetc) { + f->_has_ungetc = 0; + return (unsigned char)f->_ungetc_char; + } + unsigned char c; + if (fread(&c, 1, 1, f) != 1) return EOF; + return c; +} + +int getchar(void) { return fgetc(stdin); } + +int ungetc(int c, FILE *f) +{ + if (!f || c == EOF) return EOF; + f->_ungetc_char = (unsigned char)c; + f->_has_ungetc = 1; + f->_eof = 0; + return (unsigned char)c; +} + int fputc(int c, FILE *f) { @@ -135,6 +171,103 @@ int fputs(const char *s, FILE *f) } int feof(FILE *f) { return f ? f->_eof : 1; } int ferror(FILE *f) { return f ? f->_err : 1; } +void clearerr(FILE *f) { if (f) { f->_err = 0; f->_eof = 0; } } + +long ftell(FILE *f) { + if (!f) return -1; + off_t pos = lseek(f->_fd, 0, SEEK_CUR); + if (pos == (off_t)-1) return -1; + if (f->_has_ungetc) pos--; + return (long)pos; +} + +int fgetpos(FILE *f, fpos_t *pos) { + if (!f || !pos) return -1; + long p = ftell(f); + if (p == -1) return -1; + *pos = (fpos_t)p; + return 0; +} + +int fsetpos(FILE *f, const fpos_t *pos) { + if (!f || !pos) return -1; + return fseek(f, (long)*pos, SEEK_SET); +} + +int fseek(FILE *f, long offset, int whence) { + if (!f) return -1; + f->_has_ungetc = 0; + off_t r = lseek(f->_fd, (off_t)offset, whence); + if (r == (off_t)-1) return -1; + f->_eof = 0; + return 0; +} + +void rewind(FILE *f) { + fseek(f, 0, SEEK_SET); + f->_err = 0; +} + +int fflush(FILE *f) { + (void)f; + return 0; +} + +int setvbuf(FILE *f, char *buf, int mode, size_t size) { + (void)f; (void)buf; (void)mode; (void)size; + return 0; // successfully doing nothing +} + +void setbuf(FILE *f, char *buf) { + setvbuf(f, buf, buf ? _IOFBF : _IONBF, BUFSIZ); +} + +int fileno(FILE *f) { + return f ? f->_fd : -1; +} + +FILE *fdopen(int fd, const char *mode) { + FILE *f = (FILE *)malloc(sizeof(FILE)); + if (!f) return NULL; + f->_fd = fd; + f->_flags = (mode[0] == 'r') ? _FILE_READ : _FILE_WRITE; + f->_eof = 0; + f->_err = 0; + f->_has_ungetc = 0; + return f; +} + +FILE *freopen(const char *path, const char *mode, FILE *f) { + if (!f) return NULL; + close(f->_fd); + + int flags = 0; + int fflags = 0; + char m = mode[0]; + int plus = (mode[1] == '+') || (mode[2] == '+'); + + if (m == 'r') { + flags = plus ? O_RDWR : O_RDONLY; + fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_READ; + } else if (m == 'w') { + flags = plus ? (O_RDWR | O_CREAT) : (O_WRONLY | O_CREAT); + fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_WRITE; + } else if (m == 'a') { + flags = O_WRONLY | O_CREAT; + fflags = _FILE_WRITE; + } + + int fd = open(path, flags); + if (fd < 0) return NULL; + + f->_fd = fd; + f->_flags = fflags; + f->_eof = 0; + f->_err = 0; + f->_has_ungetc = 0; + + return f; +} int vfprintf(FILE *f, const char *fmt, va_list ap) @@ -301,4 +434,141 @@ void perror(const char *s) { const char *msg = strerror(errno); write(STDERR_FILENO, msg, strlen(msg)); write(STDERR_FILENO, "\n", 1); +} + +int rename(const char *oldpath, const char *newpath) { + (void)oldpath; (void)newpath; + errno = ENOSYS; + return -1; +} + +int remove(const char *path) { + int r = unlink(path); + if (r < 0 && errno == EISDIR) { + r = rmdir(path); + } + return r; +} + +char *tmpnam(char *s) { + static char buf[L_tmpnam]; + static int counter = 0; + if (!s) s = buf; + snprintf(s, L_tmpnam, "/tmp/tmp%d", counter++); + return s; +} + +FILE *tmpfile(void) { + char name[L_tmpnam]; + tmpnam(name); + return fopen(name, "w+"); +} + +static int _isspace(int c) { + return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'); +} + +int vsscanf(const char *str, const char *fmt, va_list ap) { + int count = 0; + const char *p = str; + for (const char *f = fmt; *f; f++) { + if (_isspace(*f)) { + while (*p && _isspace(*p)) p++; + continue; + } + if (*f != '%') { + if (*p == *f) p++; + else break; + continue; + } + f++; + if (*f == '%') { + if (*p == '%') p++; + else break; + continue; + } + while (*p && _isspace(*p)) p++; + if (!*p) break; + switch (*f) { + case 'c': { + char *c = va_arg(ap, char *); + *c = *p++; + count++; + break; + } + case 's': { + char *s = va_arg(ap, char *); + while (*p && !_isspace(*p)) *s++ = *p++; + *s = '\0'; + count++; + break; + } + case 'd': { + int *d = va_arg(ap, int *); + long val = 0; int sign = 1; + if (*p == '-') { sign = -1; p++; } + if (!(*p >= '0' && *p <= '9')) goto done; + while (*p >= '0' && *p <= '9') val = val * 10 + (*p++ - '0'); + *d = (int)(val * sign); + count++; + break; + } + case 'u': { + unsigned int *u = va_arg(ap, unsigned int *); + unsigned long val = 0; + while (*p >= '0' && *p <= '9') val = val * 10 + (*p++ - '0'); + *u = (unsigned int)val; + count++; + break; + } + case 'x': { + unsigned int *x = va_arg(ap, unsigned int *); + unsigned long val = 0; + if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) p += 2; + while (1) { + if (*p >= '0' && *p <= '9') val = val * 16 + (*p++ - '0'); + else if (*p >= 'a' && *p <= 'f') val = val * 16 + (*p++ - 'a' + 10); + else if (*p >= 'A' && *p <= 'F') val = val * 16 + (*p++ - 'A' + 10); + else break; + } + *x = (unsigned int)val; + count++; + break; + } + default: goto done; + } + } +done: + return count; +} + +int sscanf(const char *str, const char *fmt, ...) { + va_list ap; va_start(ap, fmt); + int r = vsscanf(str, fmt, ap); + va_end(ap); + return r; +} + +int vfscanf(FILE *f, const char *fmt, va_list ap) { + char buf[1024]; + if (!fgets(buf, sizeof(buf), f)) return 0; + return vsscanf(buf, fmt, ap); +} + +int fscanf(FILE *f, const char *fmt, ...) { + va_list ap; va_start(ap, fmt); + int r = vfscanf(f, fmt, ap); + va_end(ap); + return r; +} + +int vscanf(const char *fmt, va_list ap) { + return vfscanf(stdin, fmt, ap); +} + +int scanf(const char *fmt, ...) { + va_list ap; va_start(ap, fmt); + int r = vscanf(fmt, ap); + va_end(ap); + return r; } \ No newline at end of file diff --git a/src/userspace/libc/src/stdlib.c b/src/userspace/libc/src/stdlib.c index 3afff677..fc67d568 100644 --- a/src/userspace/libc/src/stdlib.c +++ b/src/userspace/libc/src/stdlib.c @@ -6,6 +6,15 @@ // bump allocator via brk static char *_heap = NULL; +static void (*_atexit_funcs[32])(void); +static int _atexit_count = 0; + +int atexit(void (*func)(void)) { + if (_atexit_count >= 32) return -1; + _atexit_funcs[_atexit_count++] = func; + return 0; +} + void *malloc(size_t n) { if (!n) return NULL; @@ -37,9 +46,17 @@ void free(void *ptr) { (void)ptr; } // no-op with bump allocator // _exit in unistd.c extern void _exit(int status) __attribute__((noreturn)); -void exit(int status) { _exit(status); __builtin_unreachable(); } +void exit(int status) { + for (int i = _atexit_count - 1; i >= 0; i--) { + if (_atexit_funcs[i]) _atexit_funcs[i](); + } + _exit(status); + __builtin_unreachable(); +} -void abort(void) { _exit(1); } +void abort(void) { + exit(EXIT_FAILURE); +} long strtol(const char *s, char **end, int base) { while (*s == ' ') s++; @@ -66,5 +83,80 @@ long strtol(const char *s, char **end, int base) { int atoi(const char *s) { return (int)strtol(s, NULL, 10); } long atol(const char *s) { return strtol(s, NULL, 10); } -int abs (int x) { return x < 0 ? -x : x; } -long labs(long x) { return x < 0 ? -x : x; } +long long atoll(const char *s) { return (long long)strtol(s, NULL, 10); } +double atof(const char *s) { (void)s; return 0.0; } // No float support yet + +unsigned long strtoul(const char *s, char **end, int base) { return (unsigned long)strtol(s, end, base); } +long long strtoll(const char *s, char **end, int base) { return (long long)strtol(s, end, base); } +unsigned long long strtoull(const char *s, char **end, int base) { return (unsigned long long)strtol(s, end, base); } + +int abs(int x) { return x < 0 ? -x : x; } +long labs(long x) { return x < 0 ? -x : x; } +long long llabs(long long x) { return x < 0 ? -x : x; } + +div_t div(int numer, int denom) { return (div_t){ numer / denom, numer % denom }; } +ldiv_t ldiv(long numer, long denom) { return (ldiv_t){ numer / denom, numer % denom }; } +lldiv_t lldiv(long long numer, long long denom) { return (lldiv_t){ numer / denom, numer % denom }; } + + +static unsigned long _next = 1; +int rand(void) { + _next = _next * 1103515245 + 12345; + return (int)((_next / 65536) % 32768); +} +void srand(unsigned int seed) { + _next = seed; +} + +void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { + if (nmemb < 2) return; + for (size_t gap = nmemb / 2; gap > 0; gap /= 2) { + for (size_t i = gap; i < nmemb; i++) { + for (size_t j = i; j >= gap; j -= gap) { + char *a = (char *)base + (j - gap) * size; + char *b = (char *)base + j * size; + if (compar(a, b) <= 0) break; + for (size_t k = 0; k < size; k++) { char t = a[k]; a[k] = b[k]; b[k] = t; } + } + } + } +} + +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { + size_t l = 0, r = nmemb; + while (l < r) { + size_t m = l + (r - l) / 2; + const void *p = (const char *)base + m * size; + int res = compar(key, p); + if (res == 0) return (void *)p; + if (res < 0) r = m; + else l = m + 1; + } + return NULL; +} + +char **environ = NULL; + +char *getenv(const char *name) { + if (!environ || !name) return NULL; + size_t len = strlen(name); + for (char **p = environ; *p; p++) { + if (strncmp(*p, name, len) == 0 && (*p)[len] == '=') return *p + len + 1; + } + return NULL; +} + +int setenv(const char *name, const char *value, int overwrite) { + (void)name; (void)value; (void)overwrite; + errno = ENOSYS; return -1; +} + +int unsetenv(const char *name) { + (void)name; + errno = ENOSYS; return -1; +} + +int system(const char *command) { + (void)command; + errno = ENOSYS; return -1; +} diff --git a/src/userspace/libc/src/unistd.c b/src/userspace/libc/src/unistd.c index 378f6718..3a3e1a1b 100644 --- a/src/userspace/libc/src/unistd.c +++ b/src/userspace/libc/src/unistd.c @@ -11,6 +11,10 @@ ssize_t write(int fd, const void *buf, size_t n) { return (ssize_t)_sc3(_SCAL_WRITE, fd, (long)buf, (long)n); } +off_t lseek(int fd, off_t offset, int whence) { + return (off_t)_sc3(_SCAL_LSEEK, fd, (long)offset, (long)whence); +} + pid_t getpid(void) { return (pid_t)_sc1(_SCAL_GETPID, 0); } pid_t fork(void) { return (pid_t)_sc0(_SCAL_FORK); } diff --git a/src/userspace/libs/eXui/exui.o b/src/userspace/libs/eXui/exui.o new file mode 100644 index 0000000000000000000000000000000000000000..f30a2abf0bdcf1058862a6826913d2ffc87cea86 GIT binary patch literal 9352 zcmcgyeQX@X72i9DB!r~rK!5ufVVIXz`;DsGXe=|98WB^T zFjIwEnJmkA$+XTOnmL$>g}5)r@`R<5Wh3;+fa;Zu-Mh>&#Y&|4dX^}Mo)M*y>7dM* zT7)TW>D5K91Dg$6qQo6%;;2^PMOuV~%q}=E8#wUl%cQt1=$=pXs~eJ$Io=2MbPH`F zvB{pcPLz}DQpu8$_!0x9~&+Jq&k;bkvxQ?zZ|q81#C3EG-!#O9F>2_-&UzqQlb<9+8}27 z-$-FCur`S4{*eQEm!92NkvS_|BD1{?tA;SW%GE5B6EZ$-%1B0rpNA^Ln`C&Xy8qDL zFCa9`R5D|P_O3$L5<}WGQWV_-XgMK8`Q+Qs-?T&~bl6Bu@7X72^_ET^2EmGqL+wCT zikVb$#t7|uoIvH`bz&xzPGcB49GmwlCRuyrPw&WVYB~T1o?(gSXKO4mY+B1mfbA^#M(CONj1|cR-ZR_&XpX!I zKfR`$l!9!CXb{EzgYcPS=|X7#O)#CA5*g5o0a4bw+?xpvo&}2A!TM|h%XtYy`9`sLmpbm%LzE8IzT|>Q<;UZy$-ijvJPJT3mHY!?GtZdyd<^|f0xCV zf(2?ACx3@OKo-YuGp#{d%Nn3$F_;NG@+3$eFx_0yV|jp>JVetvNYl;7jxGoqvpWWo zZ(Xvx6@T}{?(*>6cnV_o-0Z>9W@G%y`!#Z) z1#6Hz3yBFO5pxD<6+1Q*_tE^T;P&i~OnifbW*hjJ)oC;0D436h4zED^L1*9hl~6h(9trEj-0s)y-K5QbTcV)$I+&4v z4&7do<3Iecg461okxQQILDnF@iQ?>{F;Rrs5t2nD(DXst1m#d=nRIWB?YwlNW)ouD zQm4RDM?%OEGTcc1Qn$qx*v8pDpK@=6ZZDE@r=*zjsA5H?){Ta48k+hqm`c%@w*?Hqv2T0myS5iB%_a{m>a#MX&Iauv>H1Dvu# zWxZk`yH4bji-yVnvuCJt?Z|AD$()Q&$;hM(XK$5a95Rn6LnLdhaMp@UTJb3q3S|ol z?_MM(ST&U_8nI<`-eVrY&Y;d35utn5K41_ba!tcf z-yG&Bs&upe?bw?AsrbVLq`jvK=!W z&5wWyz8Z&(DJR2C<0!ExK6{_WP@jE1y+{E^bP))Mk}hdxTb5>-fvlPsKaPE@!EI%9 za z1l_Ik>N*KKuMxE#>bOIl=F-^C2V^U1B(gZfp{@n8RB2XF>Y{Tsj1yuRC|EcSBl(pm zt#wvp8WYrQ95FrTx{YVvS2sWB);QGvlyhaQ?LXj-b?>DR_d?vu`7X#g@;Jm*Z|C!- zdz}QXLVZXjCt)eNp{J5r^ypfUN**zGFQ!u~%Cie`#PLogYZX>2MTsz+>yoy_$>Yk- zrNHi$z*G4EtTKl}l-^ZQRohdL8$`DMOq&g7a7+})Vkf1NP*xHqZ3zX`xAZNL@DUtG zr9*uWsya7G5{ON?w20*<$qDeH#|f0C$O$m_jN=3(+&Se0xTc_-Frz++8s5`RDBx;N z1va$*0UQL!DW%Z<3ov%y(5X6`GG4@&PaZxmjv0?&8&F$jN2Y56*#H6^_eznMwN-y? zGi7pE#)o9&kPJT!M+_UW^Hs!H>I3*J>RXMA2Qzz?4AV(G*?=3q{e6N`%bmRXxGOXb zQ$3}-gZf&1iHw>5>${bT-J>D)?;aqIk^bmDD2B%xmr|F%t`cxP+~#O+hi@vg9G8jE zBb_QRhK$5z_^fKco#R4F9BL4`{kg4_!~0 zEpf3n{JE**AtMn|=J(z5q?kx0Cye+a`cA6QH>>9|S*U)M$2NF>a==9u=h^-V;bP5( zPOWpR3U*M^&o|fG-NDT6dZ%~!t#((hr@o-|0`hhIzS305LexDk zldb-5?dFXeZ>U>+^KFqU>aMz`{_6U*_R8edaoK2!T}aO1Lt!J(sIQMC0o8NY_1HEH_Iimd2&e+s={)9-iB z4@MpNk8ApU9(s#Ie_qo+@20m_*UxGC9khAYuVzbtI935FYx<4!W_qGJpML70HijP* z9D2=Y4bNY%>0c)%o*%qj2_X4*Yx*(zg@fre6G5KeujvI3{T~kfaZSJ4Ex)U(-}9P& z7rh<%-*EPq)AVcH^LwlF%bLE+vwqxJe-+_qcheu1AH2ia-+E2|nuosGUVyN98ZEiN zc(*bS$*6In)Jv^V(d@+*V;FGZG^X|$JcRR@VxJo2K*Ck5qR;qw=;MqS$MB}6ViE6) z@DSdhZKPrl*p(W8LgOm-fRT-f{}qj^m;<(6#RZ)#k{7_coGuUmu; znu;yF$p^$A)3}N$V5Aq}VhK8EDwgo>#Y6a2Dq9(biXmX%(s-N3RqO!!uEt*^1EQ&z z!FxX*lJmaCRjdH}fyTR*ql2bm1n(c?A^ul2u3`h&Pw|`$oSVui82l1XErYK2uTO(N zcN%;IILT+Z?B@xMzk)Y4#;4GqZ{5G22B%+i=i`6(H26ormm{LNwR0z$h=_2l2EUEjyzzqh(WH>w{aOZL!ww9i35o*xZqbb{Z|seI4DJVPm{+XHTEe^40F% zcx*#Y!f5Hkl$Q1m&^N?mv7T{i#(mM955#(U)jVYr+YppG$U5pOhf0634I_5E_~$fE=koJIO*`sJMC!&%M+KAh#8@Zro~LxRzWZxtTK zYh5_S0OMOU?$@W=#s66s|D!&B)<^y80{B=C%g>yK|5|-yX}(*Zr(C#O|6jRqH~-Ji zga9=Ee&<}coB!&N&ChzW{tZ5y{kucse)%yM?w0>;osU^Q+u>m!&g<^?;k@ood^pR= zo(4be!&&|bAI|cNF8mUh9g3T$fEB&UKvg9_z{XfjfQt ze6QH%!}(rOr*X0kJ=_{~hjFgI+k80J-vJ+fOpl-R;p~@;4`;tj`*5~DUolu8_E#Ml z0F80BbE6OEd)GD}&h{Db;cTBLeK^}W|R2#l~el*}ruJxb)|^YV_e8S4REL zhq_{|_u?Jvv)}F9>x*`_*2kiWm{G5~_qE1ajrx0c?lkJ#db+xzxN6jQ_r#+0JG$fb zy?s5s(Z1M2nm5|svc0dhD{5==zyGa+2r|V&pQuJXUZKx1leO7+sP5@><{KTv?j)#q zq7CSTK-XiM%jcZW?;4HkG>(zo?$qnHGoasfzA@eZ=Ucx-$rtTsK)y9_*!&m3C<&o^Zaud&~LUMzrO;UJ}GnQ5CZj4d+nQ#7doz2n8jQZ`L|6f-i!>9lN literal 0 HcmV?d00001 diff --git a/src/userspace/libs/eXui/libexui.a b/src/userspace/libs/eXui/libexui.a new file mode 100644 index 0000000000000000000000000000000000000000..56ba0bc9a07817a45bc0ae168140bd67b5375894 GIT binary patch literal 9538 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 literal 0 HcmV?d00001 diff --git a/src/userspace/libs/libfont/libfont.o b/src/userspace/libs/libfont/libfont.o new file mode 100644 index 0000000000000000000000000000000000000000..d4a7ccbc7c81c61a0d7b127557d8cf1ccaf376aa GIT binary patch literal 100040 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 literal 0 HcmV?d00001 diff --git a/src/userspace/libs/libvad/libvad.a b/src/userspace/libs/libvad/libvad.a index 3d86519a60f4ed9e78a37589d0c2bd6bc0e1ec80..7e08ad8da568c7ac50c393c8ed4ea82c24e97990 100644 GIT binary patch delta 41 qcmexn^37y|G@GT7frW|TM8zk Date: Tue, 19 May 2026 19:59:34 +0300 Subject: [PATCH 2/3] Libc time.h --- .build | 2 +- dsk/rd/emr/system/sysinfo.elf | Bin 141112 -> 141112 bytes shared/ebuild.h | 2 +- src/kernel/user/syscalls.c | 8 ++++++++ src/kernel/user/system/calls.h | 1 + src/userspace/apps/test_libc/test_libc.c | 10 ++++++++++ .../apps/test_libc/test_libc.emx/app.elf | Bin 25936 -> 26552 bytes src/userspace/apps/test_libc/test_libc.o | Bin 6040 -> 6496 bytes src/userspace/libc/Makefile | 2 +- src/userspace/libc/include/time.h | 17 +++++++++++++++++ src/userspace/libc/src/_syscall.h | 1 + src/userspace/libc/src/time.c | 18 ++++++++++++++++++ src/userspace/libs/eXui/libexui.a | Bin 9538 -> 9538 bytes src/userspace/libs/libdesktop/libdesktop.a | Bin 6808 -> 6808 bytes src/userspace/libs/libfont/libfont.a | Bin 100242 -> 100242 bytes 15 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 src/userspace/libc/include/time.h create mode 100644 src/userspace/libc/src/time.c diff --git a/.build b/.build index db88a862..2d9441aa 100644 --- a/.build +++ b/.build @@ -1 +1 @@ -2250 +2261 diff --git a/dsk/rd/emr/system/sysinfo.elf b/dsk/rd/emr/system/sysinfo.elf index 0a97e6137bda0717635cf1081af16b3d863ccd14..c3b7e8422435a350e31777b66d9084cf3c672a4c 100755 GIT binary patch delta 21 dcmdmSj$_9;jt#L5OlF47@eSMK8yIgc0|08s35x&# delta 21 dcmdmSj$_9;jt#L5Or{3S@eSMK8yIgc0|08X35fsz diff --git a/shared/ebuild.h b/shared/ebuild.h index e7dc3aed..35b78e1b 100644 --- a/shared/ebuild.h +++ b/shared/ebuild.h @@ -1,4 +1,4 @@ #pragma once // this file will always be regenerated when building emexOS // if you want to disable it goto /tools/genbuild.sh -#define ___EMEX_BUILD "26MY.01.2250" +#define ___EMEX_BUILD "26MY.01.2261" diff --git a/src/kernel/user/syscalls.c b/src/kernel/user/syscalls.c index ee9626ce..b40bad3f 100644 --- a/src/kernel/user/syscalls.c +++ b/src/kernel/user/syscalls.c @@ -7,6 +7,8 @@ #include // #include #include +#include +#include #include #include #include @@ -201,6 +203,11 @@ u64 scall_write(ulime_proc_t *proc, u64 fd, u64 buf, u64 count) { return (u64)ret; } +u64 scall_gettime(ulime_proc_t *proc, u64 flags, u64 a2, u64 a3) { + (void)proc; (void)flags; (void)a2; (void)a3; + return (u64)timer_get_milliseconds(); +} + u64 scall_exit(ulime_proc_t *proc, u64 exit_code, u64 arg2, u64 arg3) { (void)arg2; (void)arg3; @@ -1018,6 +1025,7 @@ void _init_syscalls_table(ulime_t *ulime_ptr) { ulime_ptr->syscalls[WAITPID] = scall_waitpid; ulime_ptr->syscalls[GETUID] = scall_getuid; ulime_ptr->syscalls[GETGID] = scall_getgid; + ulime_ptr->syscalls[GETTIME] = scall_gettime; // emex specific ulime_ptr->syscalls[EMXREBOOT] = scall_reboot; diff --git a/src/kernel/user/system/calls.h b/src/kernel/user/system/calls.h index fcd348d3..81d57366 100644 --- a/src/kernel/user/system/calls.h +++ b/src/kernel/user/system/calls.h @@ -13,6 +13,7 @@ #define WRITEV 20 #define READ 0 #define READV 19 +#define GETTIME 13 // #define __GETPID 391 #define GETPID 39 // # call_getpid; diff --git a/src/userspace/apps/test_libc/test_libc.c b/src/userspace/apps/test_libc/test_libc.c index 7ca285ce..482f813a 100644 --- a/src/userspace/apps/test_libc/test_libc.c +++ b/src/userspace/apps/test_libc/test_libc.c @@ -2,6 +2,7 @@ #include #include #include +#include static void cleanup_test(void) { printf("atexit handler called!\n"); @@ -90,6 +91,15 @@ int main(int argc, char **argv) { div_t d = div(33, 10); printf("div(33, 10): quot=%d rem=%d\n", d.quot, d.rem); + printf("Testing time support:\n"); + time_t t = time(NULL); + printf("Current time (seconds since boot): %ld\n", t); + + struct timeval tv; + if (gettimeofday(&tv, NULL) == 0) { + printf("gettimeofday: %ld sec, %ld usec\n", tv.tv_sec, tv.tv_usec); + } + printf("Test complete.\n"); return 0; diff --git a/src/userspace/apps/test_libc/test_libc.emx/app.elf b/src/userspace/apps/test_libc/test_libc.emx/app.elf index 8e6df65fd1d1023b59ae2f7c8865074ea1044e15..26681a7a738e8a0b2bfe29b25973ebd76165029c 100755 GIT binary patch delta 6004 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 EKOk2ydjJ3c delta 5530 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 diff --git a/src/userspace/apps/test_libc/test_libc.o b/src/userspace/apps/test_libc/test_libc.o index 8f5e80c09906a5815166b86090dfcccc98311ef2..0b4f4807b787e6bcfc44417be57831cbbfc4e376 100644 GIT binary patch delta 890 zcmZ`$O=uHA7~Q{^-87AsWH+XWtQa9J0n;K8dMGJDShNR^LM_-fYZK6Hnrsf@K}A*? zwhIYg0xF1}JPDSBU?>=af~}B44?XlCl7ojFtG5<0&deqlg%0e@oA7dz9% z5F<;a$s3;QG({EOzxmzkDTVs0Qt=j($Ph|8L>;R7wB3-8#> zr9GrfB4OLuN61OgSA-G-br50+`i@WlA#}+-Sm4eCFk#klfoWlbS-}A&Qj1)8v`v^@ z!nENFcmCQ3WTxz&EnL}DO!O5#6SDDFv5W??G%+z~jnT@>idktPUNMP`I}j3ZZx`ln zE`F*yo->Q7^s20^DgAJM=+q zN_a`rW%$AS>1TL`T~~PwhyD{@Q%B*pkC;{r~ULx%I%r2?AhUaW4L}mTQ%xod zGAr_dINeiCz(QL;Om<*S5(O#S=YVWsZ|jH2+nEbY?f_-9fD*@B9{^eGVAc~LD+SDY z0c0_QS#N+WNgxa8$UBpxS!5(Z0^M6d3c7ni8oH-~4Cn^RPGHgDy#f}w0T#J3`6P?7 z$PS=p29L%gpfHJcjEOxAf%sDS`L3mRpGfJ9seh`N6QYJHs%L4#hv%+ft diff --git a/src/userspace/libc/Makefile b/src/userspace/libc/Makefile index 5294d41a..014a2d25 100644 --- a/src/userspace/libc/Makefile +++ b/src/userspace/libc/Makefile @@ -7,7 +7,7 @@ CFLAGS := -ffreestanding -nostdlib -fno-builtin -fno-stack-protector \ -fno-PIE -fno-pic -m64 -march=x86-64 -mno-red-zone -Wall -Wextra \ -std=gnu11 -I$(INC) -Isrc -SRCS := src/errno.c src/string.c src/stdlib.c src/unistd.c src/fcntl.c src/stdio.c src/dirent.c src/ioctl.c src/system.c src/wait.c src/sinfo.c src/math.c +SRCS := src/errno.c src/string.c src/stdlib.c src/unistd.c src/fcntl.c src/stdio.c src/dirent.c src/ioctl.c src/system.c src/wait.c src/sinfo.c src/math.c src/time.c OBJS := $(patsubst src/%.c, $(BLD)/%.o, $(SRCS)) all: $(BLD)/libc.a $(BLD)/crt0.o diff --git a/src/userspace/libc/include/time.h b/src/userspace/libc/include/time.h new file mode 100644 index 00000000..279d49db --- /dev/null +++ b/src/userspace/libc/include/time.h @@ -0,0 +1,17 @@ +#pragma once +#include + +typedef long time_t; + +struct timeval { + time_t tv_sec; + long tv_usec; +}; + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; + +time_t time(time_t *t); +int gettimeofday(struct timeval *tv, struct timezone *tz); diff --git a/src/userspace/libc/src/_syscall.h b/src/userspace/libc/src/_syscall.h index 57ddb3c5..b5982ad5 100644 --- a/src/userspace/libc/src/_syscall.h +++ b/src/userspace/libc/src/_syscall.h @@ -5,6 +5,7 @@ #define _SCAL_OPEN 2 #define _SCAL_CLOSE 3 #define _SCAL_LSEEK 8 +#define _SCAL_GETTIME 13 #define _SCAL_BRK 12 #define _SCAL_GETPID 39 diff --git a/src/userspace/libc/src/time.c b/src/userspace/libc/src/time.c new file mode 100644 index 00000000..af2a018e --- /dev/null +++ b/src/userspace/libc/src/time.c @@ -0,0 +1,18 @@ +#include +#include "_syscall.h" + +time_t time(time_t *t) { + long ms = _sc1(_SCAL_GETTIME, 0); + time_t s = ms / 1000; + if (t) *t = s; + return s; +} + +int gettimeofday(struct timeval *tv, struct timezone *tz) { + if (!tv) return -1; + long ms = _sc1(_SCAL_GETTIME, 0); + tv->tv_sec = ms / 1000; + tv->tv_usec = (ms % 1000) * 1000; + (void)tz; + return 0; +} diff --git a/src/userspace/libs/eXui/libexui.a b/src/userspace/libs/eXui/libexui.a index 56ba0bc9a07817a45bc0ae168140bd67b5375894..d2ff5f19825d8eab4304e3001e42d3e85a0caddb 100644 GIT binary patch delta 21 acmX@)b;xUiJhP>l;Y6ik5Vdi}Dir`yvU5=JhP>l;Y1}*5VbK+O9}u+1O@K^ delta 21 acmbPXI>U5=JhQQ- Date: Tue, 19 May 2026 21:19:33 +0300 Subject: [PATCH 3/3] More libc --- .build | 2 +- Makefile | 4 + dsk/rd/emr/system/fm.elf | Bin 134304 -> 134984 bytes dsk/rd/emr/system/sysinfo.elf | Bin 141112 -> 141856 bytes dsk/rd/emr/system/template.elf | Bin 121464 -> 122136 bytes dsk/rd/emr/system/terminal.emx/app.elf | Bin 124840 -> 125520 bytes shared/ebuild.h | 2 +- src/kernel/mem/mem.h | 81 +- src/kernel/packages/cpio/cpio.c | 399 ++++--- src/userspace/Makefile | 2 +- src/userspace/apps/desktop/desktop.c | 2 +- .../apps/terminal/terminal.emx/app.elf | Bin 124840 -> 0 bytes src/userspace/apps/terminal/terminal.o | Bin 9432 -> 0 bytes src/userspace/libc/Makefile | 2 +- src/userspace/libc/include/assert.h | 9 + src/userspace/libc/include/ctype.h | 11 + src/userspace/libc/include/inttypes.h | 26 + src/userspace/libc/include/strings.h | 5 + src/userspace/libc/include/sys/stat.h | 29 + src/userspace/libc/include/sys/types.h | 3 + src/userspace/libc/include/unistd.h | 3 +- src/userspace/libc/src/math.c | 73 +- src/userspace/libc/src/sinfo.c | 2 +- src/userspace/libc/src/stat.c | 18 + src/userspace/libc/src/stdio.c | 1055 +++++++++-------- src/userspace/libc/src/string.c | 17 + src/userspace/libc/src/unistd.c | 11 +- src/userspace/libs/eXui/exui.o | Bin 9352 -> 0 bytes src/userspace/libs/eXui/libexui.a | Bin 9538 -> 0 bytes src/userspace/libs/libdesktop/libdesktop.a | Bin 6808 -> 0 bytes src/userspace/libs/libdesktop/libdesktop.o | Bin 6664 -> 0 bytes src/userspace/libs/libfont/libfont.a | Bin 100242 -> 0 bytes src/userspace/libs/libfont/libfont.o | Bin 100040 -> 0 bytes tools/build-doom.sh | 141 +++ 34 files changed, 1162 insertions(+), 735 deletions(-) delete mode 100755 src/userspace/apps/terminal/terminal.emx/app.elf delete mode 100644 src/userspace/apps/terminal/terminal.o create mode 100644 src/userspace/libc/include/assert.h create mode 100644 src/userspace/libc/include/inttypes.h create mode 100644 src/userspace/libc/include/strings.h create mode 100644 src/userspace/libc/include/sys/stat.h create mode 100644 src/userspace/libc/src/stat.c delete mode 100644 src/userspace/libs/eXui/exui.o delete mode 100644 src/userspace/libs/eXui/libexui.a delete mode 100644 src/userspace/libs/libdesktop/libdesktop.a delete mode 100644 src/userspace/libs/libdesktop/libdesktop.o delete mode 100644 src/userspace/libs/libfont/libfont.a delete mode 100644 src/userspace/libs/libfont/libfont.o create mode 100755 tools/build-doom.sh diff --git a/.build b/.build index 2d9441aa..67742076 100644 --- a/.build +++ b/.build @@ -1 +1 @@ -2261 +2329 diff --git a/Makefile b/Makefile index 445f5046..2513309e 100644 --- a/Makefile +++ b/Makefile @@ -90,6 +90,8 @@ $(ISO): limine.conf $(LIMINE_TOOL) buildgen $(BUILD_DIR)/kernel.elf disk userspa @cp -r src/userspace/apps/filemanager/fm.elf $(DISK_DIR)/rd/emr/system/ @cp -r src/userspace/apps/template/template.elf $(DISK_DIR)/rd/emr/system/ @cp -r src/userspace/apps/gears/gears.elf $(DISK_DIR)/rd/bin/gears.elf + @cp -r src/userspace/apps/doom/doom.elf $(DISK_DIR)/rd/bin/doom.elf + @cp -r src/userspace/apps/doom/doom1.wad $(DISK_DIR)/rd/bin/doom1.wad @echo "[MK] copying other binarys..." # delete those using make binclean @@ -211,6 +213,8 @@ binclean: @rm -f $(DISK_DIR)/rd/emr/system/desktop.elf @rm -f $(DISK_DIR)/rd/emr/system/login.elf @rm -f $(DISK_DIR)/rd/emr/system/gears.elf + @rm -f $(DISK_DIR)/rd/bin/doom.elf + @rm -f $(DISK_DIR)/rd/bin/doom1.wad @rm -f $(DISK_DIR)/rd/emr/system/libraries/cursor.elf @rm -f $(DISK_DIR)/rd/emr/system/libraries/libemxfb0.a @rm -f $(DISK_DIR)/rd/emr/system/libraries/libfont8x12.a diff --git a/dsk/rd/emr/system/fm.elf b/dsk/rd/emr/system/fm.elf index 29eb7224a909038e7254fb28134f51eee26bbe47..364bf9db2e2c708a9e2a471770ae0056474dc5fa 100755 GIT binary patch delta 8469 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 ~J1j$oo!g~Dp?CKO zFtMrt!Z%(A5Kx2WJ+r;}*45DaqqfD%F-2 z29=9}Fnqw`z#&y>By0f~?wkLDn_>?@F5v3W%K)YCDMJudba2t1<)$KZwr9N!W^YQH zww7I?v10Gg=34f}-PyjXx+!Sw!=~Gg|Z0BSN#q@~aqJ&^<{K@adhAHFZCvJ-yQzpn#t5BXw z?70zi@y%el*PH~05}kX4V=psa8iogu+O<#p>J>d>HN5{zozITnpQZ5h{@N8f9x>RV ztHtISF>=c4+HYpuVDix8;;UKF0R=ZPQ1B05Bge%*XT`{tUqt7U$!x1wUJ}LDXmuIX z#@gBvCkw$X)@Cb*OA>$0*uSd?N1Gx3`b-Rq##+AryV&9GDm^e4dUJ(`UZ|W4Jy$hs_ZKOaH-kinFDom{o+&84{d!OY`hf zsw-VmdG`iBOiY_|T|WJ@D407aM%JgK5x9*~Io!Vb?_a|}se#`S@60V=?~7Y=XQbpD zmZdJZjM_diX>qFByJHrb&}OK?HBtO!p0nEgY@PX8R#@E)ZZS}io~Cv-v}=|})j3;O zIJ3f23YmdeL5YVyCV5Nv0K>iq??X5~#~#Gtb4ZiN$Jv88{1Bw!_*8okFCe^yaI43` zWMbeCWvC$GFI`Y(!5;=BxnwhtNNHsu)c8WGf)tH_2d^Ofr4IOu8tyH5KWxV;wQ}77 zeqw=)B*|JW;T43A@mDSl>95t&T4*#JpD0i~j@J{O*a825@cx8*2E0YX^SmW<2ZbG^ zklO+Ogm8s$eSRcqH{oL<>fZf@rLpi1BQFL)3^*^seyf%BV;Al5x7jF}bNh_jENuW; z^8qVZ){*qY4&L7)d~!tHq1!A)W)XF_?y&!07Wgel5;^)7i_&dK1HEt>nY4{?c-ClT zIN%t{G{`0hc${Y13-7W}t3ql?<8^Z>nvx`qBej(s)QSkla1*2v2!T z#}f%pBK%2mzk%=}I&PKHXn^k$BLf&guw~xsu)!ib>4An9=?*;SA)6f7igkP|*%?dt zYm;<*3E_o=Z<&a=RgzMPF_9Q^HHIV^37<;%U@Y0&L->U$x}TYZe@*xZnm|hG(ow=EkJIH3lKc;Z z4=d2|u7qFG@oZ@{F}|W1|Ctm%7^^E-NZ}UYgYtD8exTLLUHeTKhs?O$*Ue(A{uGzz z*!#lmgu`Dz!}rXW0dU-bRUJ}dD9L{@Om`CuZn2mM->T?%u?|ZqnjJ66sb3nt(rjY% zw(oGW(C{Iocbekz%GJ@Ah#CVw)a~{e3uli0bmLSe+-Yu}CRBgEcC_es30^H14t0^8aI zZ0)9ipByxXQ)mB7YJa8Z@vV;KCgBrkSw`xx)JAw7rHO39eJPQ?L5b8O@7Cq*FUxX} zwF?QI>>y+y{M#XVa4(V3WWs-@BRHP$2*QVS$l4~ty=Z1VdnQT8tx^rGohRv~lEP1k9KhEM|hzYC~Q833`G$`rV)e^K8EmlbUZT% zFCaXZviWGjClP*!1{P2FRKh#aZpcO)zo?#v^n&T>`~13iZ+V!Pp>%Qi!i6P^q_PF` z7Az@QR5z)!9K<@6FP>LYvd~`YBQN(`T()Tb%;}3uWwSo0VH2FE&u=k delta 7857 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 diff --git a/dsk/rd/emr/system/sysinfo.elf b/dsk/rd/emr/system/sysinfo.elf index c3b7e8422435a350e31777b66d9084cf3c672a4c..752d80df905632e9366bc4abd4924799e0953b06 100755 GIT binary patch delta 9000 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 delta 8189 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 OAj63i=lCsw^!k5%i9_Z9 diff --git a/dsk/rd/emr/system/template.elf b/dsk/rd/emr/system/template.elf index 8d78eae19e289295c10fbbd99d0d6a95d8681eef..39e332506ad43b4126c4043007b3a7cff0cc39d6 100755 GIT binary patch delta 4847 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 delta 5518 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 Qxejv5%8Q<~%Y4ZH08_aqyZ`_I diff --git a/shared/ebuild.h b/shared/ebuild.h index 35b78e1b..4bb7df27 100644 --- a/shared/ebuild.h +++ b/shared/ebuild.h @@ -1,4 +1,4 @@ #pragma once // this file will always be regenerated when building emexOS // if you want to disable it goto /tools/genbuild.sh -#define ___EMEX_BUILD "26MY.01.2261" +#define ___EMEX_BUILD "26MY.01.2329" diff --git a/src/kernel/mem/mem.h b/src/kernel/mem/mem.h index 6b9aaad4..e8e18899 100644 --- a/src/kernel/mem/mem.h +++ b/src/kernel/mem/mem.h @@ -1,8 +1,8 @@ #ifndef MEM_H #define MEM_H -#include #include +#include typedef struct limine_memmap_response limine_memmap_response_t; typedef struct limine_hhdm_response limine_hhdm_response_t; @@ -18,65 +18,66 @@ typedef struct limine_framebuffer limine_framebuffer_t; #define GRAPHICS_SIZE 1024 * 1024 * 32 #define ULIME_START (GRAPHICS_START + GRAPHICS_SIZE) -#define ULIME_META_SIZE (1024 * 1024 * 2) //2mb +#define ULIME_META_SIZE (1024 * 1024 * 2) // 2mb -#define KLIME_SIZE_SLAB (1024 * 1024 * 8) -#define KLIME_SIZE_IO (1024 * 1024 * 4) -#define KLIME_SIZE_DMA (1024 * 1024 * 2) -#define KLIME_SIZE_NOTHEAP (PAGE_SIZE + PAGE_SIZE + KLIME_SIZE_SLAB + KLIME_SIZE_IO + KLIME_SIZE_DMA) +#define KLIME_SIZE_SLAB (1024 * 1024 * 8) +#define KLIME_SIZE_IO (1024 * 1024 * 4) +#define KLIME_SIZE_DMA (1024 * 1024 * 2) +#define KLIME_SIZE_NOTHEAP \ + (PAGE_SIZE + PAGE_SIZE + KLIME_SIZE_SLAB + KLIME_SIZE_IO + KLIME_SIZE_DMA) #define KLIME_SIZE_HEAP HEAP_SIZE - KLIME_SIZE_NOTHEAP #define KLIME_OFFSET_SLAB_META PAGE_SIZE #define KLIME_OFFSET_SLAB_DATA KLIME_OFFSET_SLAB_META + PAGE_SIZE -#define KLIME_OFFSET_IO KLIME_OFFSET_SLAB_DATA + KLIME_SIZE_SLAB -#define KLIME_OFFSET_DMA KLIME_OFFSET_IO + KLIME_SIZE_IO -#define KLIME_OFFSET_HEAP KLIME_OFFSET_DMA + KLIME_SIZE_DMA +#define KLIME_OFFSET_IO KLIME_OFFSET_SLAB_DATA + KLIME_SIZE_SLAB +#define KLIME_OFFSET_DMA KLIME_OFFSET_IO + KLIME_SIZE_IO +#define KLIME_OFFSET_HEAP KLIME_OFFSET_DMA + KLIME_SIZE_DMA -#define GLIME_SIZE_META (PAGE_SIZE * 256) //2mb +#define GLIME_SIZE_META (PAGE_SIZE * 256) // 2mb #define GLIME_HEAP_SIZE (GRAPHICS_SIZE - GLIME_SIZE_META) #define PAGE_SIZE 4096 -#define FRAME_FREE 0x00 // Frame is available -#define FRAME_USED 0x01 // Frame is allocated -#define FRAME_KERNEL 0x02 // Frame contains kernel data/code -#define FRAME_USER 0x04 // Frame belongs to user process -#define FRAME_DMA 0x08 // Frame used for DMA operations -#define FRAME_SHARED 0x10 // Frame shared between processes -#define FRAME_COW 0x20 // Copy-on-write frame -#define FRAME_CACHE 0x40 // Frame used for disk cache -#define FRAME_GUARD 0x80 // Guard page (for stack overflow) +#define FRAME_FREE 0x00 // Frame is available +#define FRAME_USED 0x01 // Frame is allocated +#define FRAME_KERNEL 0x02 // Frame contains kernel data/code +#define FRAME_USER 0x04 // Frame belongs to user process +#define FRAME_DMA 0x08 // Frame used for DMA operations +#define FRAME_SHARED 0x10 // Frame shared between processes +#define FRAME_COW 0x20 // Copy-on-write frame +#define FRAME_CACHE 0x40 // Frame used for disk cache +#define FRAME_GUARD 0x80 // Guard page (for stack overflow) typedef struct glime_request { - limine_framebuffer_response_t *fbr; - u64 virt; - u64 size; + limine_framebuffer_response_t *fbr; + u64 virt; + u64 size; } glime_request_t; typedef struct glime_response { - u64 *start_framebuffer; - u64 width; - u64 height; - u64 pitch; - u16 bpp; - u16 memory_model; - u8 red_mask_size; - u8 red_mask_shift; - u8 green_mask_size; - u8 green_mask_shift; - u8 blue_mask_size; - u8 blue_mask_shift; + u64 *start_framebuffer; + u64 width; + u64 height; + u64 pitch; + u16 bpp; + u16 memory_model; + u8 red_mask_size; + u8 red_mask_shift; + u8 green_mask_size; + u8 green_mask_shift; + u8 blue_mask_size; + u8 blue_mask_shift; } glime_response_t; typedef struct klime_request { - limine_hhdm_response_t *hpr; - u64 phys; - u64 virt; - u64 size; + limine_hhdm_response_t *hpr; + u64 phys; + u64 virt; + u64 size; } klime_request_t; typedef struct klime_response { - u64 *ptr; - u64 size; + u64 *ptr; + u64 size; } klime_response_t; #endif diff --git a/src/kernel/packages/cpio/cpio.c b/src/kernel/packages/cpio/cpio.c index 6635ca0f..18fb2a10 100644 --- a/src/kernel/packages/cpio/cpio.c +++ b/src/kernel/packages/cpio/cpio.c @@ -1,10 +1,10 @@ #include "cpio.h" -#include -#include -#include #include +#include #include +#include +#include #include // path transform for user_id folder replacement @@ -12,223 +12,250 @@ static char _t_from[64] = {0}; static char _t_to[128] = {0}; void cpio_set_user_transform(const char *from, const char *to) { - if (!from || !to) return; - str_copy(_t_from, from); - str_copy(_t_to, to); + if (!from || !to) + return; + str_copy(_t_from, from); + str_copy(_t_to, to); } -static u32 parse_hex8(const char **p) -{ - u32 val = 0; - for (int i = 0; i < 8; i++) { - char c = (*p)[i]; - u32 n; - if (c >= '0' && c <= '9') n = (u32)(c - '0'); - else if (c >= 'a' && c <= 'f') n = (u32)(c - 'a' + 10); - else if (c >= 'A' && c <= 'F') n = (u32)(c - 'A' + 10); - else n = 0; - val = (val << 4) | n; - } - *p += 8; - return val; +static u32 parse_hex8(const char **p) { + u32 val = 0; + for (int i = 0; i < 8; i++) { + char c = (*p)[i]; + u32 n; + if (c >= '0' && c <= '9') + n = (u32)(c - '0'); + else if (c >= 'a' && c <= 'f') + n = (u32)(c - 'a' + 10); + else if (c >= 'A' && c <= 'F') + n = (u32)(c - 'A' + 10); + else + n = 0; + val = (val << 4) | n; + } + *p += 8; + return val; } -static inline u64 align4(u64 n){ return (n + 3) & ~(u64)3; } +static inline u64 align4(u64 n) { return (n + 3) & ~(u64)3; } // pub iterators // -void cpio_iter_init(cpio_iter_t *iter, const u8 *data, u64 size) -{ - if (!iter) return; - iter->base = data; - iter->size = size; - iter->offset = 0; +void cpio_iter_init(cpio_iter_t *iter, const u8 *data, u64 size) { + if (!iter) + return; + iter->base = data; + iter->size = size; + iter->offset = 0; } -int cpio_iter_next(cpio_iter_t *iter, cpio_entry_t *entry) -{ - if (!iter || !entry) return CPIO_ERR_TRUNC; +int cpio_iter_next(cpio_iter_t *iter, cpio_entry_t *entry) { + if (!iter || !entry) + return CPIO_ERR_TRUNC; - u64 off = iter->offset; + u64 off = iter->offset; - if (off+CPIO_HEADER_SIZE > iter->size) return CPIO_ERR_TRUNC; + if (off + CPIO_HEADER_SIZE > iter->size) + return CPIO_ERR_TRUNC; - const char *hdr = (const char *)(iter->base + off); + const char *hdr = (const char *)(iter->base + off); - if (!(hdr[0]=='0' && hdr[1]=='7' && hdr[2]=='0' && - hdr[3]=='7' && hdr[4]=='0' && (hdr[5]=='1' || hdr[5]=='2'))) + if (!(hdr[0] == '0' && hdr[1] == '7' && hdr[2] == '0' && hdr[3] == '7' && + hdr[4] == '0' && (hdr[5] == '1' || hdr[5] == '2'))) return CPIO_ERR_MAGIC; - const char *p = hdr + 6; - entry->ino = parse_hex8(&p); - entry->mode = parse_hex8(&p); - entry->uid = parse_hex8(&p); - entry->gid = parse_hex8(&p); - entry->nlink = parse_hex8(&p); - entry->mtime = parse_hex8(&p); - entry->filesize = parse_hex8(&p); - entry->devmajor = parse_hex8(&p); - entry->devminor = parse_hex8(&p); - entry->rdevmajor = parse_hex8(&p); - entry->rdevminor = parse_hex8(&p); - entry->namesize = parse_hex8(&p); - parse_hex8(&p); // crc field / ignored - - off += CPIO_HEADER_SIZE; - - if (off+ entry->namesize > iter->size) return CPIO_ERR_TRUNC; - entry->name = (const char *)(iter->base + off); - - off = iter->offset + align4(CPIO_HEADER_SIZE + entry->namesize); - - if (str_equals(entry->name, CPIO_TRAILER)){ - iter->offset = off; - - return CPIO_ERR_EOF; - } - - if (off + entry->filesize > iter->size) return CPIO_ERR_TRUNC; - entry->data = iter->base + off; - iter->offset = off + align4(entry->filesize); - - return CPIO_OK; + const char *p = hdr + 6; + entry->ino = parse_hex8(&p); + entry->mode = parse_hex8(&p); + entry->uid = parse_hex8(&p); + entry->gid = parse_hex8(&p); + entry->nlink = parse_hex8(&p); + entry->mtime = parse_hex8(&p); + entry->filesize = parse_hex8(&p); + entry->devmajor = parse_hex8(&p); + entry->devminor = parse_hex8(&p); + entry->rdevmajor = parse_hex8(&p); + entry->rdevminor = parse_hex8(&p); + entry->namesize = parse_hex8(&p); + parse_hex8(&p); // crc field / ignored + + off += CPIO_HEADER_SIZE; + + if (off + entry->namesize > iter->size) + return CPIO_ERR_TRUNC; + entry->name = (const char *)(iter->base + off); + + off = iter->offset + align4(CPIO_HEADER_SIZE + entry->namesize); + + if (str_equals(entry->name, CPIO_TRAILER)) { + iter->offset = off; + + return CPIO_ERR_EOF; + } + + if (off + entry->filesize > iter->size) + return CPIO_ERR_TRUNC; + entry->data = iter->base + off; + iter->offset = off + align4(entry->filesize); + + return CPIO_OK; } #define CPIO_MAX_ENTRIES 512 typedef struct { - cpio_entry_t e; - char path[256]; + cpio_entry_t e; + char path[256]; } cpio_staged_t; static cpio_staged_t _staged[CPIO_MAX_ENTRIES]; -static void make_path(char *out, const char *base, const char *name) -{ - // strip leading "./" or lone "." - if (name[0] == '.' && name[1] == '/') name += 2; - if (name[0] == '.' && name[1] == '\0') { str_copy(out, base); return; } - - // apply user_id transform on first path component - char tname[256]; - if (_t_from[0]) { - int fl = str_len(_t_from); - if (str_starts_with(name, _t_from) && - (name[fl] == '/' || name[fl] == '\0')) { - str_copy(tname, _t_to); - if (name[fl] == '/') str_append(tname, name + fl); - name = tname; - } +static void make_path(char *out, const char *base, const char *name) { + // strip leading "./" or lone "." + if (name[0] == '.' && name[1] == '/') + name += 2; + if (name[0] == '.' && name[1] == '\0') { + str_copy(out, base); + return; + } + + // apply user_id transform on first path component + char tname[256]; + if (_t_from[0]) { + int fl = str_len(_t_from); + if (str_starts_with(name, _t_from) && + (name[fl] == '/' || name[fl] == '\0')) { + str_copy(tname, _t_to); + if (name[fl] == '/') + str_append(tname, name + fl); + name = tname; } - - if (str_equals(base, "/")) { - out[0] = '/'; - str_copy(out + 1, name); - } else { - str_copy(out, base); - int bl = str_len(out); - if (bl > 0 && out[bl-1] != '/') str_append(out, "/"); - str_append(out, name); - } - // remove trailing slash unless root - int l = str_len(out); - if (l >1 && out[l-1] == '/') out[l-1] = '\0'; + } + + if (str_equals(base, "/")) { + out[0] = '/'; + str_copy(out + 1, name); + } else { + str_copy(out, base); + int bl = str_len(out); + if (bl > 0 && out[bl - 1] != '/') + str_append(out, "/"); + str_append(out, name); + } + // remove trailing slash unless root + int l = str_len(out); + if (l > 1 && out[l - 1] == '/') + out[l - 1] = '\0'; } -int cpio_extract_to_vfs(const u8 *data, u64 size, const char *base_path) -{ - if (!data || size == 0 || !base_path) return CPIO_ERR_TRUNC; +int cpio_extract_to_vfs(const u8 *data, u64 size, const char *base_path) { + if (!data || size == 0 || !base_path) + return CPIO_ERR_TRUNC; - cpio_iter_t iter; - cpio_entry_t entry; - cpio_iter_init(&iter, data, size); + cpio_iter_t iter; + cpio_entry_t entry; + cpio_iter_init(&iter, data, size); - int total = 0; - int staged = 0; + int total = 0; + int staged = 0; - // self explaining i think... reading archive.... - print("\n", white()); - log("[CPIO]", "reading archive...\n", d); - - while (staged < CPIO_MAX_ENTRIES) { - int rc = cpio_iter_next(&iter, &entry); - if (rc == CPIO_ERR_EOF) break; - if (rc != CPIO_OK) { log("[CPIO]", "parse error\n", error); return rc; } - - const char *n = entry.name; - //strips "./" or "." - if (n[0]=='.' && n[1]=='\0') continue; - if (n[0]=='.' && n[1]=='/' && n[2]=='\0') continue; - if (!cpio_is_file(&entry) && !cpio_is_dir(&entry) && !cpio_is_symlink(&entry)) continue; - - cpio_staged_t *s = &_staged[staged]; - s->e = entry; - make_path(s->path, base_path, entry.name); - - if (cpio_is_dir(&entry)) { - log("[CPIO]",DIR_PREFIX, d);} - else { - log("[CPIO]",FILE_PREFIX, d);} - print(s->path, white()); - if (cpio_is_file(&entry) && entry.filesize > 0) { - char buf[20]; - str_copy(buf, " ("); - str_append_uint(buf, entry.filesize); // shows how many bytes a file has - str_append(buf, "B)"); - print(buf, white()); - } - print("\n", white()); - staged++; - } - print("\n", white()); + // self explaining i think... reading archive.... + print("\n", white()); + log("[CPIO]", "reading archive...\n", d); - // only now create all directorys - // (just made it so it looks better...) - for (int i = 0; i < staged; i++) { - if (cpio_is_dir(&_staged[i].e)) { - fs_mkdir(_staged[i].path); - total++; - } + while (staged < CPIO_MAX_ENTRIES) { + int rc = cpio_iter_next(&iter, &entry); + if (rc == CPIO_ERR_EOF) + break; + if (rc != CPIO_OK) { + log("[CPIO]", "parse error\n", error); + return rc; } - // this writes the files but it can also overwrite files - for (int i = 0; i < staged; i++) - { - cpio_staged_t *s = &_staged[i]; - if (!cpio_is_file(&s->e) && !cpio_is_symlink(&s->e)) continue; - - int fd = fs_open(s->path, O_CREAT | O_WRONLY); - if (fd < 0) continue; - if (s->e.filesize > 0) - fs_write(fd, (void *)s->e.data, s->e.filesize); - fs_close(fd); - total++; + const char *n = entry.name; + // strips "./" or "." + if (n[0] == '.' && n[1] == '\0') + continue; + if (n[0] == '.' && n[1] == '/' && n[2] == '\0') + continue; + if (!cpio_is_file(&entry) && !cpio_is_dir(&entry) && + !cpio_is_symlink(&entry)) + continue; + + cpio_staged_t *s = &_staged[staged]; + s->e = entry; + make_path(s->path, base_path, entry.name); + + if (cpio_is_dir(&entry)) { + log("[CPIO]", DIR_PREFIX, d); + } else { + log("[CPIO]", FILE_PREFIX, d); } - - char buf[32]; - str_copy(buf, ""); - str_append_uint(buf, (u32)total); - log("[CPIO]", "extracted ", d); - print(buf, white()); - print(" entries\n", white()); - - return total; + print(s->path, white()); + if (cpio_is_file(&entry) && entry.filesize > 0) { + char buf[20]; + str_copy(buf, " ("); + str_append_uint(buf, entry.filesize); // shows how many bytes a file has + str_append(buf, "B)"); + print(buf, white()); + } + print("\n", white()); + staged++; + } + print("\n", white()); + + // only now create all directorys + // (just made it so it looks better...) + for (int i = 0; i < staged; i++) { + if (cpio_is_dir(&_staged[i].e)) { + fs_mkdir(_staged[i].path); + total++; + } + } + + // this writes the files but it can also overwrite files + for (int i = 0; i < staged; i++) { + cpio_staged_t *s = &_staged[i]; + if (!cpio_is_file(&s->e) && !cpio_is_symlink(&s->e)) + continue; + + int fd = fs_open(s->path, O_CREAT | O_WRONLY); + if (fd < 0) + continue; + if (s->e.filesize > 0) + fs_write(fd, (void *)s->e.data, s->e.filesize); + fs_close(fd); + total++; + } + + char buf[32]; + str_copy(buf, ""); + str_append_uint(buf, (u32)total); + log("[CPIO]", "extracted ", d); + print(buf, white()); + print(" entries\n", white()); + + return total; } -int cpio_find(const u8 *data, u64 size, const char *name, cpio_entry_t *entry) -{ - if (!data || !name || !entry) return CPIO_ERR_TRUNC; - - cpio_iter_t iter; - cpio_iter_init(&iter, data, size); - - while (1) { - int rc = cpio_iter_next(&iter, entry); - if (rc == CPIO_ERR_EOF) return CPIO_ERR_EOF; - if (rc != CPIO_OK) return rc; - - const char *n = entry->name; - if (n[0]=='.' && n[1]=='/') n += 2; - if (str_equals(n, name)) return CPIO_OK; - } +int cpio_find(const u8 *data, u64 size, const char *name, cpio_entry_t *entry) { + if (!data || !name || !entry) + return CPIO_ERR_TRUNC; + + cpio_iter_t iter; + cpio_iter_init(&iter, data, size); + + while (1) { + int rc = cpio_iter_next(&iter, entry); + if (rc == CPIO_ERR_EOF) + return CPIO_ERR_EOF; + if (rc != CPIO_OK) + return rc; + + const char *n = entry->name; + if (n[0] == '.' && n[1] == '/') + n += 2; + if (str_equals(n, name)) + return CPIO_OK; + } } diff --git a/src/userspace/Makefile b/src/userspace/Makefile index c24a46d0..94dc6d60 100644 --- a/src/userspace/Makefile +++ b/src/userspace/Makefile @@ -49,7 +49,7 @@ clean: @$(MAKE) -C apps/system clean @$(MAKE) -C apps/system/stinf clean @$(MAKE) -C apps/shell clean - @$(MAKE) -C apps/terminal + @$(MAKE) -C apps/terminal clean @$(MAKE) -C apps/login clean @$(MAKE) -C apps/desktop clean @$(MAKE) -C apps/sysinfo clean diff --git a/src/userspace/apps/desktop/desktop.c b/src/userspace/apps/desktop/desktop.c index f6376e8d..5798cd05 100644 --- a/src/userspace/apps/desktop/desktop.c +++ b/src/userspace/apps/desktop/desktop.c @@ -319,7 +319,7 @@ static void render_band(input_state_t *is) int main(void) { - mkdir(DT_DIR); + mkdir(DT_DIR, 0755); int fd; fd = open(DT_CMD, O_WRONLY | O_CREAT); if (fd >= 0) close(fd); diff --git a/src/userspace/apps/terminal/terminal.emx/app.elf b/src/userspace/apps/terminal/terminal.emx/app.elf deleted file mode 100755 index d009b1307e356c8ad1c80d1b742224cc074c2f27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124840 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 E09=Dby#N3J diff --git a/src/userspace/apps/terminal/terminal.o b/src/userspace/apps/terminal/terminal.o deleted file mode 100644 index e025d3e72b81302bf55429d5aa1137798d9b1f27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9432 zcmbtY4RBP|6~3DvNF%s_*rB4ZC_>O0K!;KgoghAaPC=dOPDicACHo-TB)egMAhELv zcC#%z+d!t(4vzh?KU&95YyXCU6d?vpuv!cZMYL%rqp@t7w8ojJQKRX1?mKt)=8@-g zrg!JPd+&G8Irp4%&pr3PZ8bLEQsnUnRXpNGQRpdDi2X|n?JC)<60^lD;WsmHo2ikC zOmZZX$YuP4nJoi1XN>-=(VrUdq`TtFvc^cN%abuivqnxf#Dp!;-#|-B%n1PbX z5z#uc*BBx5vlkNuCh>GH}s8=(po0Mad?5?gJq-vn9ft0Sa&NY8JIoVNI ziHgj4CUJI;(Z4&{U!Ew>9m4R?C2&3Zv%PJz>{eM~lTyXI_v5@`sk}P&GD(x5RLv=~ z?v!PE`fNWywIMS4{6+7fMgNo+y=4ZLKG;G_PfoEXTxX25mgcU2R(3x%UensbQE~os z?Hyng-UCMeo+6znyXCA>E0|YnPZ^6;aiVi5@+npfmvjt!9I<9*lJMZz@FGO{xY>TE z$IST0y$6K%NLSWBmN|oH>45e$3bd^&@mdGFACbDMu;|!1dS_HR>#+}#qwr3T@i$@G z${w9Nckbk5pWVUU8XC#FD(jzE(Vg+}8sHo3HO9#wLyr>;wA&97dvOY0fKnTZ zclkbJ*n6OBxRf@FfPj)TH8RG)REC0^Aa9TH#%8r~$DzttcFTa-?tdej7~FV>*f$;| zD>A(sCr_n}aZf6VMZMxP1h#c~(;FryCusxOmaj7=TIZ`dMm&A!d%yc0MTr)P)UDRWDNk^$z=PR$gBK7KHcTe^e7OMhFoij6u0Z8S%fmH=! zj1I@llric-ca;3;i;r@%tt%c!qCi+=;QIY$`}`Nl0T>-HJ>5iPW{QSOb#Aa+kQbDA zyU_GXay!CCv7dMZ^z$fd=RDF0P4E+f)J|Sgrt32)rBEbH*!v#==#w_ViX)V5ktF0g z+Zz=bF*zZcXG&<;3pUPt2Z@$NJUmi`ZD_kO-Q{ijW0C4n`t3H`)BRYLDJjToZ$JA9 zc7#3D>5~)7wEBIJBBp6tZ(9Q-nb|avPGQF^>3zhLO%ITmbXQ{j5zul14Nf3|ts&mt z^l`K?z=;PwLM$XIF|nLK)m3I@+og>5M~T$T^q84frSV6}MA;%9@7}l2hm$)=n$(6} zk-Ltjdl92%uQ5sqiB(ql7SWNz*+=n^qs)`)Dm8DQlYM7}GLCd7@@GDVr3FJCM|Y^6 zBojMy#!OQjp=N?RNqM63oJ56)%-d0znwCP+dHOm@ t#3|hPepTec*X*X-CcAtC% z?M{&9z3DzokCt-tU@AE%5?7h+kJ3P4wdL%E^Ydt{Vj=pL2HZx@bFYf4CUbZRZJGT& zZKcOCvw$&F=Zy%XV-sUO8tI%Q&t*>VIw4`Dk^`c(GxseF4lmIBd>sKZJM7$^-xyVL zL&%J*Z3%K*KG>VfF z&-#(a`{f};mh~EAR1L4q8e>RSbQO{o)7^p**Na8U7{ldej8aTX*O6jWQj^^2ab707 z`yzFr4UZl`H}?)+YVo!l@0^9v!pfz_XL-|~2M12|J{$yXbI{Hj$FZ-lrS=%-QpsF- z99M_j?8J>S9*&knKyKj&kbDncY|JC+{)0({px*)x{^e#2HWoBxy9bS%k5UHx9zgLs2e^7wRhjFJV0lIJhaUH z-UI$~d*l^{-J$039x={I+Yrt-(L{$~-OzEQ%Z{OL`96&IOUHzOSXt;G^V83d?qmK* ztI4Vn^jhz048&`FQENvc6t#loV!baMXs~?oNW@nk32!eKE4PNiD@CPMzYSwGk%opq zIOq#U;=XN>L>LU)BGEeEwm_(!xK{?Pohw7(#zcH&oz=WG5{L#@*#w8b5%K0m%XfKw%ty0b4$)CxU?*e-w$@u}(pY7Axwx;frpjutnj*3Lm->Xb zbB(z9qDXkU2%}J=;&Jrn+pzFF^i|<$n&VkG zYi3yoh%W_B50$6rwei9^-!9rTdq&Yudq5)R*g!Z+HNDihkt#0o_Z%Y{;(w6FP_8Bg z6ix9m4+-%B+Kq?GMtvMIir0Fi5R&l=Ng?nhNQA6Mvs6RQ@dA(kT9;A$w48(Z2YLK7 z)r!C9RVjeRONb9;6TQ@UOF{lp9zTPGl^-uYSws}Xe>0CiH)Z^w94C>}6=Eq7?@mrP zR-9k0siVb$(#iRySg!h1oRSCDJ`c(@-3^Y*4ekwo1L-J#c%NPXq3?8*cXy(fSw5G$KbHQJ5!C!X4&$!@!cfsFu z!Oywi|8~LYK%UO74_$Ct|LN#wxZoGM;1|2#^w+>VOmf@jpa6>8`=}SY&@Xqv^9Mp@ zjR;z?x_G2!tsq!DeVw=E`6c$!EmWW!_J43M$&Jqy@cXc$fOMsvn$5f4K!~~ANXkeFU3`ApAbs)Mu zCbmIBwbc}g#W9))SJyNIacCw&)wNb=du<#?UpQV}D;lhZn#N|TVpiNH*cA%KYwht} z5)qL`C{t4(iCH2RkJdCa%7as$!8%i5ze8PC%Ua6%JGsqwmWtXC#$9SHe z{j-#DvQ@XM#vwKO!=X(xZ=~>3-qEpZLj1!ymDaXSl4qVAu>6F9kvet#Z$_2m0fh+wtJ8(7c z1B^TMe~xj|UH9joHC)e2r!-v8V}p#7ALwpIu|?%w4W~KOzL<2u*ANj(UQhPV-7fey zG@P#-l0U8C+?4qDxTEx(FHs@RxX=%4^wd;-e&2yByUO{V4dcq*`=k^hzUIJd84qZ3 ze43o?jH`K-{00|1?U0{j`TJbtKkAUfsr-{TJ?cS`PEn%48#MXa%(ImDx(p*L;q;v zGgDOJFHNg*dpJ?q7{#|*G~Nsv;sp8HIbx?Dk&CQci zu9tC&$%>YGM}Pnaygf3Q~gCeMC0VYllgDveM_`d zeDYm*twxjd(qocF75{70(TY0X6|@cw;$Nizu9wfY8y7inqNSqho6x2s)j59^^E>4_ z{XzeiO{ae&^FOF20v#16Km89k-TGDeh+2qIyOQ@6;#K@={id6nSo$us8GR%ih0+4u oqn-S8+&I?`kQkjuZy{DY^mlZ{T+mF%ziNqO7eTwqzn%R51qSG}C;$Ke diff --git a/src/userspace/libc/Makefile b/src/userspace/libc/Makefile index 014a2d25..9ead854f 100644 --- a/src/userspace/libc/Makefile +++ b/src/userspace/libc/Makefile @@ -7,7 +7,7 @@ CFLAGS := -ffreestanding -nostdlib -fno-builtin -fno-stack-protector \ -fno-PIE -fno-pic -m64 -march=x86-64 -mno-red-zone -Wall -Wextra \ -std=gnu11 -I$(INC) -Isrc -SRCS := src/errno.c src/string.c src/stdlib.c src/unistd.c src/fcntl.c src/stdio.c src/dirent.c src/ioctl.c src/system.c src/wait.c src/sinfo.c src/math.c src/time.c +SRCS := src/errno.c src/string.c src/stdlib.c src/unistd.c src/fcntl.c src/stdio.c src/dirent.c src/ioctl.c src/system.c src/wait.c src/sinfo.c src/math.c src/time.c src/stat.c OBJS := $(patsubst src/%.c, $(BLD)/%.o, $(SRCS)) all: $(BLD)/libc.a $(BLD)/crt0.o diff --git a/src/userspace/libc/include/assert.h b/src/userspace/libc/include/assert.h new file mode 100644 index 00000000..b770304b --- /dev/null +++ b/src/userspace/libc/include/assert.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include + +#ifdef NDEBUG +#define assert(ignore) ((void)0) +#else +#define assert(expr) ((expr) ? (void)0 : (printf("Assertion failed: %s, file %s, line %d\n", #expr, __FILE__, __LINE__), abort())) +#endif diff --git a/src/userspace/libc/include/ctype.h b/src/userspace/libc/include/ctype.h index 6f70f09b..9abed1c2 100644 --- a/src/userspace/libc/include/ctype.h +++ b/src/userspace/libc/include/ctype.h @@ -1 +1,12 @@ #pragma once + +static inline int isdigit(int c) { return (unsigned)c - '0' < 10; } +static inline int isspace(int c) { return c == ' ' || (unsigned)c - '\t' < 5; } +static inline int isupper(int c) { return (unsigned)c - 'A' < 26; } +static inline int islower(int c) { return (unsigned)c - 'a' < 26; } +static inline int isalpha(int c) { return ((unsigned)c | 32) - 'a' < 26; } +static inline int isalnum(int c) { return isalpha(c) || isdigit(c); } +static inline int isprint(int c) { return (unsigned)c - 0x20 < 95; } +static inline int isxdigit(int c) { return isdigit(c) || ((unsigned)c | 32) - 'a' < 6; } +static inline int tolower(int c) { return isupper(c) ? c + 32 : c; } +static inline int toupper(int c) { return islower(c) ? c - 32 : c; } diff --git a/src/userspace/libc/include/inttypes.h b/src/userspace/libc/include/inttypes.h new file mode 100644 index 00000000..59952e45 --- /dev/null +++ b/src/userspace/libc/include/inttypes.h @@ -0,0 +1,26 @@ +#pragma once +#include + +#define PRId8 "d" +#define PRIi8 "i" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" + +#define PRId16 "d" +#define PRIi16 "i" +#define PRIu16 "u" +#define PRIx16 "x" +#define PRIX16 "X" + +#define PRId32 "d" +#define PRIi32 "i" +#define PRIu32 "u" +#define PRIx32 "x" +#define PRIX32 "X" + +#define PRId64 "ld" +#define PRIi64 "li" +#define PRIu64 "lu" +#define PRIx64 "lx" +#define PRIX64 "LX" diff --git a/src/userspace/libc/include/strings.h b/src/userspace/libc/include/strings.h new file mode 100644 index 00000000..d0abc474 --- /dev/null +++ b/src/userspace/libc/include/strings.h @@ -0,0 +1,5 @@ +#pragma once +#include + +int strcasecmp(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t n); diff --git a/src/userspace/libc/include/sys/stat.h b/src/userspace/libc/include/sys/stat.h new file mode 100644 index 00000000..3021a323 --- /dev/null +++ b/src/userspace/libc/include/sys/stat.h @@ -0,0 +1,29 @@ +#pragma once +#include + +struct stat { + dev_t st_dev; /* ID of device containing file */ + ino_t st_ino; /* Inode number */ + mode_t st_mode; /* File type and mode */ + nlink_t st_nlink; /* Number of hard links */ + uid_t st_uid; /* User ID of owner */ + gid_t st_gid; /* Group ID of owner */ + dev_t st_rdev; /* Device ID (if special file) */ + off_t st_size; /* Total size, in bytes */ + long st_blksize; /* Block size for filesystem I/O */ + long st_blocks; /* Number of 512B blocks allocated */ + long st_atime; /* Time of last access */ + long st_mtime; /* Time of last modification */ + long st_ctime; /* Time of last status change */ +}; + +#define S_IFMT 0170000 +#define S_IFDIR 0040000 +#define S_IFREG 0100000 + +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) + +int stat(const char *path, struct stat *buf); +int fstat(int fd, struct stat *buf); +int mkdir(const char *path, mode_t mode); diff --git a/src/userspace/libc/include/sys/types.h b/src/userspace/libc/include/sys/types.h index 34a484dc..5411b158 100644 --- a/src/userspace/libc/include/sys/types.h +++ b/src/userspace/libc/include/sys/types.h @@ -7,3 +7,6 @@ typedef unsigned long ino_t; // inode num typedef unsigned int mode_t; typedef unsigned int uid_t; typedef unsigned int gid_t; +typedef unsigned int useconds_t; +typedef unsigned int dev_t; +typedef unsigned int nlink_t; diff --git a/src/userspace/libc/include/unistd.h b/src/userspace/libc/include/unistd.h index 6e73c803..71e667e6 100644 --- a/src/userspace/libc/include/unistd.h +++ b/src/userspace/libc/include/unistd.h @@ -13,7 +13,8 @@ off_t lseek(int fd, off_t offset, int whence); // filesystem int chdir(const char *path); -int mkdir(const char *path); +int usleep(useconds_t usec); +int mkdir(const char *path, mode_t mode); int rmdir(const char *path); char *getcwd(char *buf, size_t size); int unlink(const char *path); diff --git a/src/userspace/libc/src/math.c b/src/userspace/libc/src/math.c index 830a0b9e..5660491f 100644 --- a/src/userspace/libc/src/math.c +++ b/src/userspace/libc/src/math.c @@ -2,56 +2,53 @@ // @offihito - -double fabs(double x) { - return x < 0 ? -x : x; -} +double fabs(double x) { return x < 0 ? -x : x; } double sqrt(double x) { - if (x < 0) return 0; - double res; - __asm__ ("sqrtsd %1, %0" : "=x"(res) : "x"(x)); - return res; + if (x < 0) + return 0; + double res; + __asm__("sqrtsd %1, %0" : "=x"(res) : "x"(x)); + return res; } double sin(double x) { - double res; - __asm__ ("fsin" : "=t"(res) : "0"(x)); - return res; + double res; + __asm__("fsin" : "=t"(res) : "0"(x)); + return res; } double cos(double x) { - double res; - __asm__ ("fcos" : "=t"(res) : "0"(x)); - return res; + double res; + __asm__("fcos" : "=t"(res) : "0"(x)); + return res; } double pow(double x, double y) { - double res; - // x^y = 2^(y * log2(x)) - // This is a simplified x87 implementation - __asm__ ( - "fyl2x;" // st(1) = y * log2(x), pop st(0) - "fld %%st(0);" // duplicate y*log2(x) - "frndint;" // round to integer - "fsubr %%st(1), %%st(0);" // get fractional part - "f2xm1;" // 2^(fractional) - 1 - "fld1;" - "faddp;" // 2^(fractional) - "fscale;" // st(0) * 2^st(1) - "fstp %%st(1);" // pop integer part - : "=t"(res) - : "0"(x), "u"(y) - ); - return res; + double res; + // x^y = 2^(y * log2(x)) + // This is a simplified x87 implementation + __asm__("fyl2x;" // st(1) = y * log2(x), pop st(0) + "fld %%st(0);" // duplicate y*log2(x) + "frndint;" // round to integer + "fsubr %%st(1), %%st(0);" // get fractional part + "f2xm1;" // 2^(fractional) - 1 + "fld1;" + "faddp;" // 2^(fractional) + "fscale;" // st(0) * 2^st(1) + "fstp %%st(1);" // pop integer part + : "=t"(res) + : "0"(x), "u"(y)); + return res; } double floor(double x) { - if (x >= 0) { - return (double)(long)x; - } else { - long i = (long)x; - if (x == (double)i) return x; - return (double)(i - 1); - } + if (x >= 0) { + return (double)(long)x; + } else { + long i = (long)x; + if (x == (double)i) + return x; + return (double)(i - 1); + } } \ No newline at end of file diff --git a/src/userspace/libc/src/sinfo.c b/src/userspace/libc/src/sinfo.c index f8e3875b..7cd92f56 100644 --- a/src/userspace/libc/src/sinfo.c +++ b/src/userspace/libc/src/sinfo.c @@ -3,5 +3,5 @@ int sysinfo(struct sysinfo_t *info) { - (int) _sc1(_SCAL_SYSINFO, (long) info); + return (int) _sc1(_SCAL_SYSINFO, (long) info); } \ No newline at end of file diff --git a/src/userspace/libc/src/stat.c b/src/userspace/libc/src/stat.c new file mode 100644 index 00000000..9a1bf796 --- /dev/null +++ b/src/userspace/libc/src/stat.c @@ -0,0 +1,18 @@ +#include +#include +#include + +int stat(const char *path, struct stat *buf) { + if (!buf) { errno = EINVAL; return -1; } + memset(buf, 0, sizeof(struct stat)); + // Stub implementation: everything is a regular file of size 0 + buf->st_mode = S_IFREG | 0644; + return 0; +} + +int fstat(int fd, struct stat *buf) { + if (!buf) { errno = EINVAL; return -1; } + memset(buf, 0, sizeof(struct stat)); + buf->st_mode = S_IFREG | 0644; + return 0; +} diff --git a/src/userspace/libc/src/stdio.c b/src/userspace/libc/src/stdio.c index 336bc666..1547a01b 100644 --- a/src/userspace/libc/src/stdio.c +++ b/src/userspace/libc/src/stdio.c @@ -1,574 +1,703 @@ -#include +#include #include -#include +#include #include #include -#include -//#include - -static FILE _stdin = { ._fd = STDIN_FILENO, ._flags = _FILE_READ, ._eof = 0, ._err = 0, ._has_ungetc = 0 }; -static FILE _stdout = { ._fd = STDOUT_FILENO, ._flags = _FILE_WRITE, ._eof = 0, ._err = 0, ._has_ungetc = 0 }; -static FILE _stderr = { ._fd = STDERR_FILENO, ._flags = _FILE_WRITE, ._eof = 0, ._err = 0, ._has_ungetc = 0 }; - -FILE *stdin = &_stdin; +#include +// #include + +static FILE _stdin = {._fd = STDIN_FILENO, + ._flags = _FILE_READ, + ._eof = 0, + ._err = 0, + ._has_ungetc = 0}; +static FILE _stdout = {._fd = STDOUT_FILENO, + ._flags = _FILE_WRITE, + ._eof = 0, + ._err = 0, + ._has_ungetc = 0}; +static FILE _stderr = {._fd = STDERR_FILENO, + ._flags = _FILE_WRITE, + ._eof = 0, + ._err = 0, + ._has_ungetc = 0}; + +FILE *stdin = &_stdin; FILE *stdout = &_stdout; FILE *stderr = &_stderr; -FILE *fopen(const char *path, const char *mode) -{ - if (!path || !mode) { errno = EINVAL; return NULL; } - - int flags = 0; - int fflags = 0; - - // parse mode string - char m = mode[0]; - int plus = (mode[1] == '+') || (mode[2] == '+'); - - if (m == 'r') { - flags = plus ? O_RDWR : O_RDONLY; - fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_READ; - } else if (m == 'w') { - flags = plus ? (O_RDWR | O_CREAT) : (O_WRONLY | O_CREAT); - fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_WRITE; - } else if (m == 'a') { - flags = O_WRONLY | O_CREAT; - fflags = _FILE_WRITE; - } else { - errno = EINVAL; - return NULL; - } - - int fd = open(path, flags); - if (fd < 0) return NULL; // errno already set by open() +FILE *fopen(const char *path, const char *mode) { + if (!path || !mode) { + errno = EINVAL; + return NULL; + } + + int flags = 0; + int fflags = 0; + + // parse mode string + char m = mode[0]; + int plus = (mode[1] == '+') || (mode[2] == '+'); + + if (m == 'r') { + flags = plus ? O_RDWR : O_RDONLY; + fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_READ; + } else if (m == 'w') { + flags = plus ? (O_RDWR | O_CREAT) : (O_WRONLY | O_CREAT); + fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_WRITE; + } else if (m == 'a') { + flags = O_WRONLY | O_CREAT; + fflags = _FILE_WRITE; + } else { + errno = EINVAL; + return NULL; + } + + int fd = open(path, flags); + if (fd < 0) + return NULL; // errno already set by open() + + FILE *f = (FILE *)malloc(sizeof(FILE)); + if (!f) { + close(fd); + errno = ENOMEM; + return NULL; + } + + f->_fd = fd; + f->_flags = fflags; + f->_eof = 0; + f->_err = 0; + f->_has_ungetc = 0; + + return f; +} + +int fclose(FILE *f) { + if (!f) { + errno = EINVAL; + return EOF; + } + + // do not close the static standard streams + int is_std = (f == stdin || f == stdout || f == stderr); + + int r = 0; + if (!is_std) { + r = close(f->_fd); + free(f); + } + return r; +} + +size_t fread(void *buf, size_t sz, size_t n, FILE *f) { + if (!f || !buf || !sz || !n) + return 0; + if (f->_eof || f->_err) + return 0; + if (!(f->_flags & _FILE_READ)) { + f->_err = 1; + return 0; + } - FILE *f = (FILE *)malloc(sizeof(FILE)); - if (!f) { close(fd); errno = ENOMEM; return NULL; } + size_t total = sz * n; + size_t done = 0; + unsigned char *p = (unsigned char *)buf; - f->_fd = fd; - f->_flags = fflags; - f->_eof = 0; - f->_err = 0; + if (f->_has_ungetc && total > 0) { + *p++ = (unsigned char)f->_ungetc_char; f->_has_ungetc = 0; + done++; + } - return f; -} - -int fclose(FILE *f) -{ - if (!f) { errno = EINVAL; return EOF; } - - // do not close the static standard streams - int is_std = (f == stdin || f == stdout || f == stderr); - - int r = 0; - if (!is_std) { - r = close(f->_fd); - free(f); - } - return r; -} - -size_t fread(void *buf, size_t sz, size_t n, FILE *f) -{ - if (!f || !buf || !sz || !n) return 0; - if (f->_eof || f->_err) return 0; - if (!(f->_flags & _FILE_READ)) { f->_err = 1; return 0; } - - size_t total = sz * n; - size_t done = 0; - unsigned char *p = (unsigned char *)buf; - - if (f->_has_ungetc && total > 0) { - *p++ = (unsigned char)f->_ungetc_char; - f->_has_ungetc = 0; - done++; - } - - if (done < total) { - ssize_t got = read(f->_fd, p, total - done); - if (got < 0) { - f->_err = 1; - } else { - done += (size_t)got; - if ((size_t)got < (total - (size_t)(p - (unsigned char *)buf))) f->_eof = 1; - } + if (done < total) { + ssize_t got = read(f->_fd, p, total - done); + if (got < 0) { + f->_err = 1; + } else { + done += (size_t)got; + if ((size_t)got < (total - (size_t)(p - (unsigned char *)buf))) + f->_eof = 1; } + } - return done / sz; + return done / sz; } -size_t fwrite(const void *buf, size_t sz, size_t n, FILE *f) -{ - if (!f || !buf || !sz || !n) return 0; - if (!(f->_flags & _FILE_WRITE)) { f->_err = 1; return 0; } - - size_t total = sz * n; - ssize_t written = write(f->_fd, buf, total); - - if (written < 0) { f->_err = 1; return 0; } - return (size_t)written / sz; -} - -char *fgets(char *buf, int n, FILE *f) -{ - if (!f || !buf || n <= 0) return NULL; - if (f->_eof || f->_err) return NULL; - if (!(f->_flags & _FILE_READ)) { f->_err = 1; return NULL; } - - int i = 0; - while (i < n - 1) { - int c = fgetc(f); - if (c == EOF) break; - buf[i++] = (char)c; - if (c == '\n') break; - } +size_t fwrite(const void *buf, size_t sz, size_t n, FILE *f) { + if (!f || !buf || !sz || !n) + return 0; + if (!(f->_flags & _FILE_WRITE)) { + f->_err = 1; + return 0; + } - if (i == 0) return NULL; - buf[i] = '\0'; - return buf; -} + size_t total = sz * n; + ssize_t written = write(f->_fd, buf, total); -int fgetc(FILE *f) -{ - if (!f) return EOF; - if (f->_has_ungetc) { - f->_has_ungetc = 0; - return (unsigned char)f->_ungetc_char; - } - unsigned char c; - if (fread(&c, 1, 1, f) != 1) return EOF; - return c; + if (written < 0) { + f->_err = 1; + return 0; + } + return (size_t)written / sz; +} + +char *fgets(char *buf, int n, FILE *f) { + if (!f || !buf || n <= 0) + return NULL; + if (f->_eof || f->_err) + return NULL; + if (!(f->_flags & _FILE_READ)) { + f->_err = 1; + return NULL; + } + + int i = 0; + while (i < n - 1) { + int c = fgetc(f); + if (c == EOF) + break; + buf[i++] = (char)c; + if (c == '\n') + break; + } + + if (i == 0) + return NULL; + buf[i] = '\0'; + return buf; +} + +int fgetc(FILE *f) { + if (!f) + return EOF; + if (f->_has_ungetc) { + f->_has_ungetc = 0; + return (unsigned char)f->_ungetc_char; + } + unsigned char c; + if (fread(&c, 1, 1, f) != 1) + return EOF; + return c; } int getchar(void) { return fgetc(stdin); } -int ungetc(int c, FILE *f) -{ - if (!f || c == EOF) return EOF; - f->_ungetc_char = (unsigned char)c; - f->_has_ungetc = 1; - f->_eof = 0; - return (unsigned char)c; -} - - -int fputc(int c, FILE *f) -{ - if (!f || !(f->_flags & _FILE_WRITE)) return EOF; - unsigned char ch = (unsigned char)c; - ssize_t r = write(f->_fd, &ch, 1); - if (r != 1) { f->_err = 1; return EOF; } - return (unsigned char)c; -} -int fputs(const char *s, FILE *f) -{ - if (!f || !s || !(f->_flags & _FILE_WRITE)) return EOF; - size_t len = strlen(s); - ssize_t r = write(f->_fd, s, len); - if (r < 0) { f->_err = 1; return EOF; } - return 0; +int ungetc(int c, FILE *f) { + if (!f || c == EOF) + return EOF; + f->_ungetc_char = (unsigned char)c; + f->_has_ungetc = 1; + f->_eof = 0; + return (unsigned char)c; +} + +int fputc(int c, FILE *f) { + if (!f || !(f->_flags & _FILE_WRITE)) + return EOF; + unsigned char ch = (unsigned char)c; + ssize_t r = write(f->_fd, &ch, 1); + if (r != 1) { + f->_err = 1; + return EOF; + } + return (unsigned char)c; +} +int fputs(const char *s, FILE *f) { + if (!f || !s || !(f->_flags & _FILE_WRITE)) + return EOF; + size_t len = strlen(s); + ssize_t r = write(f->_fd, s, len); + if (r < 0) { + f->_err = 1; + return EOF; + } + return 0; } int feof(FILE *f) { return f ? f->_eof : 1; } int ferror(FILE *f) { return f ? f->_err : 1; } -void clearerr(FILE *f) { if (f) { f->_err = 0; f->_eof = 0; } } +void clearerr(FILE *f) { + if (f) { + f->_err = 0; + f->_eof = 0; + } +} long ftell(FILE *f) { - if (!f) return -1; - off_t pos = lseek(f->_fd, 0, SEEK_CUR); - if (pos == (off_t)-1) return -1; - if (f->_has_ungetc) pos--; - return (long)pos; + if (!f) + return -1; + off_t pos = lseek(f->_fd, 0, SEEK_CUR); + if (pos == (off_t)-1) + return -1; + if (f->_has_ungetc) + pos--; + return (long)pos; } int fgetpos(FILE *f, fpos_t *pos) { - if (!f || !pos) return -1; - long p = ftell(f); - if (p == -1) return -1; - *pos = (fpos_t)p; - return 0; + if (!f || !pos) + return -1; + long p = ftell(f); + if (p == -1) + return -1; + *pos = (fpos_t)p; + return 0; } int fsetpos(FILE *f, const fpos_t *pos) { - if (!f || !pos) return -1; - return fseek(f, (long)*pos, SEEK_SET); + if (!f || !pos) + return -1; + return fseek(f, (long)*pos, SEEK_SET); } int fseek(FILE *f, long offset, int whence) { - if (!f) return -1; - f->_has_ungetc = 0; - off_t r = lseek(f->_fd, (off_t)offset, whence); - if (r == (off_t)-1) return -1; - f->_eof = 0; - return 0; + if (!f) + return -1; + f->_has_ungetc = 0; + off_t r = lseek(f->_fd, (off_t)offset, whence); + if (r == (off_t)-1) + return -1; + f->_eof = 0; + return 0; } void rewind(FILE *f) { - fseek(f, 0, SEEK_SET); - f->_err = 0; + fseek(f, 0, SEEK_SET); + f->_err = 0; } int fflush(FILE *f) { - (void)f; - return 0; + (void)f; + return 0; } int setvbuf(FILE *f, char *buf, int mode, size_t size) { - (void)f; (void)buf; (void)mode; (void)size; - return 0; // successfully doing nothing + (void)f; + (void)buf; + (void)mode; + (void)size; + return 0; // successfully doing nothing } void setbuf(FILE *f, char *buf) { - setvbuf(f, buf, buf ? _IOFBF : _IONBF, BUFSIZ); + setvbuf(f, buf, buf ? _IOFBF : _IONBF, BUFSIZ); } -int fileno(FILE *f) { - return f ? f->_fd : -1; -} +int fileno(FILE *f) { return f ? f->_fd : -1; } FILE *fdopen(int fd, const char *mode) { - FILE *f = (FILE *)malloc(sizeof(FILE)); - if (!f) return NULL; - f->_fd = fd; - f->_flags = (mode[0] == 'r') ? _FILE_READ : _FILE_WRITE; - f->_eof = 0; - f->_err = 0; - f->_has_ungetc = 0; - return f; + FILE *f = (FILE *)malloc(sizeof(FILE)); + if (!f) + return NULL; + f->_fd = fd; + f->_flags = (mode[0] == 'r') ? _FILE_READ : _FILE_WRITE; + f->_eof = 0; + f->_err = 0; + f->_has_ungetc = 0; + return f; } FILE *freopen(const char *path, const char *mode, FILE *f) { - if (!f) return NULL; - close(f->_fd); - - int flags = 0; - int fflags = 0; - char m = mode[0]; - int plus = (mode[1] == '+') || (mode[2] == '+'); - - if (m == 'r') { - flags = plus ? O_RDWR : O_RDONLY; - fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_READ; - } else if (m == 'w') { - flags = plus ? (O_RDWR | O_CREAT) : (O_WRONLY | O_CREAT); - fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_WRITE; - } else if (m == 'a') { - flags = O_WRONLY | O_CREAT; - fflags = _FILE_WRITE; + if (!f) + return NULL; + close(f->_fd); + + int flags = 0; + int fflags = 0; + char m = mode[0]; + int plus = (mode[1] == '+') || (mode[2] == '+'); + + if (m == 'r') { + flags = plus ? O_RDWR : O_RDONLY; + fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_READ; + } else if (m == 'w') { + flags = plus ? (O_RDWR | O_CREAT) : (O_WRONLY | O_CREAT); + fflags = plus ? (_FILE_READ | _FILE_WRITE) : _FILE_WRITE; + } else if (m == 'a') { + flags = O_WRONLY | O_CREAT; + fflags = _FILE_WRITE; + } + + int fd = open(path, flags); + if (fd < 0) + return NULL; + + f->_fd = fd; + f->_flags = fflags; + f->_eof = 0; + f->_err = 0; + f->_has_ungetc = 0; + + return f; +} + +int vfprintf(FILE *f, const char *fmt, va_list ap) { + char buf[512]; + int len = vsnprintf(buf, sizeof(buf), fmt, ap); + if (len >= (int)sizeof(buf)) + len = (int)sizeof(buf) - 1; + ssize_t r = write(f->_fd, buf, (size_t)len); + if (r < 0) { + f->_err = 1; + return -1; + } + return len; +} + +int fprintf(FILE *f, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int r = vfprintf(f, fmt, ap); + va_end(ap); + return r; +} + +static int _uitoa(unsigned long v, int base, char *out) { + static const char _hex[] = "0123456789abcdef"; + char tmp[32]; + int len = 0; + if (v == 0) { + out[0] = '0'; + return 1; + } + while (v) { + tmp[len++] = _hex[v % (unsigned)base]; + v /= (unsigned)base; + } + for (int i = 0; i < len; i++) + out[i] = tmp[len - 1 - i]; + return len; +} + +int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap) { + size_t pos = 0; + char tmp[32]; + int tlen; + +#define _EMIT(c) \ + do { \ + if (buf && pos + 1 < size) \ + buf[pos] = (c); \ + pos++; \ + } while (0) + + for (const char *p = fmt; *p; p++) { + if (*p != '%') { + _EMIT(*p); + continue; + } + p++; + if (!*p) + break; + + // width and zero-pad + char pad = ' '; + int width = 0; + int is_long = 0; + + if (*p == '0') { + pad = '0'; + p++; + } + while (*p >= '1' && *p <= '9') { + width = width * 10 + (*p - '0'); + p++; + } + if (*p == 'l') { + is_long = 1; + p++; } - int fd = open(path, flags); - if (fd < 0) return NULL; - - f->_fd = fd; - f->_flags = fflags; - f->_eof = 0; - f->_err = 0; - f->_has_ungetc = 0; - - return f; -} - - -int vfprintf(FILE *f, const char *fmt, va_list ap) -{ - char buf[512]; - int len = vsnprintf(buf, sizeof(buf), fmt, ap); - if (len >= (int)sizeof(buf)) len = (int)sizeof(buf) - 1; - ssize_t r = write(f->_fd, buf, (size_t)len); - if (r < 0) { f->_err = 1; return -1; } - return len; -} - -int fprintf(FILE *f, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - int r = vfprintf(f, fmt, ap); - va_end(ap); - return r; -} - -static int _uitoa(unsigned long v, int base, char *out) -{ - static const char _hex[] = "0123456789abcdef"; - char tmp[32]; - int len = 0; - if (v == 0) { out[0] = '0'; return 1; } - while (v) { tmp[len++] = _hex[v % (unsigned)base]; v /= (unsigned)base; } - for (int i = 0; i < len; i++) out[i] = tmp[len - 1 - i]; - return len; -} - -int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap) -{ - size_t pos = 0; - char tmp[32]; - int tlen; - -#define _EMIT(c) do { if (buf && pos + 1 < size) buf[pos] = (c); pos++; } while (0) - - for (const char *p = fmt; *p; p++) { - if (*p != '%') { _EMIT(*p); continue; } - p++; - if (!*p) break; - - // width and zero-pad - char pad = ' '; - int width = 0; - int is_long = 0; - - if (*p == '0') { pad = '0'; p++; } - while (*p >= '1' && *p <= '9') { width = width * 10 + (*p - '0'); p++; } - if (*p == 'l') { is_long = 1; p++; } - - switch (*p) { - case 's': { - const char *s = va_arg(ap, const char *); - if (!s) s = "(null)"; - while (*s) _EMIT(*s++); - break; - } - case 'd': { - long val = is_long ? va_arg(ap, long) : (long)va_arg(ap, int); - if (val < 0) { _EMIT('-'); val = -val; } - tlen = _uitoa((unsigned long)val, 10, tmp); - for (int i = tlen; i < width; i++) _EMIT(pad); - for (int i = 0; i < tlen; i++) _EMIT(tmp[i]); - tlen = 0; - break; - } - case 'u': { - unsigned long val = is_long ? va_arg(ap, unsigned long) - : (unsigned long)va_arg(ap, unsigned int); - tlen = _uitoa(val, 10, tmp); - for (int i = tlen; i < width; i++) _EMIT(pad); - for (int i = 0; i < tlen; i++) _EMIT(tmp[i]); - tlen = 0; - break; - } - case 'x': { - unsigned long val = is_long ? va_arg(ap, unsigned long) - : (unsigned long)va_arg(ap, unsigned int); - tlen = _uitoa(val, 16, tmp); - for (int i = tlen; i < width; i++) _EMIT(pad); - for (int i = 0; i < tlen; i++) _EMIT(tmp[i]); - tlen = 0; - break; - } - case 'p': { - unsigned long val = (unsigned long)va_arg(ap, void *); - _EMIT('0'); _EMIT('x'); - tlen = _uitoa(val, 16, tmp); - for (int i = 0; i < tlen; i++) _EMIT(tmp[i]); - tlen = 0; - break; - } - case 'c': { - _EMIT((char)va_arg(ap, int)); - break; - } - case '%': { - _EMIT('%'); - break; - } - default: { - _EMIT('%'); - if (is_long) _EMIT('l'); - _EMIT(*p); - break; - } - } + switch (*p) { + case 's': { + const char *s = va_arg(ap, const char *); + if (!s) + s = "(null)"; + while (*s) + _EMIT(*s++); + break; } + case 'i': + case 'd': { + long val = is_long ? va_arg(ap, long) : (long)va_arg(ap, int); + if (val < 0) { + _EMIT('-'); + val = -val; + } + tlen = _uitoa((unsigned long)val, 10, tmp); + for (int i = tlen; i < width; i++) + _EMIT(pad); + for (int i = 0; i < tlen; i++) + _EMIT(tmp[i]); + tlen = 0; + break; + } + case 'u': { + unsigned long val = is_long ? va_arg(ap, unsigned long) + : (unsigned long)va_arg(ap, unsigned int); + tlen = _uitoa(val, 10, tmp); + for (int i = tlen; i < width; i++) + _EMIT(pad); + for (int i = 0; i < tlen; i++) + _EMIT(tmp[i]); + tlen = 0; + break; + } + case 'x': { + unsigned long val = is_long ? va_arg(ap, unsigned long) + : (unsigned long)va_arg(ap, unsigned int); + tlen = _uitoa(val, 16, tmp); + for (int i = tlen; i < width; i++) + _EMIT(pad); + for (int i = 0; i < tlen; i++) + _EMIT(tmp[i]); + tlen = 0; + break; + } + case 'p': { + unsigned long val = (unsigned long)va_arg(ap, void *); + _EMIT('0'); + _EMIT('x'); + tlen = _uitoa(val, 16, tmp); + for (int i = 0; i < tlen; i++) + _EMIT(tmp[i]); + tlen = 0; + break; + } + case 'c': { + _EMIT((char)va_arg(ap, int)); + break; + } + case '%': { + _EMIT('%'); + break; + } + default: { + _EMIT('%'); + if (is_long) + _EMIT('l'); + _EMIT(*p); + break; + } + } + } - if (buf && size > 0) buf[pos < size ? pos : size - 1] = '\0'; - return (int)pos; + if (buf && size > 0) + buf[pos < size ? pos : size - 1] = '\0'; + return (int)pos; #undef _EMIT } - int snprintf(char *buf, size_t size, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - int r = vsnprintf(buf, size, fmt, ap); - va_end(ap); - return r; + va_list ap; + va_start(ap, fmt); + int r = vsnprintf(buf, size, fmt, ap); + va_end(ap); + return r; } int vprintf(const char *fmt, va_list ap) { - char buf[512]; - int len = vsnprintf(buf, sizeof(buf), fmt, ap); - // clamp to actual buffer size to avoid overrun - if (len >= (int)sizeof(buf)) len = (int)sizeof(buf) - 1; - write(STDOUT_FILENO, buf, (size_t)len); - return len; + char buf[512]; + int len = vsnprintf(buf, sizeof(buf), fmt, ap); + // clamp to actual buffer size to avoid overrun + if (len >= (int)sizeof(buf)) + len = (int)sizeof(buf) - 1; + write(STDOUT_FILENO, buf, (size_t)len); + return len; } int printf(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - int r = vprintf(fmt, ap); - va_end(ap); - return r; + va_list ap; + va_start(ap, fmt); + int r = vprintf(fmt, ap); + va_end(ap); + return r; } int putchar(int c) { - char ch = (char)c; - write(STDOUT_FILENO, &ch, 1); - return (unsigned char)ch; + char ch = (char)c; + write(STDOUT_FILENO, &ch, 1); + return (unsigned char)ch; } int puts(const char *s) { - write(STDOUT_FILENO, s, strlen(s)); - write(STDOUT_FILENO, "\n", 1); - return 0; + write(STDOUT_FILENO, s, strlen(s)); + write(STDOUT_FILENO, "\n", 1); + return 0; } void perror(const char *s) { - // "prefix: error message\n" - if (s && s[0] != '\0') { - write(STDERR_FILENO, s, strlen(s)); - write(STDERR_FILENO, ": ", 2); - } - const char *msg = strerror(errno); - write(STDERR_FILENO, msg, strlen(msg)); - write(STDERR_FILENO, "\n", 1); + // "prefix: error message\n" + if (s && s[0] != '\0') { + write(STDERR_FILENO, s, strlen(s)); + write(STDERR_FILENO, ": ", 2); + } + const char *msg = strerror(errno); + write(STDERR_FILENO, msg, strlen(msg)); + write(STDERR_FILENO, "\n", 1); } int rename(const char *oldpath, const char *newpath) { - (void)oldpath; (void)newpath; - errno = ENOSYS; - return -1; + (void)oldpath; + (void)newpath; + errno = ENOSYS; + return -1; } int remove(const char *path) { - int r = unlink(path); - if (r < 0 && errno == EISDIR) { - r = rmdir(path); - } - return r; + int r = unlink(path); + if (r < 0 && errno == EISDIR) { + r = rmdir(path); + } + return r; } char *tmpnam(char *s) { - static char buf[L_tmpnam]; - static int counter = 0; - if (!s) s = buf; - snprintf(s, L_tmpnam, "/tmp/tmp%d", counter++); - return s; + static char buf[L_tmpnam]; + static int counter = 0; + if (!s) + s = buf; + snprintf(s, L_tmpnam, "/tmp/tmp%d", counter++); + return s; } FILE *tmpfile(void) { - char name[L_tmpnam]; - tmpnam(name); - return fopen(name, "w+"); + char name[L_tmpnam]; + tmpnam(name); + return fopen(name, "w+"); } static int _isspace(int c) { - return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'); + return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || + c == '\v'); } int vsscanf(const char *str, const char *fmt, va_list ap) { - int count = 0; - const char *p = str; - for (const char *f = fmt; *f; f++) { - if (_isspace(*f)) { - while (*p && _isspace(*p)) p++; - continue; - } - if (*f != '%') { - if (*p == *f) p++; - else break; - continue; - } - f++; - if (*f == '%') { - if (*p == '%') p++; - else break; - continue; - } - while (*p && _isspace(*p)) p++; - if (!*p) break; - switch (*f) { - case 'c': { - char *c = va_arg(ap, char *); - *c = *p++; - count++; - break; - } - case 's': { - char *s = va_arg(ap, char *); - while (*p && !_isspace(*p)) *s++ = *p++; - *s = '\0'; - count++; - break; - } - case 'd': { - int *d = va_arg(ap, int *); - long val = 0; int sign = 1; - if (*p == '-') { sign = -1; p++; } - if (!(*p >= '0' && *p <= '9')) goto done; - while (*p >= '0' && *p <= '9') val = val * 10 + (*p++ - '0'); - *d = (int)(val * sign); - count++; - break; - } - case 'u': { - unsigned int *u = va_arg(ap, unsigned int *); - unsigned long val = 0; - while (*p >= '0' && *p <= '9') val = val * 10 + (*p++ - '0'); - *u = (unsigned int)val; - count++; - break; - } - case 'x': { - unsigned int *x = va_arg(ap, unsigned int *); - unsigned long val = 0; - if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) p += 2; - while (1) { - if (*p >= '0' && *p <= '9') val = val * 16 + (*p++ - '0'); - else if (*p >= 'a' && *p <= 'f') val = val * 16 + (*p++ - 'a' + 10); - else if (*p >= 'A' && *p <= 'F') val = val * 16 + (*p++ - 'A' + 10); - else break; - } - *x = (unsigned int)val; - count++; - break; - } - default: goto done; - } + int count = 0; + const char *p = str; + for (const char *f = fmt; *f; f++) { + if (_isspace(*f)) { + while (*p && _isspace(*p)) + p++; + continue; } + if (*f != '%') { + if (*p == *f) + p++; + else + break; + continue; + } + f++; + if (*f == '%') { + if (*p == '%') + p++; + else + break; + continue; + } + while (*p && _isspace(*p)) + p++; + if (!*p) + break; + switch (*f) { + case 'c': { + char *c = va_arg(ap, char *); + *c = *p++; + count++; + break; + } + case 's': { + char *s = va_arg(ap, char *); + while (*p && !_isspace(*p)) + *s++ = *p++; + *s = '\0'; + count++; + break; + } + case 'i': + case 'd': { + int *d = va_arg(ap, int *); + long val = 0; + int sign = 1; + if (*p == '-') { + sign = -1; + p++; + } + if (!(*p >= '0' && *p <= '9')) + goto done; + while (*p >= '0' && *p <= '9') + val = val * 10 + (*p++ - '0'); + *d = (int)(val * sign); + count++; + break; + } + case 'u': { + unsigned int *u = va_arg(ap, unsigned int *); + unsigned long val = 0; + while (*p >= '0' && *p <= '9') + val = val * 10 + (*p++ - '0'); + *u = (unsigned int)val; + count++; + break; + } + case 'x': { + unsigned int *x = va_arg(ap, unsigned int *); + unsigned long val = 0; + if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) + p += 2; + while (1) { + if (*p >= '0' && *p <= '9') + val = val * 16 + (*p++ - '0'); + else if (*p >= 'a' && *p <= 'f') + val = val * 16 + (*p++ - 'a' + 10); + else if (*p >= 'A' && *p <= 'F') + val = val * 16 + (*p++ - 'A' + 10); + else + break; + } + *x = (unsigned int)val; + count++; + break; + } + default: + goto done; + } + } done: - return count; + return count; } int sscanf(const char *str, const char *fmt, ...) { - va_list ap; va_start(ap, fmt); - int r = vsscanf(str, fmt, ap); - va_end(ap); - return r; + va_list ap; + va_start(ap, fmt); + int r = vsscanf(str, fmt, ap); + va_end(ap); + return r; } int vfscanf(FILE *f, const char *fmt, va_list ap) { - char buf[1024]; - if (!fgets(buf, sizeof(buf), f)) return 0; - return vsscanf(buf, fmt, ap); + char buf[1024]; + if (!fgets(buf, sizeof(buf), f)) + return 0; + return vsscanf(buf, fmt, ap); } int fscanf(FILE *f, const char *fmt, ...) { - va_list ap; va_start(ap, fmt); - int r = vfscanf(f, fmt, ap); - va_end(ap); - return r; + va_list ap; + va_start(ap, fmt); + int r = vfscanf(f, fmt, ap); + va_end(ap); + return r; } -int vscanf(const char *fmt, va_list ap) { - return vfscanf(stdin, fmt, ap); -} +int vscanf(const char *fmt, va_list ap) { return vfscanf(stdin, fmt, ap); } int scanf(const char *fmt, ...) { - va_list ap; va_start(ap, fmt); - int r = vscanf(fmt, ap); - va_end(ap); - return r; + va_list ap; + va_start(ap, fmt); + int r = vscanf(fmt, ap); + va_end(ap); + return r; } \ No newline at end of file diff --git a/src/userspace/libc/src/string.c b/src/userspace/libc/src/string.c index 4e2f60c6..df895d72 100644 --- a/src/userspace/libc/src/string.c +++ b/src/userspace/libc/src/string.c @@ -1,6 +1,7 @@ #include #include #include +#include void *memcpy(void *dst, const void *src, size_t n) { unsigned char *d = dst; const unsigned char *s = src; @@ -119,3 +120,19 @@ char *strdup(const char *s) { if (p) memcpy(p, s, n); return p; } + +int strcasecmp(const char *s1, const char *s2) { + while (*s1 && tolower((unsigned char)*s1) == tolower((unsigned char)*s2)) { + s1++; s2++; + } + return tolower((unsigned char)*s1) - tolower((unsigned char)*s2); +} + +int strncasecmp(const char *s1, const char *s2, size_t n) { + for (size_t i = 0; i < n; i++) { + if (tolower((unsigned char)s1[i]) != tolower((unsigned char)s2[i])) + return tolower((unsigned char)s1[i]) - tolower((unsigned char)s2[i]); + if (!s1[i]) return 0; + } + return 0; +} diff --git a/src/userspace/libc/src/unistd.c b/src/userspace/libc/src/unistd.c index 3a3e1a1b..00c34246 100644 --- a/src/userspace/libc/src/unistd.c +++ b/src/userspace/libc/src/unistd.c @@ -31,7 +31,7 @@ int execve(const char *path, char *const argv[], char *const envp[]) { int chdir(const char *path) { return (int)_sc1(_SCAL_CHDIR, (long)path); } -int mkdir(const char *path) { return (int)_sc1(_SCAL_MKDIR, (long)path); } +int mkdir(const char *path, mode_t mode) { (void)mode; return (int)_sc1(_SCAL_MKDIR, (long)path); } int rmdir(const char *path) { return (int)_sc1(_SCAL_UNLINK, (long)path); } @@ -41,3 +41,12 @@ char *getcwd(char *buf, size_t size) { long r = _sc2(_SCAL_GETCWD, (long)buf, (long)size); return (r > 0) ? buf : NULL; } + +int usleep(useconds_t usec) { + if (usec == 0) return 0; + long start_ms = _sc1(_SCAL_GETTIME, 0); + long target_ms = start_ms + (usec / 1000); + if (target_ms == start_ms) target_ms++; + while (_sc1(_SCAL_GETTIME, 0) < target_ms); + return 0; +} diff --git a/src/userspace/libs/eXui/exui.o b/src/userspace/libs/eXui/exui.o deleted file mode 100644 index f30a2abf0bdcf1058862a6826913d2ffc87cea86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9352 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 diff --git a/src/userspace/libs/eXui/libexui.a b/src/userspace/libs/eXui/libexui.a deleted file mode 100644 index d2ff5f19825d8eab4304e3001e42d3e85a0caddb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9538 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 PKNq$+I+#)4{p0@&Lj>xM diff --git a/src/userspace/libs/libdesktop/libdesktop.a b/src/userspace/libs/libdesktop/libdesktop.a deleted file mode 100644 index 808fd13fa5d83bfdf2b6d11ed71d5ee40f40d0ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6808 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 diff --git a/src/userspace/libs/libfont/libfont.o b/src/userspace/libs/libfont/libfont.o deleted file mode 100644 index d4a7ccbc7c81c61a0d7b127557d8cf1ccaf376aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100040 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 diff --git a/tools/build-doom.sh b/tools/build-doom.sh new file mode 100755 index 00000000..1f81176c --- /dev/null +++ b/tools/build-doom.sh @@ -0,0 +1,141 @@ +#!/bin/bash +set -e + +# Configuration +REPO_URL="https://github.com/ozkl/doomgeneric.git" +WAD_MIRRORS=( + "https://github.com/Doom-Generic/doomgeneric/raw/master/doom1.wad" + "https://github.com/varkon/linux-doom/raw/master/doom/doom1.wad" +) +APPS_DIR="src/userspace/apps" +DOOM_DIR="$APPS_DIR/doom" + +echo "[DOOM] Initializing Doom port..." + +mkdir -p "$DOOM_DIR" + +# 1. Clone doomgeneric source +if [ ! -f "$DOOM_DIR/doomgeneric.c" ]; then + echo "[DOOM] Cloning doomgeneric..." + TEMP_CLONE=$(mktemp -d) + git clone "$REPO_URL" "$TEMP_CLONE" + cp -r "$TEMP_CLONE/doomgeneric"/* "$DOOM_DIR/" + rm -rf "$TEMP_CLONE" +fi + +# 2. Get the WAD +if [ ! -f "$DOOM_DIR/doom1.wad" ]; then + echo "[DOOM] Downloading doom1.wad..." + DOWNLOADED=false + for url in "${WAD_MIRRORS[@]}"; do + if wget "$url" -O "$DOOM_DIR/doom1.wad"; then + DOWNLOADED=true + break + fi + done + if [ "$DOWNLOADED" = false ]; then + echo "[WARNING] Could not download doom1.wad automatically." + fi +fi + +# 3. Create EmexOS Backend with main loop and stubs +echo "[DOOM] Creating Doom backend for EmexOS..." +cat < "$DOOM_DIR/doom_emex.c" +#include "doomgeneric.h" +#include +#include +#include +#include + +void DG_Init() { + printf("Doom: Initializing EmexOS backend...\n"); +} + +void DG_DrawFrame() { + // Current framebuffer logic: stub +} + +void DG_SleepMs(uint32_t ms) { + usleep(ms * 1000); +} + +uint32_t DG_GetTicksMs() { + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); +} + +int DG_GetKey(int* pressed, unsigned char* key) { + (void)pressed; (void)key; + return 0; +} + +void DG_SetWindowTitle(const char * title) { + printf("Doom: %s\n", title); +} + +// Missing stubs +void I_InitJoystick() {} +void I_BindJoystickVariables() {} +void I_Endoom() {} + +int main(int argc, char **argv) { + doomgeneric_Create(argc, argv); + while (1) { + doomgeneric_Tick(); + } + return 0; +} +EOF + +# 4. Create Makefile +echo "[DOOM] Creating Makefile..." +cat < "$DOOM_DIR/Makefile" +CC := x86_64-elf-gcc +LD := x86_64-elf-ld +LIBC := ../../libc +LIBGCC := \$(shell \$(CC) -print-libgcc-file-name) + +RESX := 320 +RESY := 200 + +CFLAGS := -ffreestanding -nostdlib -fno-builtin -fno-stack-protector \\ + -fno-PIE -fno-pic -m64 -march=x86-64 -mno-red-zone -Wall -Wextra \\ + -msoft-float -std=gnu11 \\ + -I\$(LIBC)/include -DDOOMGENERIC_RESX=\$(RESX) -DDOOMGENERIC_RESY=\$(RESY) + +LDFLAGS := -nostdlib -static -no-pie -T ../../user.ld + +# Exclude other platform backends and unnecessary files +EXCLUDE := doomgeneric_allegro.c doomgeneric_emscripten.c doomgeneric_linuxvt.c \\ + doomgeneric_sdl.c doomgeneric_soso.c doomgeneric_sosox.c \\ + doomgeneric_win.c doomgeneric_xlib.c \\ + i_allegromusic.c i_allegrosound.c i_sdlmusic.c i_sdlsound.c \\ + i_cdmus.c i_endoom.c i_joystick.c + +SRCS := \$(filter-out \$(EXCLUDE), \$(wildcard *.c)) +OBJS := \$(SRCS:.c=.o) + +all: doom.elf + +doom.elf: \$(OBJS) \$(LIBC)/build/crt0.o \$(LIBC)/build/libc.a + \$(LD) \$(LDFLAGS) \$(LIBC)/build/crt0.o \$(OBJS) \$(LIBC)/build/libc.a \$(LIBGCC) -o \$@ + +%.o: %.c + \$(CC) \$(CFLAGS) -c \$< -o \$@ + +clean: + rm -f *.o doom.elf + +.PHONY: all clean +EOF + +# 5. Build +echo "[DOOM] Building..." +make -C "$DOOM_DIR" clean +if make -C "$DOOM_DIR"; then + echo "[DOOM] Porting complete! doom.elf created in $DOOM_DIR" +else + echo "[ERROR] Doom build failed." + exit 1 +fi