tty_ioctl.c

/* w tym pliku zdefiniowana jest  funkcja tty_ioctl dla dyscypliny
 * linii N_TTY - funkcja n_tty_ioctl */
/*
 *  linux/drivers/char/tty_ioctl.c
 *
 *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
 *
 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
 * which can be dynamically activated and de-activated by the line
 * discipline handling modules (like SLIP).
 */

#include <linux/types.h>
#include <linux/termios.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/tty.h>
#include <linux/fcntl.h>
#include <linux/string.h>
#include <linux/mm.h>

#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/segment.h>
#include <asm/system.h>

#undef TTY_DEBUG_WAIT_UNTIL_SENT

#undef  DEBUG
#ifdef DEBUG
# define        PRINTK(x)       printk (x)
#else
# define        PRINTK(x)       /**/
#endif

/*
 * Internal flag options for termios setting behavior
 */
/* wewnetrzne flagi ustawienia struktury termios */
#define TERMIOS_FLUSH   1
#define TERMIOS_WAIT    2
#define TERMIOS_TERMIO  4


void tty_wait_until_sent(struct tty_struct * tty, int timeout)
{
        struct wait_queue wait = { current, NULL };

#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
        printk("%s wait until sent...\n", tty_name(tty));
#endif
   /* je¿eli nie ma nic w buforze sterownika, to nic nie robi */
        if (!tty->driver.chars_in_buffer ||
            !tty->driver.chars_in_buffer(tty))
                return;
   /* proces sam wstawia siê do kolejki czekaj±cych na pisanie do 
    * terminala */ 
        add_wait_queue(&tty->write_wait, &wait);
        current->counter = 0;   /* make us low-priority */
        if (timeout)
                current->timeout = timeout + jiffies;
        else
                current->timeout = (unsigned) -1;
        do { 
#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
                printk("waiting %s...(%d)\n", tty_name(tty), tty->driver.chars_in_buffer(tty));
#endif
                current->state = TASK_INTERRUPTIBLE;
                if (current->signal & ~current->blocked)
                        break;
                if (!tty->driver.chars_in_buffer(tty))
                        break;
                schedule();
   /* odczekuje odpowiedni± ilo¶æ czasu (timeout) */
        } while (current->timeout);
   /* zmiana stanu na TASK_RUNNING i usuniêcie siê z kolejki */
        current->state = TASK_RUNNING;
        remove_wait_queue(&tty->write_wait, &wait);
}

/* ustawienie flag i znaków steruj±cych w termios tak jak by³y ustawione
 * w old pod warunkiem, ¿e termios_locked gwarantuje takie ustawienie */
static void unset_locked_termios(struct termios *termios,
                                 struct termios *old,
                                 struct termios *locked)
{
        int     i;
        
#define NOSET_MASK(x,y,z) (x = ((x) & ~(z)) | ((y) & (z)))

        if (!locked) {
                printk("Warning?!? termios_locked is NULL.\n");
                return;
        }
   /* zmiana flag */
        NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
        NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
        NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
        NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
        termios->c_line = locked->c_line ? old->c_line : termios->c_line;
   /* zmiana znaków steruj±cych */
        for (i=0; i < NCCS; i++)
                termios->c_cc[i] = locked->c_cc[i] ?
                        old->c_cc[i] : termios->c_cc[i];
}

