C (1972)

Trebao mu je samo jezik da prepiše Unix za vikend — dobili smo jezik koji i danas kuca u tvom mikrovalu, telefonu i svakom drugom CVE-u s riječju 'memory'.

poglavlje 2/2721 min čitanja1970 – 1980

Lipanj 1972. Pet muškaraca uhvaćeno je s lateks rukavicama i prislušnim uređajima u zgradi Watergate u Washingtonu, i skoro nikoga to ne zanima. Novine to strpaju na petu stranicu, negdje između oglasa za automobile i vremenske prognoze. Tek će za godinu-dvije ta sitnica eskalirati u nešto što će srušiti predsjednika — ali 1972. to je samo čudna provala, jedna od tisuću te godine. Zapamti tu rečenicu, jer cijelo ovo poglavlje je upravo o tome: kako sitnica koju nitko ne primijeti postane razlog zašto tvoj telefon danas radi ono što radi.

U Reykjaviku se odvija nešto što ljudi stvarno prate — Bobby Fischer i Boris Spasski igraju šah kao da igraju Treći svjetski rat s figuricama, a cijela planeta gleda kao da je finale Svjetskog kupa. Amerikanac protiv Sovjeta, kapitalizam protiv komunizma, sve stavljeno na šahovsku ploču od 64 polja. Ljudi koji ne znaju razliku između lovca i topa odjednom su eksperti za sicilijansko otvaranje. To je 1972. — godina kad je jedan geopolitički obračun prerušen u društvenu igru bio zanimljiviji od bilo čega što se događa u informatici.

A u informatici, da budemo iskreni, ništa se ne događa što bi dospjelo na naslovnice. Hewlett-Packard je upravo izbacio HP-35, prvi džepni kalkulator koji radi znanstvene funkcije — sinuse, logaritme, sve to što je do sad tražilo šiber, onu drvenu ili plastičnu ravnalicu s pomičnim dijelom koju je tvoj otac ili djed nosio u džepu kao značku struke. Šiber je odjednom smiješan, muzejski predmet, a inženjeri se navikavaju na ideju da stroj koji stane u dlan računa brže od čovjeka koji je za to trenirao cijeli život.

Ono što se, međutim, ne mijenja — i to je poanta — jest kako se pišu programi. Asembler je jezik u kojem svaka naredba odgovara točno jednoj instrukciji procesora — pišeš gotovo izravno u strojnom kodu, bez ikakve apstrakcije koja bi te štitila od hardvera ispod. Baš zato je toliko nezgodan za prenošenje: naredbe su skrojene za jedan specifičan procesor, i to je to. Ako imaš PDP-11, pišeš asembler za PDP-11. Ako sutra kupiš IBM mainframe, bacaš sve što si napisao i počinješ ispočetka, na novom jeziku, po novim pravilima, kao da prvi program nikad nije postojao. Nema prevoditelja koji prenosi tvoj rad s jednog stroja na drugi, nema mosta. Riječ »prenosivost« postoji, ali živi u akademskim radovima, na konferencijama gdje profesori raspravljaju o teoriji — ne u strojarnicama gdje inženjeri stvarno kucaju kod i moraju sutra ujutro imati nešto što radi.

U jednoj takvoj strojarnici, u Bell Labsu u New Jerseyju, sjedi čovjek koji ima posve praktičan, nimalo epohalan problem: treba prepisati jedan operativni sustav, a asembler mu ide na živce jer mu ne dopušta da to napravi jednom i gotovo. Nitko od njegovih kolega ne sluti da će rješenje tog dosadnog, lokalnog, gotovo administrativnog problema za pola stoljeća pokretati mikrovalne pećnice, Mars roverse i kernel telefona u tvom džepu — onu srž operativnog sustava koja izravno upravlja hardverom, memorijom, diskovima, procesima, i bez koje bi taj telefon bio samo skupo staklo. Ali dosad smo već skužili — najveće stvari u ovoj enciklopediji rijetko počinju s trubama. Počinju s nekim tko je samo htio prestati ispočetka pisati isti kod.

