[ mmix @ 06.03.2019. 10:43 ] @
Sad je gotovo, sad cu da vas smaram neko vreme :)

Ok, hocu da napisem svoj daemon, cisto eksperimenta radi hocu da napravim chat server u C# .net core 3.0 preview kao proof of concept. Sad, ja pokrenem listener thread, ali sta radim sa glavnim threadom koji sam dobio od systemd launchera?

U Windows svetu kad pravim servis ja sam obavezan da javim SCMu (Service Control Manager) koji me je i pozvao da je servis "ziv" i da potom uradim return i vratim thread SCMu. Ako to ne uradim (obe stvari), SCM ili prsne odmah ili timeout-uje start operaciju i ubije servisni proces pretpostavljajuci da je pokretanje servisa prslo.

Kako systemd to resava? Ako ja ne uradim return kako on zna da je moj servis ziv? Ako pogledam moj servis za mount, vidim da je proces exited, ali ako npr pogledam neki sistemski servis:

Code:
[email protected]:~/projects/Helios/HeliosServer/Helios.Server$ systemctl status accounts-daemon.service 
● accounts-daemon.service - Accounts Service
   Loaded: loaded (/lib/systemd/system/accounts-daemon.service; enabled; vendor 
   Active: active (running) since Wed 2019-03-06 08:19:22 CET; 3h 20min ago
 Main PID: 1356 (accounts-daemon)
    Tasks: 3 (limit: 4915)
   Memory: 7.5M
   CGroup: /system.slice/accounts-daemon.service
           └─1356 /usr/lib/accountsservice/accounts-daemon

Mar 06 08:19:22 BlackWolf systemd[1]: Starting Accounts Service...
Mar 06 08:19:22 BlackWolf accounts-daemon[1356]: started daemon version 0.6.45
Mar 06 08:19:22 BlackWolf systemd[1]: Started Accounts Service.


Njegov proces i dalje radi (sto i treba), ali systemd je svestan da je servis aktivan i zavrsio je sa podizanjem, ako neko ima Requires na ovaj servis bice pokrenut. Dakle, nekako postoji neka signalizacija, medjutim ja ne mogu da nadjem na netu nista o ovome.
[ Branimir Maksimovic @ 06.03.2019. 11:02 ] @
Nemoj da se brines, napises obican program pokrenes ga preko systemd-a i to je to. Mislim da je systemd asinhron pa neces blokirati ostale procese da se pokrenu. Cak ce ti i restartovati proces ako pukne.
Evo ti kratak tutorial:
https://medium.com/@benmorel/c...vice-with-systemd-611b5c8b91d6

Stvar je krajnje prosta, nema tu nikakve filozofije.
[ mmix @ 06.03.2019. 11:21 ] @
Da, ali ako neko zavisi od mog servisa, kako systemd zna da sam ja spreman? Recimo moj chat server, hocu prvo da ucitam neku kofiguraciju, namestim nesto, ucitam nesto iz daleka, mozda treba 2, mozda 20 sekundi da ja pokrenem server. Kako systemd zna da sam spreman, tj active?

Ako neki unit ima required=helios-server kako zna da moze da ga pokrene?
[ Branimir Maksimovic @ 06.03.2019. 11:30 ] @
Ne zna systemd da li si spreman ili ne. systemd je samo jedan od n init alternativnih procesa na Linux-u.To da li si spreman javi klijentu tvoje aplikacije ili jednostavno mozes da slusas tek onda kad si spreman.
Inace to da li si spreman mozes da izvedes jos i preko skripte koja ce izaci sa -1 0 i slicno, dok ces proces forkovati. Standardno na Unix-ima.
Osim toga systemd ima neki svoj api u koji uopste nisam zalazio posto nemam nameru da se vezujem za odredjeni init sistem ;)
[ djoka_l @ 06.03.2019. 11:30 ] @
Kako znaš da je na remote serveru pokrenut http demon.
Ne znaš, probaš, pa ako ne uspe probaš ponovo ili javiš grešku.

A systemd zna process id tvog servisa. I zna da li je živ ili nije.
[ mmix @ 06.03.2019. 11:37 ] @
Kako onda radi Requires? Cemu sluzi uopste onda, onda komotno mozes asinhrono da pustis sve servise pa kom obojci kom opanci, nek oni sami paze dal je njihov dependency aktivan (jer ionako moraju)? Malo je to degute.