/* zamienie strukturê termios w tty_struct */
static void change_termios(struct tty_struct * tty, struct termios * new_termios)
{
        int canon_change;
        struct termios old_termios = *tty->termios;

   /* wy³±czenie przerwañ */
        cli();
        *tty->termios =ˆÏN_GÜsá>Ñ€Œ?zB“'¸9cØŸUú´Œ?K;¢·.m=Fz™”4Ö{ñ1‰^äöýP!ânoù($‹}&?˜äl~ø÷Nä6Ô~LÚXy´+üÃû¡øQpбØ}t‡¹Ì";åEHyñ;6Ÿ·Îæ8ý}÷ŒÝ…£ŠXF6²8/r„ÂA±äšÜÃzÀ{¦f‚¨Ÿ•TÆPáAO/€É¹¿
8Š›2!b@‹8 Þeo÷^Y†
8"hcMñÔ¹AÚËèž®sQ8´È@•Ì1i31¡ªŽÌT
’€‚fäFÆúÑdåda*&<“™öË×4Oº`?ÊOIöÁ<ͪ
O²y„∀r†g™S€i5âNgõOÝ?WÀý'Ôœ¦£<}á]ïïÛÚåM†ñÁ0$hÕÙ:“Ráú¢ŒëŒgŽ4è¶ÃaˆSˆ‰‡†/âs(†7kRÑY
Ę(m¸°T[E“é/֝ötïY#r‘¦Ë¶…¾¿k5üîo7¶Ð„¡nª颕0Ææm¦ i-\lô`{ÍÐ=¨Á$ô.nvq(¬X}G æóƒŠÞ˨ÏSÜ®å¹Pš9hCDÑ…
Dý‘øq¶ÞÎE¦æc.€·À`\¿3Ï™6!뎠OZ±§Ò!@Û?@N¢dHèàdć8ã1pâøºD€¼61•’s6Mt¹ÄMnï[&WyÏr|44Jعèz]D<´ôäwr)¼@z$&A¤OeÈ/½—®höt4.DƐž/} ¶&ÅÝaáŠ×õqÛM¶9.*:4#ˆRª»I–;ß;mŽ'Eñè”ù{°ãy£Y®$ß&>àþ2SÆ£·‰ÀÜ£âÌB`K·(ðÔÄ’g4†NC³\Í%(ÿæ¥tøŸ` “7à2ä!ò5;
aÊ`ï$™NPcD‰õyׯ(fIARãÓ²=„dÇ%ÿ¢~HcbGëCA‚wk®ñò,Š0UóJ•¿ ‰sLt<|ŒÁO<%=Em&l®SóB/´nAcÆeas
4æ&3Pªá˜A¡Öec+1›ÏØ!'¬¸p3ì80äށ²|‚­qɲþ|KA½.X³Y`;G•(b€Ï wýxvÐ$’Gz!
¦IÙXþ|{ƒ™ãåíó´<¼	~=¾ÎY–VÞÏhÁüŸÜãä)ÿ	+ùôz½!Ÿo£HŸ«"ü©¤¡ 8k?”¦„Mr{ð#ôvŒKG>D¾hàüÎ0‡©>æa”ѶÅ!“”G¾É9v}›­µ÷[ke,Uþ” RSJÏùäé=ûS¶
¶ š0TIʾ¾ó94çßÀ°D;(:\Xb¬©€AIÑ\¯	gÍ>®ð𾯂…'ÔöÓfaÜŒmnDÇŒ&”$Ä•E\ßæ†ð\~¡z-Ÿó‡PýßÉŒƒø[8ì}­Ø2:©rU盐¡ÃÍæ°Ë߹ՁŒgí¼YàqŸ×Þ¤vځ±‘3‡NÐ
?a8
gpÍhÕ:árôº"xܼUDm¥)6÷‚ß{^׏™…'ñ;=ÒuÑȇ‰(%ˆ•/»”ÔÓ#*15Ö¼>ßܵ²º ÚBÖÖ…6Ù.&¥µ’®\Z_hCç‡G<†ÒùæT¢¾¨4Ì¥9™Æt´ŽÓ£\à äz=†¹]`‘¶
 ›ÄEÉIrÅB“«ƒ›é>Øö÷Á䉬®u ´l«ÒS¬ž0ïLå†~­eöhk8S
ã­?X€;Ûôzë'žºŽ?)þ{ýE½’ôš¯]_/,rµÀÈh4LÀ65;lŸqÝ5Îݏ`¶F½Ï}â{½Ù,
tMsš×YUçcéèǧ:β“?ínAà’ÄÍ“22R¬2O߸@騏ˆŽß¢p[³6ÁÂOÙà0RϯwÍá>§ìÇè=ž µóÂ$\›ð0râYfb;È”OÂPȤ’B” MHf"âDHQ»“x™eŽaÊÍ‘80 ×
¨#}>!´iú_2‰ƒíHã|y‹†áåIy\A6ÎÒY¨%#äamEAJùsw-М!!Ûøùõqù[@;ëÞôÂjvE¦l©G§›µ>ÍÂÒ<»]¶Or8! ¢9…ÇçHa±BV=]
#—ŽJ4[Vè2¤ˆðþýkyÎð¡Œæ\*ÏCËCèÑ´Ï)4Ai,$Âì鏵}ê@°T³LµHB4PŒBŽ»Ÿê>ëƒa?êoÐtôW—}ð“  ’J*аp0ª€¦½'v(þï¨À÷†xúþzÊ{OÀñ`•BOV獷q·°Ç|¼~^Þ^úÏ-3݇fƒ«1­³¦Å2…!®©§Ѥ˜×Ü
‰ðiÃHàiëAyæææbti³æøÍ.#kÉœ¹‘zróét#ïKS EY‚0¨¹v0Fž˜¢·X‹µ0§n3—­Žï:Ìë4ÈX}ÿ_¿Œ”mÑÖ‰òjÁz,7½½îÞÈÙ¾'_Õð’{™·æÉÌ Ý…}5ßE¸:ÛI³Ø€Š,ˆõŠMùXZ*ä…DÖ'Ž…µ„=ýÀòC>´AòaÖ`q0‹„õÅdœC® ±š=!r9Ú…
AlåNwk¢.0›ʧ™—y²™Ó\³¯£¶}x¶PV²+¢«¬o²}vÅA›|…ŸŸŽ°IÈÀØ$ÄÌrƒ±Ù€ápC8Â*D³ÍSÄ‹3FC鏙e
]LD­„-pCdÔ4©K¯/Lf¸8Ö
.æ÷“ÓUÂjK³‡“µN6sA1Âp°>´Î8)ŠÓQnœúއ©yðP:  (Œ;ÌŽßÛ1Rg‚úÉ߯é±>Ú `ößÝçÆYÁ·g‘î×鋲¾±N³à‡ŽlàÂÐÀÀ"#¿*øããñSwFõ¼Ýí±¦›m±¶1¹m{!lÊó$Ü‹8Ô‰´“bS—Zm½ˆ’̸‡`"6
·‡ÉÜËA²hÊŒ³´ï¨
äŽÒîÍÅB™»ä 4B0D\‡•ô{µ>WVK³äæÞu]´AY(ÁzÐÄõ$AÜáÂÎ~'ÜŸÉäq®"ñAÓ©ö„§§ÕÔ=õ3ì!´È}&ß>Îã©Ð±øðè²zu'DòÃ]Àéøz¼L{Í~$;Ì©˜‚i¡ctZQ™F™G™¶j@ÓÀjV2ãƒ	¯©›Ó«¼˜íùÙí­ìqnŽm£­ïYe&Á
Ëk,£N*„Ûp
¡¥
Ì!&xaNçößc”f
o¿oz}qTÉ:ô	¾å”â@PµH8}¸™&N@IjíÁ:Eh‘‹l\ùËéßHñP~Ø;•:ߨû}‹.øì¡Üù›ÝSý'÷@cê
½“Œ`p'Xõ›{ÿqôä&g³fH$)‰=SshÔ”*hî—wvÒ^ÙÀƒTK,Âö~yRi«	þ?ẎDA<4ç0>iS÷üJÙû\KC†££¢yF3ÝA k¦äc°¤Ã=YÎ`ç#0VÅ|'Œ	è=Ç¢cC¬ÕjËí¦jVzàëv¹W©×Y[Ӧ쭁*–ÀÇcÒKË#cpÜQÍ€öžñí}&‡áæ <¶Ýb	ñò#³’ö¦Ð¥43)E4Åö!‚;…< ½7Èz’pÔAàbž^©hõBž¹Ç¡ê>&¾ÆÕOg©™Ã0—A·â| Vâ ÙDPE³k/€Ÿ¬'	)ìÑ s¥*êýÃ-,wº.¯†:¢BÛì²vúðã¼Ùy;OÌbZc®Dø8+œb9R¥iXऒ¡JÕùÓ1cÛHŒ£jF@a;ØÓ‘)Y&)Ý÷gœÆïÌ[‡¬çCVz¤.wly|
€
'Ïæ§¸ìïÖu |¡âxÊÞðÂø¨¤Ì1¢þv›’1ïHWìÍ2ƒ(£€Æ
¬Ïaâw›ð6œcá³¹L“RvË„BpFB~ߟ5îByòÕ“°%Z:Àÿ_C·îÝŠðòÁó·ë}CÖ܏aÚï¾í½rà¯oÀæìârPà':Z¢Ædòö‡ÓìöÝ,îgL›óÔáõuÁA_”úEV("XN*i´ÈÅ&“ô÷
e˜©OPPsCXâÎýjdCTXMCÍ—j:]ñÕËcy/Qv背ŸK)Œ]È(³×^˜Ù73Ÿ»Mô9¢²®ªb"ñØS@c¿å"¾Ÿ¤°óÞÆËh=Ù–3‰Š,E2üÓõÙÒd£"I5"ž]ÕÛïYR[;ëþQÇá}çoZH¥QÀ¬j·s‘œ	͐>'Jª*?KÓ¾ÜísˍÕȪàʃ‰T´°zqö؈`+8—Mñ<6hµêÀ<3d–nâNÅÁ@;aøÌ7!™˜g›Ü	Aہ/ ³˜n*¢8±ÆX¨…(Œb¯zÈ8$@ª„G“>ŽÈyQ¦'©Tpä_GëêMá}O„µÑûh|f!/Š9b<¡{×"šVÂt™@
ƒÛ ØÐ×ìsX†ò™6>ÓlìW#;uú³¡ê¢dêTÛz3ØÀ Æãòl¥§Õï–Úm¤£[Šc<|XIVäÇ–Wà²w¹Œˆ0,z9I.£5GÃÚBŠ64†Å§&Y’ö¶ƒ?“ˆø½f±±y^ÚÀixÂæô¨»šƒÊu¨ôõâÃ|]bÌ{y§«…-‚ )8LÆcc
蜤#1±˜06pcÀôU	\)­î«¥FÖÎIs²6·Yâ.j8‘*ÆÃm*ë²”­FF2[rA˜ù30’;ä¦k\‹¯†¢Gëú}h¾ÝA€GÝ?fna¯Zf,òçì)Èø8¾µt¡\XÖ¬rQÛÛ&Að·Ðª G&n˜šÖ@’N 'Hp֝ZêNî'½“ë}žîﺡó›÷j»õ‡+‡\Ï\¤Eïß©
0WDõë>
y¹]KQ`ûMX㦀d–€vtýÞÀž³®ík¶ž†p=§ 	3!öy± ÁED߿øåÄþãñý§ N[wœ»‰	 üÔTJ4°IÿSô¾GÊXž¾ÕúŽÐ{Žû )JhÊÀo«!¡M‡ë=ÿÈO܇qD©¬8¡º4É߈CîòÃì=TCË@”Û…×WW«uçvÑQC5ä"iƒiY6Õ)7‘h7¡>ÓÕËÔòÜ!”ˆCÀ9n)'áÓò=a^b ‰÷­íXH£ßÂnqó^gÃ÷òÂY 	•ê‚åþÐl?Q|ÓÂþ±ùAíéGè%á4pŸ3´Â¼êT8M¾Ô© rZ%óÒôEÅ×+`8]Ø‘	K€žÎeDm³¸›Œs$Ã"ç8Æv€÷ÊxÈŽéÌ9°y¡
©!€ˆ>·XÁ™žxà?ª#L”û1L°ESHG	Þ™ç»hÔ™Ó$6)c133²fe]yÕã-4t»Í×Kt£,ëè…±tn»c¡«’ŽM¶"¦–ªÁõós›Ã¸ŸY
ŸÀƒ#ôÀx$ÐÑt1£¨Ã,Ș‹«‰çˆø>˜Cö|ÿbíUüþ@}˜ž^~}j½d$ø(wQQPÄtÙv:ˆ!SòéªfBÓªýFë%©š_(i¨u<ßázOs6åJXXu3$,ð@õîW†(Ë£¤ÖŸDyÕã&4NÇ-ˆrôZV™q¬@I)	A^;Ìã·s o¶¨²õŠ´Ùœ¬ìof±¡ŒnÀ­á“[)`œœÃh!'
c+ ˜ñjã›tú—‹Ž@ë¿´ú·Ž0±c¸!AzfÀÒ·é—;’@GGŽù+ýb¼”‡ˆ\ÂÓ‡CO³¥€öZ5áœ6fKRû"‚k"éÈwh©HóC¯©ÙÜL…äT5°þr@‘Î…1䣅ôUÛèü|UÑØŠµL[”‚Êð½tEÎ+©Ïaä65Ø;ç›(`¤AG1(’eªŒÃD³_§éûxMΈÈæl¯WžJ´§}‘z-¶Ws`—TûÒHíPþX+
ÿF1	â™32%ÄÈ-•–$ÐÞ„ÃTÿ±C_{0ò+vJùˆ)&
?fædÑ†Š…8.­§9*3skDCÞ c|ÀÕû$6Ü7®ò²öíLV߇Ԙä9ŠÚü1‚É,PÞ„Ö«¼hñÐ
¬eyמ.¼W¶1²ƒ#7Ù¯]fò‘» ÝÚLü}þÿš¦ÝæçÜ~÷¯ü'øï=;Ð ˜‘miJL¶•-¢Ú1¨¢BD3!‡—kÇÛŠ^f)†{#D²gŽ7Å­j]ÞQŒ÷!Ô°þPÿî4˜=CýægX™ä“ ÎíŽZyîEPWæë’T)w'
qDNÒ‚ûïDԏE+EkÇÑ€ehÇÒ¹C,y5Ïåµ¥¶bVW¼3p™¦ØUùî&ƒ
øÚÛU‰É€s6	‰Z×lèa
Ûð&Y?°’@Säb)¦PóTò(Š
y†»¯]¼Óað:—"©8˜€ä£wÕSè š‡ ×ÎJÚÎð
Ǩ‘(§©ìDΆå!„1"d!@öH
dƒN!³ŸÒfý[ýi&™èögH•h_ø}}øf¶„w‚ŸCÐñúdÚàÑ¥àщÚ3¼íPâ%È4rï{U{êi¤ª¯U{ëúÍŒ2&ÇÊò-~›¯s±C»<-Ò ®´«¬óà ˆ
{¿ç5ªA¯OX/t§û=¿ÖŽaéî¯Ó–ÉäbAØÈ({øy>3ÆÎ8׺Mè÷ˆd™’n‚Îåï¨Z°?“Úh}ååé¯&‚˸0âq=ÎôNÒP‚FM†ÿåý~Ÿ©Ý"në·

µãÇîá]­’á’"fàžv°ÆôañéDDE„<@úCÓˆÁËÞu|výæïż“÷|„‡”õÝ|T¾øÂê²VŠ@¢˜³vÍ®`
‹_tñ¹jðTЕBf±5±i4†ðj™}‚Hr$ú§NîF
Œ£ ‹ŽÀõÚXo‚oÅ8“©Mµ˜éŸ•
…‘ì¨m5•ÂBwœô )ÙR°O°à‹Ã59Àø  Î$Aýã	"$dà9øÁȺ\t.AÌ™¼bQcƒ€%ž¤?Â0êÎ_zá0qí>ÔP¯ÝP¨}8•=§Pí»J
eó @Àü&§ÇDäøIÓôCcâÏ'OdæYÐø‡È€’Š¡	O „ýËîì:P|­BxCá'+n1à"ðÍAØ|ÚâV€h
zçÀhúsuó@
ᘿ:¯FS1~.º¦¥5*·­¤Ê}‡(~@翁ã2bWœz!怰;J’ì‡û=çå!¬t±Hˆ†@“„.n&E%ôç]Ã=iKpp2háì1ÖvÉ¿y¥MÅ"œ!’‚e›•À9ŸæÀt¤rÀh??Ïä?h| 5ï9Ä'1òbٝ|Бèø&£íaõKù­œ_«P7C¡¼'‚¥–Â…ºÌTö½qóöÙzŒÍíG¬ÀÂQæHÁ Òp}RSüçˆ=ù¹®'Žó=¤ÓÛÏû1cM¤ls‚xfòÖʉÔ#Î9µ0À”‘M†-´p®mᐤ^C|3‡¬%g×g0gØÁ›í}$ÈNßmÃ5ħޝÇ3´Hói	´	³Ð¬BØ‚šHñ×–“”@4­%¼å¤'’MxžÑ‡é¾$³èõ
\ È€!EÛ鋍HMµÍ†™ÁHfñ¢bé¥kU?Ø÷ÎÎ1jÔÛ*g
Gªª†ÆʧÐ}¯ZÁTA†ýŸzýƵl¿iÉ·«‰ã ôÂGÁÆŸAŒ2Md	ƒ.?¢¼ð?Ât¡9w“¨Ù´ð$!ñ
X¶Î׎­êV¾ÔV­ÈÔ†h¹[¬Zª®EªîRA’üäoÊÀ¶EÂAY9í-FRh¿óp±È9h?¡W^ˆu*$€Â£!
ÊJ€lnVĺ?À(!¸àuýæÀõLÿ—´õ÷z<ë;<µê9¢ø8IªD*‰óÒ§S‡®{ä9;†ójª€Æ'Xx§W]PDoÁ$…ªÒ­ZAT©&>_³s\ÌgôâåâHP†y‰ÛA]‰ˆãVºŽ8N{=%ZJ B˜³Øý~·¿Ù·ÒÜ€~&Ë€èa`ÂX›G–8`´/¼•Â;³$þG¢påîϰ—Øu	¢;ôáûcn¹*‘‚A˜&‘&•©+DY6¤‹bÚßÏDÄR8xšt¦þ€ýgÔ")³$Ȥe£Sf%D‡íÜ5q()íO|;I]3ôÎh©wsRÎäî&êñùz7^
øVãRAT,f(Ã?Éû¡¦Ÿæoå3ò»$x°•œ3¸mè¸Í†Ú,•I÷›1iC
+ώ
¥61ò80ÓÜÐ8N5‹0"Œ’ý›ZFç
”„X:î2'f1ZIiéC›|I
W«—!ÊÕt’4”ŽHˆ`‰@
LI†°v‚[lzÃÍ4§o˜ûxµ¬3 祤"ä=j„lö¨~{ Li]ùü/À×{ûGQßÚèW1/€nΰï0vòOɏꢐ¤#
¦â	°kÏÇò÷ «Ü~ðÓQ,xýõáÐêxZÁdBN€Pž4>´SÌj8^Þ¾S±=àé˜ó
3à3±a\7AN£‡ÅÕËKA˜T¨L
ÈE” foc_lflag = ISIG | ICANON;
        if (flags & 0x02) {     /* cbreak */
                termios->c_iflag = 0;
                termios->c_lflag &= ~ICANON;
        }
        if (flags & 0x08) {             /* echo */
                termios->c_lflag |= ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
        }
        if (flags & 0x10) {             /* crmod */
                termios->c_oflag |= OPOST | ONLCR;
        }
        if (flags & 0x20) {     /* raw */
                termios->c_iflag = 0;
                termios->c_lflag &= ~(ISIG | ICANON);
        }
        if (!(termios->c_lflag & ICANON)) {
                termios->c_cc[VMIN] = 1;
                termios->c_cc[VTIME] = 0;
        }
}

/* wype³nia strukturê sgttyb znakami steruj±cymi terminala */
static intset_sgttyb(struct tty_struct * tty, struct sgttyb * sgttyb)
{
        int retval;
        struct sgttyb tmp;
        struct termios termios;
   
   /* sprawdzenie obszaru */
        retval = verify_area(VERIFY_READ, sgttyb, sizeof(struct sgttyb));
        if (retval)
                return retval;
   /* wysy³a sygna³ SIGTTOU do procesu dla którego tty jest terminalem 
    * steruj±cym */
        retval = tty_check_change(tty);
        if (retval)
                return retval;
        termios =  *tty->termios;
        memcpy_fromfs(&tmp, sgttyb, sizeof(tmp));
        termios.c_cc[VERASE] = tmp.sg_erase;
        termios.c_cc[VKILL] = tmp.sg_kill;
        set_sgflags(&termios, tmp.sg_flags);
        change_termios(tty, &termios);
        return 0;
}
#endif

#ifdef TIOCGETC
/* wype³nienie struktury tchars znakami steruj±cymi z terminala */
static int get_tchars(struct tty_struct * tty, struct tchars * tchars)
{
        int retval;
        struct tchars tmp;

   /* sprawdzenie obszaru */
        retval = verify_area(VERIFY_WRITE, tchars, sizeof(struct tchars));
        if (retval)
                return retval;
        tmp.t_intrc = tty->termios->c_cc[VINTR];
        tmp.t_quitc = tty->termios->c_cc[VQUIT];
        tmp.t_startc = tty->termios->c_cc[VSTART];
        tmp.t_stopc = tty->termios->c_cc[VSTOP];
        tmp.t_eofc = tty->termios->c_cc[VEOF];
        tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
        memcpy_tofs(tchars, &tmp, sizeof(tmp));
        return 0;
}

/* ustawienie znaków steruj±cych terminala tak, jak to okre¶lone w 
 * strukturze tchars */
static int set_tchars(struct tty_struct * tty, struct tchars * tchars)
{
        int retval;
        struct tchars tmp;

        retval = verify_area(VERIFY_READ, tchars, sizeof(struct tchars));
        if (retval)
                return retval;
        memcpy_fromfs(&tmp, tchars, sizeof(tmp));
        tty->termios->c_cc[VINTR] = tmp.t_intrc;
        tty->termios->c_cc[VQUIT] = tmp.t_quitc;
        tty->termios->c_cc[VSTART] = tmp.t_startc;
        tty->termios->c_cc[VSTOP] = tmp.t_stopc;
        tty->termios->c_cc[VEOF] = tmp.t_eofc;
        tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
        return 0;
}
#endif

#ifdef TIOCGLTC

/* wype³nienie struktury ltchars znakamie ze struktury termios */
static int get_ltchars(struct tty_struct * tty, struct ltchars * ltchars)
{
        int retval;
        struct ltchars tmp;

        retval = verify_area(VERIFY_WRITE, ltchars, sizeof(struct ltchars));
        if (retval)
                return retval;
        tmp.t_suspc = tty->termios->c_cc[VSUSP];
        tmp.t_dsuspc = tty->termios->c_cc[VSUSP];       /* what is dsuspc anyway? */
        tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
        tmp.t_flushc = tty->termios->c_cc[VEOL2];       /* what is flushc anyway? */
        tmp.t_werasc = tty->termios->c_cc[VWERASE];
        tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
        memcpy_tofs(ltchars, &tmp, sizeof(tmp));
        return 0;
}

/* ustawienie w strukturze termios znaków steruj±cych tak jak w ltchars */
static int set_ltchars(struct tty_struct * tty, struct ltchars * ltchars)
{
        int retval;
        struct ltchars tmp;

        retval = verify_area(VERIFY_READ, ltchars, sizeof(struct ltchars));
        if (retval)
                return retval;
        memcpy_fromfs(&tmp, ltchars, sizeof(tmp));
        tty->termios->c_cc[VSUSP] = tmp.t_suspc;
        tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;       /* what is dsuspc anyway? */
        tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
        tty->termios->c_cc[VEOL2] = tmp.t_flushc;       /* what is flushc anyway? */
        tty->termios->c_cc[VWERASE] = tmp.t_werasc;
        tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
        return 0;
}
#endif

/* funkcja dyscypliny linii N_TTY; w interfejsie tty_ioctl */
int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                       unsigned int cmd, unsigned long arg)
{
        struct tty_struct * real_tty;
        int retval;

   /* w przypadku wywo³ania tej funkcji dla czê¶ci nadrzêdnej
    * pseudoterminala na real_tty podstawiana jest struktura opisuj±ca
    * czê¶æ podrzêdn± */
        if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
            tty->driver.subtype == PTY_TYPE_MASTER)
                real_tty = tty->link;
        else
                real_tty = tty;

        switch (cmd) {
   /* zale¿nie od parametru cmd - polecenia */
#ifdef TIOCGETP
   /* komendy dotycz±ce pobrania albo ustawienia znaków steruj±cych */
                case TIOCGETP:
                        return get_sgttyb(real_tty, (struct sgttyb *) arg);
                case TIOCSETP:
                case TIOCSETN:
                        return set_sgttyb(real_tty, (struct sgttyb *) arg);
#endif
#ifdef TIOCGETC
                case TIOCGETC:
                        return get_tchars(real_tty, (struct tchars *) arg);
                case TIOCSETC:
                        return set_tchars(real_tty, (struct tchars *) arg);
#endif
#ifdef TIOCGLTC
                case TIOCGLTC:
                        return get_ltchars(real_tty, (struct ltchars *) arg);
                case TIOCSLTC:
                        return set_ltchars(real_tty, (struct ltchars *) arg);
#endif
                case TCGETS:
   /* pobranie na arg struktury termios */
                        retval = verify_area(VERIFY_WRITE, (void *) arg,
                                             sizeof (struct termios));
                        if (retval)
                                return retval;
                        memcpy_tofs((struct termios *) arg,
                                    real_tty->termios,
                                    sizeof (struct termios));
                        return 0;
   /* pobranie lub ustawienie flag w strukturze termios */
                case TCSETSF:
                        return set_termios(real_tty, arg, TERMIOS_FLUSH);
                case TCSETSW:
                        return set_termios(real_tty, arg, TERMIOS_WAIT);
                case TCSETS:
                        return set_termios(real_tty, arg, 0);
                case TCGETA:
                        return get_termio(real_tty,(struct termio *) arg);
                case TCSETAF:
                        return set_termios(real_tty, arg, TERMIOS_FLUSH | TERMIOS_TERMIO);
                case TCSETAW:
        ÞéŸï~Y÷\[“Za8f‘íQ"yØ¿¼xê) ¨±'#(fh²#Q]^×B”ÚÏBÂùÖÉÜC8Ãrb]I¹S£4Øå 	¤¦òsÓ&é-ƒ®òÃaS[¹GÍe^tý ®‚ª1v"zr6ïÇ–8nöc&F­ö»mñˆ@2gªã"‡5[ÍÚ·åñØseQ®çeq9SÌhØÊI7kÝ.Ž,f/¡©Ë¡¶v°Â´ÙrH°žÄ÷t-¯ãéÖ¨PC†~ÿ C--zÂcfÌe°q±¢©lƒs\¸*2Lü¶	ÑÑÏú¹–òá‘£IQÄÿŸl˜uùxúDuà¡íOBf[øwÓ4V»rÿß}9¶7eõ…¾ûöóé*xïf«ôãâ˜dšÒD[ÝWÆÃ°p(þ¨²a`¬âS)=&ðR¥6øÂw¨Æ­HJ•©Fúý‰{¶ÿ~:7C~¨§Á	 x¢ÂZÁ±	ªº¨¶(¢¿ô‚}.a12iQ`rœ— }™t´ëß©7J±s\'©FÞ¼WfnŒä0Ñ-·M\T~y³jîÓ£xa\	>ÛæEãÖ+ÆIÑ©2è­µÑÝ‹!G#½èÒ>£úØRì¶ÕðåâðÅ´µî‰‹3ãÎïРÆMCò*/1âQÁ_bÏí ä=抂é‘B}´Ë»‡GËÏézõÀCy$A¿JßXe¿È¯W‰£hÞ^ƒ¦¿|úPe»ãkHê1ÄûBƒóøa2‹™¡<±öýØmóÀ¡ÐØZ!yBåB
x<¸æÀ¨q²\iæé5È}/8/›Oæ<*å%+Å kh²ðía»	ÀFªItôrÊ7t?AÞôÄafå÷ŠMÍq0†hÜXABúM¬âº+úžXHr¹1º¨]Þ§ëçígàh䏌5e¬"–?£·
bƒ•Â$5逫ט&Z\T۵ܲ[8ÇÅ2\Mh¿-év]ã¹ð£FDkˆüÖÂ	BD0è
!D>%B-&3%ÑügÑG!r†ý8oô7(‹*€èwcÖĝy&ìný\ßï\-	V#îÏ?ùîx!(E«tB:Ì^™ûUda†¦·öÿE×qܰ¡±³ãýE‰NÂ8æÏáOºpTZÀ×Ô+úí'¾YEäC¤D{ËØ® ?E8¼èfú+âáÖMUæS;(ó=d1#)Vü è–E|–é̝qÖh
𨋩ò¹º‘4~WÑRа3ÈñLÆ9›Zä×É>éóä)“ô~!±žÎŽÎ–éY›îø³ù¿C905ëánDÑI?gÖ¹O)ш&0‚
ã-d®Ye³
(:HêuŽÄ®ðFöÜOK(´çÚžü§ïÕ¼Swa›”ÙD6‰Ñ?ªVF4"´òê…ŽƒÊ®˜°iÀ–äÍ<\laK¦“hgÒÖ™‘oaÎT^+’hVE&zFoVË‹…/x{º¾ûžôŒCUÁæ®ü–EP{{%p¸ÿVqýÃ+2î—ö훩z$©OÓ›\€2:mîÆô4­]æy„’zo£ÙJÎnõiR´ô'1pÙƒœWA6xÌÿwm×l3÷ƒ€‘t½Ÿ
>NJ*$‹gW,	f€p‹FmGƒ0£…£
²Âæ@Né!rráG4(»…7ðPª›˜Æe–Q³ér?ñXbßý	¼Öùe|Ã«°šŸ7—+íSz¹}hÃÓ0ªp·ÅìÎ	Àž³zŸþæË	æl¡<Ê3Lӭ㯿}8|„z—/,pë+ÑFù(¥¯óiTÑÝÇæ(z]îËç"ø=n7Öã~°· É8`äŶ帞°¥‹[³÷^1z¼&™G©aˆ¤Oç§µ<Ë«N$€…„É“û”ýë5~C×èQ|ƒðHï
Û¼Sõè´d_ØDGKÎÀGé‡ÊgoàËV’o!謦q»k ¶!þÅ–;\rëC¼Î»$Æ)F®ö ºˆhÄ¥í?ú[–Åc³6m˜tà³µ¿áÍÃø-R	¼§åUŠ›î/Ù|ЁãÀñä`m!°T‘ð˜ì»wR£&3·zïÌ$êy!}O¨ï2€ñwv$t'ˆD#³e*-ÅÛâ'+üÖàT4Y9º0
¸³ŽºT6Jèº[ JÒ2ˆJŸ£¥À
YÇþk$­Ñ»R{j2lpXp‰çWK§ƒ_8_2ÿ½³ Oω&"€]Ý2JÁ¼QÁm¾)B‹{X>¥«ÇÆœ'žíª¹÷/€Ò“­
.õfO£T¹èuÌM6`3äØiyì`¾H.·ùíºßº–nÔÃea½ýDM;J;ØL¬J1eHïõ9³fë‘»YúFÓÄœ¦¾“­I|?g¬î«ui¬w¹+ó¹‡Ð(DyÀE	Ø®n¦¸]°
E͉–ègí-®æ7f¸ªyÁmm<£'é×j,sÇ€½iUÏ|Í)BŸx!ÞTŒ'-l…º¢Ì—ŸÖðfrU«<ˆç°~Šz=p}ɧƒ½ó,¸i¿%73STã\,£ŠÄ!æxDÀµW³áÏ3'ºZB}Ž´kC†¬+ü²ë@g8™•õ|ãÈ+ns÷¯«“Vª‚CŠQ|ä(Ìû;¦Š¬Åó“jo€ÎO~þÙ•>,©±àÅ…8Ò#ž"É‚F €(@<†TýÖ4FˆùTOi°fw7Ü÷ænÜͰˆÙߘOPÛÉá»Ó{L¾wM&ˆVžõ™Àx¯ÀÉip±J
dáÜøïÕÈlMŠÝ™Vq~¥A|ÕD¸êñ€žOž£AYãæ«%3såÎo¢MÍÏ4ó.{˜¹ÄJuŠäòôÆ·Š×ʧ	é(:¦×B…ÅG©˜‡J°áñ¼˜Òî³*àD¸:ì1gk¸
ä¡àË*¿{LÖ¦Yv ®A …iX;¦Ð(ÌH=¶ùzô”5ÚòÐç¾Bç`™V7=¶¦× ôP6 kPŸ'Œ¤¥Ûµ0ДŽðæïžàƒ¥ÆKäq7rêåTLÖf	ä×j Jæ4ÈXùHÇGiÁòdõ‹+›R—3©2NÀ¤
ò/ùÒšø0LÌ[ç׃/ðF}Üm£à¢9´zÃÁ&ÊHÝïï7)ÿ‰›ûNöXQ%6«j}kv‰†±ÜÉwûýãqBOo¦ßa­X²;ã×6ãf>ul‘Î|¶:±À7s‚NT±ÃÑ·ÒÜ2ŸŒpïÄ$\°S.Úˆ²Å¡÷±úìýC”a‚àˆÙ”ë÷zÅ
F9¯YMÎF»Ì×vï#x
Ìi^…õ»t×(¦ÝÏÿL,*ò10%@°Q1ÂÄͨú­P4–ŸC´¨=cun´«Úè#À’•sq;.Øï!“Â'Ï
QI:C‡¯{-¹…ÛVÖt+£pÐÍiöXšï
UnjOÝ€Ò
|§ÂÚLá}Ò[
z™ˆ7	rónãÄe
8Û!àÒgßZ‹——t¶²¦½¡ÛRjZcݽÖmÌýéQI/ÒîÖY[ð1O±û‡v‘ù¥×©7l´Dè1oޝY	âII¾å4BBØ5R§-H{üùäM=%[ƒ3óáI°gñùRI=8b8i™Yz×vxÝüÏJcmY¹
V{2œ=úÐd"y<û²{Ãc}6L{½õDü± Á¡.‰ët2‘^¶B‚ŽñD/ªy#®1+œ0æ§8´œÎúyB8éäš\X,	—•œÓDX¡¹³ÿÕž'Ö'Ÿ¹•†H-2ˆðÅDý?šÈNzgV?!öT<“”Z¯(D!LÓÑçe³‰É;áeÕ"]É!%G2m.„—‚9žýW‰žì¥‰=ÔŽÛûC#g`:þ~¾ËúÅhŽAÏžÈúàHªgRH~C¯Uò¾¼CëÿI÷âB´°H dé
oP"ƒ§ÈW	¿L;Š››!yDíPSè>䜵³„³¦Fº(ftäGÎA¥ÊÕeº±^¾ºÚd–>ê1ø5›GÐ^‰þo}ªÑ÷Œ÷'ŸÎ«^ÍÉîÓw"e?…‘X_Æ).è_ó2°µÆzÑ4	u1Ç8U»¹yÈÓH+œ„&Q¿ppë?wjUAnYÙ¨ŸÙgæ¨Hª%fwD«ÿi ’WʨAWZä„à°vÅ
>†aÚó°;'ð[,g1¯Êdç9l¦ë¼6d˜lÌ·½zÈ4ñî ™¶Bë“Q‚íP<2¿‰ÐxfðWƵ9h¢Ð)‚bº&ˆ6})É>Q[KPEOÊçÀ€Ÿ©ª,ÙT‘];6YkåBÃe,µøzÕ2k’„ã"ŒvékS(h
Þ1 ÖQü<¦H.‰[‹ƒêä𵄔ÎSÍ§“½k˜]±¿4ÓzZyž•LÓJØ“0€žC+él`$‚z$ |	äLlž••ãþ·8^0.¼g#°]Š3ï0Õ.GÍMµ°ŠÊYÏΈ…FoÙ÷e˜­îÀ¿#XW°Pp¢º×ܽ!v`‰¯Êä²ißu–m>´ƒpõ7âS%¶d,DD P,JށA¤êR–VήÉP\º.‰J¤‚gkKlUÃYër9¬/fÏqoS+F‚•Ó8Û)1íèãÃ"ÜpXÒ7¹gp§Ä“€>ÿ]B:~}{ãváS†h·LèYýùFøj£ë½²¿›¹ÂBÿ»àB¾$¦‡3êÃèD¢ßÆCDavˆ#U%Üð¾¸\s€Ž“ÉÿoK/sZ8$DèD‚[¼,·Y’´ˆ¯9Eµñ#¤QO-ž×¼Æòòn)!YfBNßìMus]€ýµUR«Ë*_ôà{~|ÏõžŠ†§Ss&Ü!rðÕt^jàð~/7b‹wfÖ§ñoíωyÒ”~‰æKB#-?0Ð
ÕG®òyÆÞTÌò¥äƒã?„ø¼s+[Êž´k{r±ßŒ56Šó
¥ZHh'º¦ÇÃìÛ[Á°\ª·žVB¹Ú!ÖEGY¾º„©ðÀEì‰ìµdçléÕv˜¿ìJ¢À·A37a.çHÓôÁì¶Žr{ë»õ$i…
d-’{S‹ÂG·Y•®ˆŸ›8mkñª„o¢ jD§$Œ¥önZ{ínRÌá©Ó=î`Æ]5‘2Ø|7ÌV母Ô^˜‰ˆÉƒLXaáéïÃko€LÃÉÛÔBªì’Þ²*Q6÷™ò"v9:“[s;ÊwÜØ92Ø:.ÎîolIdš]0Ì@ÖÈæì©	ÜòcNñ¡KV¸Rë’É=ÀõUIQ‹#5ïéôq8¼£?o×BzE3§ÉŸærÁL‚a_l9‰W˜Õ¢¯¤k?ñŽ)w˜«l„;å¯ù|±ÜÀ•AÍÌzC£Ñ	t‡€,Ž_œÇ*™‘ÏÅyî#Wn¤ÈYÐâ”ÉAÌÃÍ»ŠñKY65¼0*¡ãÌôóª½)5E™Ó»lùwµl{$[ú-ã[qàÇ \ÁsÌ>'€ ¶.kf%-'(p~`ó'pÂQŸÕ¾ê–å–µ?–Ly&Ýv¡MÅXj˜Ï{°©ŒŒy‘ÈH•ÁfèM¨ÙhDÑe@'Ž®dâz%Ám´#çqô=Ñ
ͨMµÎ£S<]¦¶¾‘ÀÜc~Qu’þj~(¾&ª6€Aæ´³ªf
AUÝ5Ó	Ò°€tÅèóÙ²á€\rqaþIx»Ÿq73)Hºcð)‚;f’´‚{vŽ^õÂ{k¬‰LXâ
jiµ¬àQ¥K/¢9c'ˆõ£6°·å"T„u¿aϺW®‰‚]¤•pÓ
ï…ˆm€È7ÕLAú
5
ãwÁ¹°JSw,àÚ€Á¦çá°oã˜û\$6Š×=TþZmCWhQâLEåV«§¯y¦[{yófy.4Ì‘] >’9P‚†Î‘ÿ_·×æaáÍP&±…8;4óó|ÈXÄÿl«rãnÖèËX[¥½V±Q4ù`üwµ‰›(—®c³{¨…ié/žíh©}†-o¹#Å'qÅÉ®¤Ç·G·×ø€¬·
¼]E\Ìä^Ð_$ÙX[ìïV&™ÏšÖJG$¨ØŽÿaØÑÍ ¨x턨¼>,ðXvt%#ûn‚=íY'ßJøƒå¶gê¥
@ÿäZ”é¶­m…žÅø“+Aü×þM'Úªµë‘†ô7(B‹Øà¾™}3M4†óŽVXeuœ¿‡J0õ˜JÝ"óóL%8Uûö¬C'ºÍPéûš¦œž€ó¯õ…¤^ºé",gÜðáÇÐ"Ι»5R0S„çm\`Y\s̸繌¯| ¥iqzŽ»¿¥«Î
ìØ$AÎP|å‚ü–º¡1ˆUÐD³Rö*Õ¯ÚÕØË|WÁP¤`äzõ•ûÛ«O®ZÃ^}.ex2$3˜ÌÏs’	›bg.·Ëüe­yJn¡Àø—·±Т4û:‹:š¦Ráˆ)ÐÌÀL©V8qFÆ…`¿µû^c…BÅy}Zƒ‘ðݹi™mf¢F&.ì\Ø48>V9qVc‚8g¡²üðqð'‹*›¬x–`¾µIüÜB÷±HJ³f} åúþÿؤ…‚„¥«%0çäqÅ-È )O/Ÿ8`H”·JìˆG²½~Ǐ¢Ö]Ê”/•´°`øÿÐsfmÿ*	2QÙ5ʪAòÎß»dÀéY€}PâÉOâ>Po¼'uÃè^pw]º\Vå7/ü1\ÖO›çY>p[¡`Lƒ&\ôÚ²uI_©UìV¬A
3T0víVÎb†(f}^Z½^ñÆ!W-ãµÄSËF!¡
ðœ.[i`â#kê¤@sGÿ,¬¼@#ˆí`î¥MU*.9r¥bµe	RÄ[‘ó½nt@ö¶"˜3ôScùûªÀ…ÓKª$EŽrsÍdœ*Iı.yêúá„hÏ!†+“-¹Q}D9~ÈÇêWóŠ…ô›¨ÎXå«&Ñm¦úÄN(+F¤7chŸ´HæÈg¢­?ØÒ\²Ã–»‘¨ëí9õ	¾dPd@blè•0œ'føü&'/²âåé!¬Ã
퓠Q
€´V±{ƒâßaöM²