1972. Dennis Ritchie nema problem koji zvuči kao problem. Nema deadline od šefa, nema investitora koji dahće za rezultatima, nema ni jasnog naslova posla — u Bell Labsu tih godina to je normalno stanje. Ima samo jedan mali, tehnički, dosadan problem: Unix, operativni sustav koji je s Kenom Thompsonom sklepao na PDP-7, napisan je u asembleru. PDP-7, a poslije i PDP-11, minirаčunala tvrtke DEC — u ono doba omiljena igračka po laboratorijima i sveučilištima, nešto poput ormara punog elektronike koji bi danas u snazi gubio i od kalkulatora — a asembler za PDP-7 vrijedi, pazi sad, isključivo za PDP-7. Prebaciš sustav na drugi stroj i cijeli taj asemblerski kod postaje beskorisna hrpa nula i jedinica koje nešto znače samo jednom, specifičnom, ubrzo zastarjelom komadu hardvera.

Zvuči poznato? Trebalo bi. Ovo je 1972., ali princip je isti kao i danas kad migriraš neki „legacy” sustav — programerski žargon za staru, zakrpanu informatičku ruševinu koja i dalje tiho pogoni pola tvrtke, a nitko se ne usudi dirati je iz straha da se sve ne raspadne — i otkriješ da je pola njega napisano za bazu podataka koju već godinama nitko ne održava. Samo je 1972. verzija toga gora, jer nema ni baze za usporedbu — nema ničeg. Svaki proizvođač računala ima svoj set instrukcija, svoj dijalekt asemblera, i ako želiš da tvoj sustav radi na drugom stroju, ne prevodiš kod. Pišeš ga iznova. Cijelog. Ponovno.

Thompson je već pokušao riješiti taj problem jezikom zvanim B, koji je i sam bio pojednostavljena verzija starijeg jezika BCPL (koji je, da budemo do kraja precizni u genealogiji, i sam bio pojednostavljena verzija još starijeg CPL-a — akademici tih godina vole jezik zvati po slovima i onda ga skratiti, ne pitaj zašto). B je bio korak u pravom smjeru, ali imao je jednu rupu koja ga je onesposobila za pisanje ozbiljnog sustava: nije znao razlikovati tipove podataka. Za B, broj je broj, bio on cijeli broj, znak ili adresa u memoriji — sve je jedna riječ, sve se tretira isto. Fino za mali interpreter, katastrofa za operativni sustav (odnosno kernel) koji mora precizno znati je li ono što gleda broj 65 ili slovo A.

I tu upada Ritchie, negdje između 1971. i 1973., s potpuno neromantičnim ciljem. Ne sjedi on tu i sanja o jeziku koji će za pedeset godina još pokretati pola planeta. Ne piše manifest o elegantnoj sintaksi ni o tome kako bi programski jezici trebali izgledati u idealnom svijetu. On rješava jedan konkretan, prizemni problem: treba mu jezik u kojem može prepisati Unix tako da ga sutra može prebaciti na drugi stroj bez da piše sve iznova. To je to. Cijela ambicija.

Uzeo je B, dodao mu tipove podataka — cijeli broj je cijeli broj, znak je znak, a pointer je pointer (jednostavno rečeno, adresa u memoriji, papirić s uputom „podatak koji te zanima nalazi se tu i tu”, umjesto samog podatka) — i jezik je konačno znao razliku. Nazvao ga je, u nastavku te bogate tradicije imenovanja po jednom slovu, jezikom C. Ne C kao u nečem kreativnom. C kao sljedeće slovo u nizu B, BCPL, CPL. Ni truna marketinga, ni truna pretencioznosti. Samo alat, s imenom koje je zapravo redni broj.

Nitko u tom trenutku, ni Ritchie sam, nije mislio da upravo gleda početak nečeg što će za pedeset godina i dalje pokretati kernel svakog telefona u tvom džepu. Gledao je samo jedno: ima li ovaj jezik dovoljno moći da njime napiše operativni sustav, a dovoljno apstrakcije da taj sustav sutra radi i na stroju koji još ne postoji.

Prva posljedica: OS u višem jeziku
§ 02

Prva posljedica: OS u višem jeziku

Godina 1973. Ritchie ima jezik. Sad dolazi pravo pitanje, ono koje mijenja sve — što s njim, sad kad postoji? Odgovor koji su Ritchie i Thompson dali te godine toliko je jednostavan da danas zvuči kao nešto što bi predložilo i dijete, a tada je zvučao kao da su u kantini Bell Labsa pojeli nešto neprovjereno: prepisat ćemo Unix. Cijeli operativni sustav. U C-u.