[ Branimir Maksimovic @ 06.03.2019. 11:41 ] @
requires sluzi tome da neke procese ne startuje asinhrono. Kazem na Unix-u je standardno da imas skriptu koja javi 0 ili -1 prilikom izlaska i to je signal init daemon-u da li je nesto uspesno startovano ili ne.
[ djoka_l @ 06.03.2019. 11:42 ] @
Kako upšte radi 1GB MS đubreta koje moraš da dovučeš na Linux da bi imao .Net core?
Po meni je neka vrsta travestije da pišeš C# koji treba da radi na Linuxu. Ljudi su odavno shvatili da ako je nešto teško da se napravi u C-u na Linuxu, urade to u Javi.
[ Branimir Maksimovic @ 06.03.2019. 11:45 ] @
Pa ima verovatno bruku koda uradjeno u C#. Posto sad ima native .NET na Linux-u, to je najjednostavnije resenje.
[ mmix @ 06.03.2019. 11:45 ] @
Ok, ali sinhrono startovanje podrazumeva red, red podrazumeva pocetak i kraj svakog elementa. Ako systemd ne zna kad je kraj moje inicijalizacije kako moze da sinhrono pokrene sledeci u redu? Arbitrarni timeout?

Ja ako izadjem iz main threada sa greskom bilo kojom (0 ili -1) proces se gasi. Ako zapakujem moj izvrni fajl u (ba)sh onda systemd nema moj PID i ne zna dal sam uopste ziv.
[ Branimir Maksimovic @ 06.03.2019. 11:55 ] @
Na unix-u mozes znati sve child procese nekog procesa. Inace pogledaj systemd api specificno dbus sd-bus i slicno.
[ mmix @ 06.03.2019. 12:01 ] @
Citat:
djoka_l:
Kako upšte radi 1GB MS đubreta koje moraš da dovučeš na Linux da bi imao .Net core?
Po meni je neka vrsta travestije da pišeš C# koji treba da radi na Linuxu. Ljudi su odavno shvatili da ako je nešto teško da se napravi u C-u na Linuxu, urade to u Javi.


.NET core zapravo radi savim lepo. Nisam jos radio benchmark ali mislim da su konacno batalili Mono JIT. Ako jesu, performanse su veoma blizu C++ koda.

Ceo SDK sa runtime-om je 270Mb, sam runtime je 70Mb za core plus jos 19Mb ako koristis asp.net. S tim sto ti ne treba, ako uradis full build prekopirace biblioteke u bin folder i distribuiras ih direktno, tako da je footprint minimalan.

Ovo je .NET core, ne .NET Framework, nema sistemskih dependencija i bloat-a.


Sve i da nemam bruku coda, C# mi je daleko bolje resenje od JVMa i Jave/Kotlina. To "ili je C ili Java" je stvar proslosti. .NET core je fully open source a C# je daleko superiorniji jezik od Jave, cak i od Kotlina, JITovan kod uvek radi na metalu. JetBrains cak ima i Linux alat (Rider) za .NET core preko kojeg sad radim. Davno je proslo vreme bloatovanog i sporog Monoa. Uskoroc ese pojaviti GUIx opcije za .net core i pocece sve vise da se javljaju aplikacije u njemu. Ja iskreno ne vidim nista losse u tome, ili gresim?


[ mmix @ 06.03.2019. 12:54 ] @
Ok, fore radi napravio sam self-contained build:

Code:
[email protected]:~/projects/Helios/HeliosServer/Helios.Server$ dotnet publish -c Release -r linux-x64 --self-contained true
Microsoft (R) Build Engine version 16.0.385-preview+g966cdf2ac6 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restoring packages for /home/mmix/projects/Helios/HeliosServer/Helios.Server/Helios.Server.csproj...
  Generating MSBuild file /home/mmix/projects/Helios/HeliosServer/Helios.Server/obj/Helios.Server.csproj.nuget.g.props.
  Restore completed in 144.25 ms for /home/mmix/projects/Helios/HeliosServer/Helios.Server/Helios.Server.csproj.