Da vidiš zašto je to ludo, moraš znati što je 1973. bila sveta istina, ona vrsta istine koju nitko ne dovodi u pitanje jer je »svi znaju«. A svi su znali da se operativni sustavi pišu u asembleru. Ne zato što je to bilo pravilo napisano negdje na zidu, nego zato što je to bila jedina razumna opcija. Kernel razgovara s hardverom izravno, upravlja memorijom, prekidima, diskovima — stvarima gdje ti treba potpuna kontrola nad svakim bitom, i asembler ti je davao baš to. Viši jezik bio je za znanstvene proračune, za fakultetske vježbe, za stvari koje si mogao priuštiti s luksuzom apstrakcije. Za srce sustava? Nikad. To je bilo poput ideje da avion pilotiraš u rukavicama za pećnicu — tehnički moguće probati, praktično samoubojstvo.

Pa su to i učinili. I nije bilo katastrofe. To je ono što stvarno boli heretike svih generacija — kad se hereza pokaže točnom, i to bez drame, bez eksplozije, bez naslova u novinama. Kernel je radio. Radio je dobro. Radio je, štoviše, brže nego što su mnogi očekivali, jer C je bio dovoljno tanak, dovoljno blizak stroju, da apstrakcija nije koštala skoro ništa. Dobio si čitljivost višeg jezika po cijeni koja je bila zaokružena na nulu.

Ali prava posljedica, ona koja se u tom trenutku možda nije čak ni prepoznala kao najveća, nije bila brzina. Bila je selidba. Unix pisan u PDP-11 asembleru bio je zavezan za PDP-11 kao pas za lanac — mogao je lajati koliko hoće, nije mogao dalje od dvorišta. Prebaci taj kod na drugi procesor i imaš posao od nekoliko mjeseci, praktički pisanje iznova, red po red, instrukciju po instrukciju, jer asemblerski kod jednog čipa ne razumije ništa od jezika drugog. To je bio normalan trošak. Svi su ga plaćali. Nitko se nije bunio, jer se nije znalo da postoji alternativa.

I odjednom je ta prenosivost postojala, stvarno, ne u teoriji. Prepiši Unix u C, i ono što je preostalo za prilagodbu novom stroju svelo se na tanak sloj — dijelove koji zaista moraju razgovarati s konkretnim hardverom. Sve ostalo, cijela filozofija sustava, datotečni sustav, procesi, cijevi između programa, putovalo je bez otpora. Napiši kompajler za novi stroj, i tvoj operativni sustav odjednom govori taj novi jezik, bez da si ga učio ispočetka.

To se zove prenosivost, i danas je ta riječ toliko banalna da je uopće ne primjećuješ, kao zrak kojim dišeš. 1973. to je bila znanstvena fantastika koja je upravo, tiho, postala rutina u jednoj zgradi u New Jerseyu.

Nitko u tom trenutku nije znao da su upravo napravili predložak po kojem će se pisati praktički svaki operativni sustav sljedećih pedeset godina. Domino je pao. Sljedeći je bio puno veći.

Eskalacija: jezik koji je pojeo svijet
§ 03

Eskalacija: jezik koji je pojeo svijet

1978. izlazi knjiga od 228 stranica, jeftinija od pizze, koja će promijeniti više karijera nego bilo koji MBA program. Zove se »The C Programming Language«, autori su Brian Kernighan i sam Dennis Ritchie, a cijela struka je od tog trenutka zove jednostavno K&R — po inicijalima, kao da je zakon, kao da je propis. I jest propis, u praksi. Nema poglavlja o „filozofiji programiranja”, nema motivacijskih citata o snovima i inovaciji, nema slika sretnih programera koji gledaju u monitor s osmijehom kao da su upravo riješili glad u svijetu. Ima definicije, ima primjere, ima vježbe. Rečenice su kratke, gotovo osorne. Kad K&R objašnjava nešto, objašnjava to jednom, dobro, i onda ide dalje. Nema udvaranja čitatelju.

To je vrlo neobično za tehničku knjigu tog doba, gdje se pisalo kao da je svaki koncept dostojan doktorske disertacije. K&R je pisan kao da je autor umoran, žuri se na sastanak i nema vremena tumačiti očito. I upravo ta lakoničnost — ta nepotrebna, gotovo agresivna štedljivost riječima — postala je uzor za cijelu generaciju tehničkih priručnika koji su dolazili poslije. Ako si u devedesetima čitao neki priručnik za bilo koji jezik i osjećao da je pisan suho, precizno, bez suvišnog ukrasa — hvala K&R-u, on je postavio kalup.

Ali zaboravimo na trenutak knjigu i vratimo se na ono što se stvarno događalo vani, u svijetu koji nije čitao K&R nego je samo htio da mu program radi. Do sredine sedamdesetih C je prestao biti „onaj jezik kojim su u Bell Labsu prepisali Unix” i postao nešto puno opasnije za konkurenciju — postao je zajednički jezik. Lingua franca. Riječ koju koristimo za latinski u srednjovjekovnoj Europi ili za engleski danas na aerodromima — jezik koji ne mora biti nikome materinji, ali ga svi razumiju dovoljno da se posao obavi.

Kompajleri (programi koji tvoj C kod prevode u jezik razumljiv procesoru) pisali su se za sve što je imalo strujni kabel. Mainframeovi — ona ogromna računala veličine ormara kojima su upravljali ljudi u sivim mantilima — mini-računala, kasnije mikroprocesori u raznim uređajima: svugdje se pojavio isti C, s malim razlikama koje su programere nervirale, ali temeljno isti jezik. To znači da je vještina prestala biti vezana za jedan stroj. Nekad si učio „asembler za PDP-11” i to znanje je vrijedilo dok imaš PDP-11 pred sobom, a onda ga baciš u ropotarnicu znanja kad firma kupi novi stroj. C je to promijenio — naučio si koncept, i koncept je putovao s tobom, bez obzira na to koje računalo stoji ispred tebe. Ovo je civilizacijska promjena maskirana u tehnički detalj, i zato je ova priča lančana reakcija, a ne slijeganje ramenima: prepisivanje jednog operativnog sustava nije ostalo izolirani slučaj, postalo je predložak po kojem se pisalo sve ostalo.

A onda dolazi dio koji je danas lako preskočiti kao sitnicu, a zapravo je jedan od najvećih tihih trijumfa u povijesti softvera: sve što je dolazilo poslije C-a nije ga zamijenilo. Nadograđivalo ga je. Bjarne Stroustrup je osamdesetih htio objektno orijentirano programiranje — pristup u kojem se program organizira oko „objekata” koji spajaju podatke i funkcije, poput ladica koje same znaju što im je unutra i što s time raditi — ali nije izmislio novi jezik od nule. Uzeo je C i dodao mu klase, pa ga je pošteno i nazvao: C++. Ime samo priznaje dug. Plus plus, uvećanje, sljedeći korak — ali korijen je i dalje C.

Java je devedesetih obećavala »pišeš jednom, radi svugdje« — u vrijeme kad je to bilo zaista veliko obećanje, jer je do tada program napisan za jedan sustav često trebalo gotovo iznova pisati da bi radio na drugom. Bio je to ironičan odjek onoga što je C već tiho radio dvadeset godina prije, bez marketinške kampanje, samo zahvaljujući kompajlerima koji su postojali za svaki stroj. Ali sintaksa Jave — vitičaste zagrade, točke-zarezi, if, for, while u istom poretku — sve je to C u odijelu. C# je došao poslije kao Microsoftov odgovor Javi, i opet — ista obitelj sintakse, isti geni, samo drugo prezime. Čak i JavaScript, jezik napravljen u deset dana za sasvim drugu svrhu i u sasvim drugom kontekstu, posudio je vitičaste zagrade i sintaksu petlji od C-a jednostavno zato što je to bio jezik koji su programeri već znali čitati. Brendan Eich nije morao objašnjavati što je for petlja — svi su je već vidjeli.

OK, sve jasno do sad? Dobro. Jer sad dolazi ono najbitnije, ono što ovu priču čini lančanom reakcijom a ne pukom listom trivijalnosti: kad kažemo da je „C pojeo svijet”, ne mislimo samo da se puno koristio. Mislimo da je definirao kako izgleda programiranje samo po sebi, i to na način toliko dubok da ga danas i ne primjećujemo — kao što riba ne primjećuje vodu u kojoj pliva. Petlje, uvjeti, funkcije, sintaksa s vitičastim zagradama — sve je to postalo „normalno”, iako nije bilo neizbježno. Postojali su i drugi putovi: Lisp je nudio potpuno drukčiju filozofiju programiranja, Smalltalk drukčiju, Prolog opet neku svoju, treću priču. Ali pobijedio je C, i njegovi potomci su pobijedili s njim, jednostavno zato što je bio prvi jezik koji je bio istovremeno dovoljno moćan za sistemsko programiranje i dovoljno prenosiv da putuje sa strojem na stroj.