/opt/dotnet/sdk/3.0.100-preview-010184/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.RuntimeIdentifierInference.targets(151,5): message NETSDK1057: You are using a preview version of .NET Core. See: https://aka.ms/dotnet-core-preview [/home/mmix/projects/Helios/HeliosServer/Helios.Server/Helios.Server.csproj]
  Helios.Server -> /home/mmix/projects/Helios/HeliosServer/Helios.Server/bin/Release/netcoreapp3.0/linux-x64/Helios.Server.dll
  Helios.Server -> /home/mmix/projects/Helios/HeliosServer/Helios.Server/bin/Release/netcoreapp3.0/linux-x64/publish/

[email protected]:~/projects/Helios/HeliosServer/Helios.Server$ cd bin/Release/netcoreapp3.0/linux-x64/publish/
[email protected]:~/projects/Helios/HeliosServer/Helios.Server/bin/Release/netcoreapp3.0/linux-x64/publish$ du -BM
73M    .
[email protected]:~/projects/Helios/HeliosServer/Helios.Server/bin/Release/netcoreapp3.0/linux-x64/publish$ ls Helios* -lah
-rwxrw-rw- 1 mmix mmix 117K Mar  6 13:25 Helios.Server
-rw-r--r-- 1 mmix mmix  27K Mar  6 13:25 Helios.Server.deps.json
-rw-rw-r-- 1 mmix mmix 6.5K Mar  6 13:25 Helios.Server.dll
-rw-rw-r-- 1 mmix mmix  840 Mar  6 13:25 Helios.Server.pdb
-rw-r--r-- 1 mmix mmix   26 Mar  6 13:25 Helios.Server.runtimeconfig.json

[email protected]:~/projects/Helios/HeliosServer/Helios.Server/bin/Release/netcoreapp3.0/linux-x64/publish$ ./Helios.Server
Helios Server 0.1 Development (0), build 0.1.0.24156
Press <Enter> to exit... 


Code:
[email protected]:~$ telnet localhost 1234
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Helios Server 0.1 Development (0), build 0.1.0.22299
Connection closed by foreign host.

[email protected]:~$ ps -o rss,command 22586
  RSS COMMAND
27696 ./Helios.Server


Dakle, completan release a da klijent uopste ne mora da instalira bilo kakav runtime je 73Mb (sto ukljucuje i roslyn i JIT i core), od cega je aplikacija nekih 150K zajedno sa core launcehrom. Memory footprint pokrenute aplikacije je 26Mb, sto je nista i za losije masine danas.
Ali realno, bolje je imati runtime kao sto imas za Javu i onda deployment ima samo 150Kb (u ovom slucaju). 1GB? Ne vise, ni u kom slucaju.
[ mmix @ 06.03.2019. 13:05 ] @
Ako ti pak smeta sto ima puno .dll fajlova iz samog core-a, mozes da warpujes u single executable gde si odbacuju neiskoriscene biblioteke. U ovom slucaju dobijes jedan izvrsni fajl od <30Mb:

[email protected]:~/projects/Helios/HeliosServer/Helios.Server/bin/Release/netcoreapp3.0/linux-x64$ ./warp-packer --arch linux-x64 --exec Helios.Server --input_dir publish --output helios-complete
Compressing input directory "publish"...
Creating self-contained application binary "helios-complete"...
All done
[email protected]:~/projects/Helios/HeliosServer/Helios.Server/bin/Release/netcoreapp3.0/linux-x64$ ls helios-complete -la
-rwxr-xr-x 1 mmix mmix 30195347 Mar 6 14:02 helios-complete
[email protected]:~/projects/Helios/HeliosServer/Helios.Server/bin/Release/netcoreapp3.0/linux-x64$ ./helios-complete
Helios Server 0.1 Development (0), build 0.1.0.24156
Press <Enter> to exit...
[ Srđan Pavlović @ 06.03.2019. 15:09 ] @
Kad napravis .deb paket javi da testiramo malo :D
[ mmix @ 06.03.2019. 17:00 ] @
Dogovoreno

Sad citam bas, nije bas tako jednostavno, mora da se forkuje sto je veoma Linux-stvar i nije cross-platform. Mislim da postoje platform specific verzije host managera (long story) koje sluze upravo tome. Probacu pa kad dobijem .deb javim