I tu smo, na pola priče, s jezikom koji je od pukog rješenja jednog problema u jednom laboratoriju postao gramatika kojom cijela industrija razmišlja pola stoljeća. Domino je pao, i pao je na cijelo polje. Ali svaka moć ima cijenu, a ova je posebno slikovita — i o njoj ide sljedeći dio priče.

Cijena: povjerenje kao feature
§ 04

Cijena: povjerenje kao feature

E sad dolazimo do dijela gdje se zabava malo prekine. Jer svaka odluka u ovoj priči — asembler koji je Ritchie htio zamijeniti, jezik koji je htio da bude brz i blizu stroja — ima cijenu. I ta cijena se nije naplatila 1972. Naplaćuje se i danas, svaki put kad neka firma objavi da je »otkrila sigurnosni propust« i da korisnici trebaju odmah ažurirati sve. Skoro pola stoljeća kasnije, ista faktura, drugi datum.

Zato da razjasnimo što je C zapravo obećao programeru, jer to obećanje je srž cijele priče. C ti kaže: vjerujem ti, ne provjeravam te. Ako kažeš da ovaj niz ima deset elemenata, dat ću ti deset elemenata i ni mrvicu zaštite ako pokušaš upisati jedanaesti. Ako želiš pokazivač koji gleda na komad memorije, evo ti pokazivač, i ne pitam te je li ta memorija još tvoja ili ju je već netko drugi preuzeo. C ne provjerava granice nizova. C ne broji za tebe. C ti daje ključeve auta, pun tank benzina i kaže „sretan put”, bez pojasa, bez airbaga, bez one lampice koja se pali kad zaboraviš pojas.

Zvuči kao sloboda, i jest. Upravo ta sloboda je razlog zašto je Unix mogao biti brz i zašto je C mogao raditi na stroju koji je imao manje memorije nego što danas ima jedna sličica emotikona. Ali ta ista sloboda je i najskuplja pretpostavka u povijesti softvera: da programer zna što radi.

Ovo se zove buffer overflow (prelijevanje međuspremnika) — i ako imaš osjećaj da si taj pojam već čuo, imaš pravo: spomenuli smo ga davno, kad je von Neumann spojio program i podatke u istu memoriju. Ta odluka je otvorila vrata. C ih je samo ostavio širom otvorena, bez čuvara, bez alarma, s tepihom za dobrodošlicu ispisanim za bilo koga tko naiđe.

I naići će netko. Naišao je 1988., kad je jedan studentski crv — Morris worm, o njemu detaljnije kasnije u ovoj knjizi — iskoristio baš takvu rupu u jednom Unix servisu i za nekoliko sati ugasio velik dio interneta koji je tada postojao, što jest bio manji internet, ali i mnogo veći šok, jer nitko nije vjerovao da je to moguće. Naišao je opet 2014., kad je Heartbleed, propust u OpenSSL-u — knjižnici napisanoj, naravno, u C-u, koja se koristi da šifrira internetski promet i čuva tajne poput lozinki dok putuju do servera, ono što vidiš kao malokatanac pored adrese web stranice — pustio da se iz memorije servera cijedi baš ono što je trebala čuvati: lozinke, ključevi, komadići razgovora koji su trebali biti privatni. Isti mehanizam. Ista rečenica u pozadini: vjerovali smo programeru da će paziti.

I nemoj sad misliti da su to bili loši programeri. Ne. To su bili neki od najboljih ljudi koji su u tom trenutku postojali u toj industriji, ljudi koji su čitali specifikacije, pisali testove, brinuli se. Problem nije bio u njima. Problem je bio u jeziku koji je od početka rekao: ti si odgovoran za granice, ne ja. A granice, ispada, čovjek zaboravi. Uvijek. Nije to sramota, to je jednostavno kako radi ljudski mozak pod pritiskom, s previše stvari u glavi, s previše linija koda koje treba pogledati prije petka.

Ritchie i Thompson, kad su ovo pisali, nisu razmišljali o milijardama linija koda ni o internetu, ni o tome da će jednog dana neki server u Njemačkoj cijediti lozinke jer je knjižnica napisana 2012. imala jednu provjeru manje nego što je trebala. Razmišljali su o PDP-11 i o tome da im program stane u memoriju, da radi brzo, da mogu prepisati OS bez asemblera. Sitni, praktični, razumni ciljevi. Ali odluka da se povjerenje ugradi kao temeljna značajka jezika, a ne kao opcija — to je odluka koja se, kao svaka dobra lančana reakcija, umnožila daleko izvan sobe u kojoj je donesena.

I zato, kad danas čitaš da je neka aplikacija, neki router, neka pametna kamera na tvom balkonu imala »kritičnu sigurnosnu ranjivost povezanu s memorijom« — ne treba te čuditi to što se dogodilo. Treba te čuditi obrnuto: da toga nema više. Jezik koji ti vjeruje da znaš što radiš, ugrađen u pola svjetske infrastrukture, u rukama generacija programera koji su, svi do jednog, samo ljudi — dakle svi u petak popodne umorni — to nije recept za katastrofu. To je raspored isporuke katastrofe, s dostavom svakih nekoliko godina, pouzdano kao autobus.

Svijet kakav poznaješ
§ 05

Svijet kakav poznaješ

Pa dobro, reći ćeš, sve je to lijepo i davno, 1972. je prošlost, danas imamo Python, JavaScript, cloud, AI koji piše kod umjesto tebe. Otvori sad telefon koji ti je u ruci. Njegov kernel, dio koji stvarno diže i sliježe svaki proces, svaku poruku, svaki dodir ekrana, piše se, dobar dio i danas, u C-u. Android? Linux kernel, C. iPhone? XNU kernel, mješavina C-a i C-ova nezakonitog djeteta, C++-a. Nije to neka nostalgična referenca za muzej, to je aktivni kod koji se kompajlira ovog trena negdje u nekoj fabrici čipova.

I ne staje na telefonu. Tvoja mikrovalna pećnica ima procesorčić veličine nokta koji broji sekunde i pali magnetron (onu cjevčicu koja stvarno grije hranu) — pisan u C-u, ili u nečemu što se C-u toliko klanja da razlika nije bitna. Perilica robe. Router. Pacemaker, ako ga imaš, ili kad ga jednog dana budeš imao. Auto ti danas ima više linija C koda u sebi nego što je Apollo 11 imao ukupno softvera za slijetanje na Mjesec — i to je stvarna, provjerena usporedba, ne moja fora.

A onda odeš još dalje. Curiosity i Perseverance, dva robota koja upravo sad, dok ti čitaš ovo, guraju kotače po crvenoj prašini 225 milijuna kilometara od najbliže pizzerije — njihov softver za letenje i navigaciju? C, s malo C++-a za šminku. Kad NASA šalje nešto što ne može popraviti serviser sutra ujutro, kad cijena greške nije reboot nego milijarde dolara i deset godina posla koje baciš u smeće, ne posegneš za najnovijim frameworkom s Hacker Newsa. Posegneš za jezikom koji zna točno, do bajta, što se događa u memoriji. Ritchie je 1972. htio jezik koji radi na PDP-11 s 8 kilobajta RAM-a — toliko malo da bi mu se danas smijala i tvoja pametna žarulja. Pola stoljeća kasnije, taj isti mentalitet — vjerujem programeru, dajem mu adresu i pusti me na miru — vozi robote po drugom planetu.

Zato tek sad, pola stoljeća nakon što je Ritchie zapisao prvi kompajler, netko konačno kuca dovoljno glasno da ga čuju i oni koji pišu kernele. Rust ne obećava da će biti brži od C-a — neće, ili hoće, nebitno. Obećava da neće dopustiti onaj buffer overflow o kojem smo govorili *dok kompajlira*, ne dok već gori u produkciji. Linux kernel je 2022. prvi put pustio Rust unutra, pored C-a, kao stanara u istoj zgradi. Prvi put u pedeset godina neka konkurencija stvarno kuca na ta vrata, umjesto da samo lupa i odlazi.