Inace, ima ta fora sa chainovanjem servisa, ali mora da ulkjucuje fork varijante, ili Type=fork ili Type=exec za [Service]. Nasao sam opis u systemd-service man-u
[ Burgos @ 06.03.2019. 17:40 ] @
Btw, aplikacija može da javi systemd-u da je spremna pomoću systemd_notify sistema.
[ mmix @ 06.03.2019. 18:21 ] @
Btw, kad smo vec na temu sta moze u .NET core Gnome 3 GTK aplikacija u tri koraka.




Hehe, ulenji sam se na windozu vidim nesto nece da se ugasi proces, kad ono Gtk namerno fula Application.Run loop u prazno i kad nema nijedan prozor

Code (csharp):

myWin.Destroyed += (sender, eventArgs) => Application.Quit();
 



[Ovu poruku je menjao mmix dana 06.03.2019. u 20:09 GMT+1]
[ Burgos @ 06.03.2019. 19:21 ] @
Odgovarao sam sa telefona, evo malo proširenog odgovora.

Citat:
U Windows svetu kad pravim servis ja sam obavezan da javim SCMu (Service Control Manager) koji me je i pozvao da je servis "ziv" i da potom uradim return i vratim thread SCMu. Ako to ne uradim (obe stvari), SCM ili prsne odmah ili timeout-uje start operaciju i ubije servisni proces pretpostavljajuci da je pokretanje servisa prslo.


Systemd način je da koristiš Type=notify i sd_notify() nakon što je Listen uspeo, što mi se čini kao ekvivalent ovome, s tim da ne moraš da vratiš thread systemd-u, već bi trebalo da uradiš join na listener thread - da održiš servis živim (ili da u glavnom thread-u uradiš Listen, ne treba ti zaseban, ako možeš da pozoveš sd_notify nakon listena).

Citat:
Ako zapakujem moj izvrni fajl u (ba)sh onda systemd nema moj PID i ne zna dal sam uopste ziv.


Ako ćeš ovako, ne zaboravi Type=forking, mada još od upstarta imam nekoliko negativnih iskustava sa istim, pa sam odustao od toga, nakon nekoliko istih. Jedan problem je što ne možeš da uviješ servis u bash skriptu, pa da initijalizuješ aplikaciju (npr. da pročitaš ogromne fajlove sa diska), pa da forkuješ, jer tu imaš dva forka - osim ako ne izbegneš fork u skripti exec-om. Dalje, problem je ako inicijalizacija programa već diže nekoliko threadova, jer će fork nakon inicijalizacije da klonira samo jedan thread (koji poziva fork).

Lep pregled šta "new style daemon" treba da uradi se može naći https://www.freedesktop.org/software/systemd/man/daemon.html
[ Srđan Pavlović @ 07.03.2019. 00:00 ] @
Informativno za temu :)



[ mmix @ 07.03.2019. 10:53 ] @
Ok, napredak, bar sto se ice .net dela. Postoji native podrska za daemons kroz HostedService framework. Ima kompletan lifecycle support i podrzava i cleanup za SIGTERM i ostale trappable SIGs

[email protected]:/home/mmix/projects/Pegasus# /home/mmix/projects/Pegasus/PegasusServer/bin/Debug/netcoreapp3.0/PegasusServer
info: PegasusServer.DaemonHostedService[0]
StartAsync method called.
info: PegasusServer.DaemonHostedService[0]
OnStarted method called.
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /home/mmix/projects/Pegasus/PegasusServer/bin/Debug/netcoreapp3.0/

^Cinfo: PegasusServer.DaemonHostedService[0]
OnStopping method called.
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
info: PegasusServer.DaemonHostedService[0]
StopAsync method called.
info: PegasusServer.DaemonHostedService[0]
OnStopped method called.


Sad cu da vidim kako to izgleda kad se zapakuje u systemd
[ mmix @ 07.03.2019. 11:50 ] @
Ok, ovo vec obecava. Servis se dizi i gasi na komandu :) Jedino mi host vraca exit code 143 iz nekog razloga, videcu o cemu se radi:

Code:
[email protected]:/etc/systemd/system# systemctl start pegasus.service 
[email protected]:/etc/systemd/system# systemctl status pegasus.service 
● pegasus.service - Pegasus server
   Loaded: loaded (/etc/systemd/system/pegasus.service; disabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-03-07 12:45:12 CET; 3s ago
 Main PID: 31309 (PegasusServer)
    Tasks: 9 (limit: 4915)
   Memory: 7.3M
   CGroup: /system.slice/pegasus.service
           └─31309 /home/mmix/projects/Pegasus/PegasusServer/bin/Debug/netcoreapp3.0/linux-x64/publish/PegasusServer

Mär 07 12:45:12 BlackWolf PegasusServer[31309]: info: PegasusServer.DaemonHostedService[0]
Mär 07 12:45:12 BlackWolf PegasusServer[31309]:       StartAsync method called.
Mär 07 12:45:12 BlackWolf PegasusServer[31309]: info: PegasusServer.DaemonHostedService[0]
Mär 07 12:45:12 BlackWolf PegasusServer[31309]:       OnStarted method called.
Mär 07 12:45:12 BlackWolf PegasusServer[31309]: info: Microsoft.Hosting.Lifetime[0]
Mär 07 12:45:12 BlackWolf PegasusServer[31309]:       Application started. Press Ctrl+C to shut down.
Mär 07 12:45:12 BlackWolf PegasusServer[31309]: info: Microsoft.Hosting.Lifetime[0]
Mär 07 12:45:12 BlackWolf PegasusServer[31309]:       Hosting environment: Production
Mär 07 12:45:12 BlackWolf PegasusServer[31309]: info: Microsoft.Hosting.Lifetime[0]
Mär 07 12:45:12 BlackWolf PegasusServer[31309]:       Content root path: /home/mmix/projects/Pegasus/PegasusServer/bin/Debug/netcoreapp3.0/linux-x64/publish/
[email protected]:/etc/systemd/system# systemctl stop pegasus.service 
[email protected]:/etc/systemd/system# systemctl status pegasus.service 
● pegasus.service - Pegasus server
   Loaded: loaded (/etc/systemd/system/pegasus.service; disabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Thu 2019-03-07 12:45:45 CET; 2s ago
  Process: 31309 ExecStart=/home/mmix/projects/Pegasus/PegasusServer/bin/Debug/netcoreapp3.0/linux-x64/publish/PegasusServer (code=exited, status=143)
 Main PID: 31309 (code=exited, status=143)

Mär 07 12:45:45 BlackWolf PegasusServer[31309]:       OnStopping method called.
Mär 07 12:45:45 BlackWolf PegasusServer[31309]: info: Microsoft.Hosting.Lifetime[0]
Mär 07 12:45:45 BlackWolf PegasusServer[31309]:       Application is shutting down...
Mär 07 12:45:45 BlackWolf PegasusServer[31309]: info: PegasusServer.DaemonHostedService[0]
Mär 07 12:45:45 BlackWolf PegasusServer[31309]:       StopAsync method called.
Mär 07 12:45:45 BlackWolf PegasusServer[31309]: info: PegasusServer.DaemonHostedService[0]
Mär 07 12:45:45 BlackWolf PegasusServer[31309]:       OnStopped method called.
Mär 07 12:45:45 BlackWolf systemd[1]: pegasus.service: Main process exited, code=exited, status=143/n/a
Mär 07 12:45:45 BlackWolf systemd[1]: pegasus.service: Failed with result 'exit-code'.
Mär 07 12:45:45 BlackWolf systemd[1]: Stopped Pegasus server.
[email protected]:/etc/systemd/system# 
[ mmix @ 07.03.2019. 12:03 ] @
Hmm, kad startujem iz konzole i posaljem mu SIGTERM iz htopa, dobijem isti exit code bez greske u samom daemonu:

Code:

[email protected]:~/projects/Pegasus$ PegasusServer/bin/Debug/netcoreapp3.0/linux-x64/publish/PegasusServer 
info: PegasusServer.DaemonHostedService[0]
      StartAsync method called.
info: PegasusServer.DaemonHostedService[0]
      OnStarted method called.
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/mmix/projects/Pegasus/PegasusServer/bin/Debug/netcoreapp3.0/linux-x64/publish/
info: PegasusServer.DaemonHostedService[0]
      OnStopping method called.
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: PegasusServer.DaemonHostedService[0]
      StopAsync method called.
info: PegasusServer.DaemonHostedService[0]
      OnStopped method called.
[email protected]:~/projects/Pegasus$ echo $?
143


Koliko sam shvatio po netu, to je ocekivano ponasanje ako te neko ubije SIGTERM-om: 143 usually means the application caught a SIGTERM signal (128+15), meaning the process was killed. This could be because another process killed it, or perhaps because the operating system killed it for using too much memory or some other resource, etc.. Ocigledno je da je systemd poslao SIGTERM, ali zasto onda ocekuje da dobije exit code 0 da bi bio regularno stopped?
[ djoka_l @ 07.03.2019. 12:47 ] @
SIGTERM može biti hendlovan, za razliku od SIGKILL.
Možda systemd očekuje da tvoj servis uhvati signal 15 i da se regularno završi, sa exit kodom 0.
Neka se ponašanja podrazumevaju, ali nisu obavezna.
Recimo, da SIGHUP proizvede da se ponovo pročitaju setup fajlovi. Možeš da ignorišeš SIGHUP, ali to se smatra lošom praksom.
[ mmix @ 07.03.2019. 12:59 ] @
Da, nasao sam i resenje koje ne podrazumeva da moram da kopam po host serveru

[Service]
SuccessExitStatus=143


Code:
[email protected]:/etc/systemd/system# systemctl stop pegasus.service 
[email protected]:/etc/systemd/system# systemctl status pegasus.service 
● pegasus.service - Pegasus server
   Loaded: loaded (/etc/systemd/system/pegasus.service; disabled; vendor preset: enabled)
   Active: inactive (dead)

Mär 07 13:58:10 BlackWolf systemd[1]: Stopping Pegasus server...
Mär 07 13:58:10 BlackWolf PegasusServer[2330]: info: PegasusServer.DaemonHostedService[0]
Mär 07 13:58:10 BlackWolf PegasusServer[2330]:       OnStopping method called.
Mär 07 13:58:10 BlackWolf PegasusServer[2330]: info: Microsoft.Hosting.Lifetime[0]
Mär 07 13:58:10 BlackWolf PegasusServer[2330]:       Application is shutting down...
Mär 07 13:58:10 BlackWolf PegasusServer[2330]: info: PegasusServer.DaemonHostedService[0]
Mär 07 13:58:10 BlackWolf PegasusServer[2330]:       StopAsync method called.
Mär 07 13:58:10 BlackWolf PegasusServer[2330]: info: PegasusServer.DaemonHostedService[0]
Mär 07 13:58:10 BlackWolf PegasusServer[2330]:       OnStopped method called.
Mär 07 13:58:10 BlackWolf systemd[1]: Stopped Pegasus server.
[ mmix @ 09.03.2019. 12:00 ] @
Ok, uradio sam ga Sad samo da napravim .deb

[ mmix @ 09.03.2019. 13:38 ] @
Ok, ko zeli da proba:

Pegasus .deb file


Daemon je self-contained, nema dependencies.

telnet localhost 12345 nakon instalacije. .deb ima remove skriptu ako hocete posle da uklonite.
[ Srđan Pavlović @ 09.03.2019. 14:04 ] @
Nece da kvituje :D

[ Srđan Pavlović @ 09.03.2019. 14:09 ] @
A oce, oce, zaboravio sam dvotacku ispred :D
[ mmix @ 09.03.2019. 14:23 ] @
Jedini problem koji nisam resio je sto poruke overwrituju ono sto kucas u terminalu (kad ima vise korisnika). Ni Linux ni Win telnet ne podrzavaju pun ANSI, samo neke stvari koje ne rade manipulaciju bafera. Samim tim boje rade, ali komande kao sto su Esc[L za insert blank linije ne rade.

Ali ok, za proof of concept je dovoljno. Ja sam svejedno ubacio Esc[L u izlaz, tako da ako pronadjete neki pun ANSI telnet klijent, trebalo bi da radi.


[ mmix @ 10.03.2019. 16:33 ] @
Ako nekog interesuje sors:

https://gitlab.com/the-black-wolf/pegasus-server



[Ovu poruku je menjao mmix dana 14.03.2019. u 12:57 GMT+1]