OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [drivers/] [char/] [tty_io.c] - Blame information for rev 1622

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 *  linux/arch/arm/drivers/char/tty_io.c
3
 *
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
5
 *
6
 *  Modifications for ARM processor Copright (C) 1995, 1996 Russell King.
7
 */
8
 
9
/*
10
 * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
11
 * or rs-channels. It also implements echoing, cooked mode etc.
12
 *
13
 * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
14
 *
15
 * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the
16
 * tty_struct and tty_queue structures.  Previously there was an array
17
 * of 256 tty_struct's which was statically allocated, and the
18
 * tty_queue structures were allocated at boot time.  Both are now
19
 * dynamically allocated only when the tty is open.
20
 *
21
 * Also restructured routines so that there is more of a separation
22
 * between the high-level tty routines (tty_io.c and tty_ioctl.c) and
23
 * the low-level tty routines (serial.c, pty.c, console.c).  This
24
 * makes for cleaner and more compact code.  -TYT, 9/17/92
25
 *
26
 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
27
 * which can be dynamically activated and de-activated by the line
28
 * discipline handling modules (like SLIP).
29
 *
30
 * NOTE: pay no attention to the line discipline code (yet); its
31
 * interface is still subject to change in this version...
32
 * -- TYT, 1/31/92
33
 *
34
 * Added functionality to the OPOST tty handling.  No delays, but all
35
 * other bits should be there.
36
 *      -- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993.
37
 *
38
 * Rewrote canonical mode and added more termios flags.
39
 *      -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94
40
 *
41
 * Reorganized FASYNC support so mouse code can share it.
42
 *      -- ctm@ardi.com, 9Sep95
43
 *
44
 * Altered get_free_page to kmalloc's for tty structures to save memory
45
 *  on the ARM processor
46
 *      -- rmk@ecs.soton.ac.uk
47
 *
48
 * New TIOCLINUX variants added.
49
 *      -- mj@k332.feld.cvut.cz, 19-Nov-95
50
 *
51
 * Restrict vt switching via ioctl()
52
 *      -- grif@cs.ucr.edu, 5-Dec-95
53
 *
54
 * Rewrote init_dev and release_dev to eliminate races.
55
 *      -- Bill Hawes <whawes@star.net>, June 97
56
 */
57
 
58
#include <linux/config.h>
59
#include <linux/types.h>
60
#include <linux/major.h>
61
#include <linux/errno.h>
62
#include <linux/signal.h>
63
#include <linux/fcntl.h>
64
#include <linux/sched.h>
65
#include <linux/interrupt.h>
66
#include <linux/tty.h>
67
#include <linux/tty_flip.h>
68
#include <linux/timer.h>
69
#include <linux/ctype.h>
70
#include <linux/kd.h>
71
#include <linux/mm.h>
72
#include <linux/string.h>
73
#include <linux/malloc.h>
74
 
75
#include <asm/segment.h>
76
#include <asm/system.h>
77
#include <asm/bitops.h>
78
 
79
/*#include <linux/scc.h>*/
80
 
81
#include "kbd_kern.h"
82
#include "vt_kern.h"
83
#include "selection.h"
84
 
85
#ifdef CONFIG_KERNELD
86
#include <linux/kerneld.h>
87
#endif
88
 
89
#ifdef CONFIG_SERIAL_TRIO
90
extern int rs_trio_init(void);
91
#endif
92
 
93
#if PAGE_SIZE > 8192
94
static __inline__ struct tty_struct * alloc_tty_struct (int prio)
95
{
96
        return kmalloc (sizeof (struct tty_struct), prio);
97
}
98
 
99
static __inline__ void free_tty_struct (struct tty_struct *tty)
100
{
101
        kfree (tty);
102
}
103
#else
104
static __inline__ struct tty_struct * alloc_tty_struct (int prio)
105
{
106
        return (struct tty_struct *) get_free_page (prio);
107
}
108
 
109
static __inline__ void free_tty_struct (struct tty_struct *tty)
110
{
111
        free_page ((unsigned long) tty);
112
}
113
#endif
114
 
115
#define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
116
#define TTY_DEV MKDEV(TTYAUX_MAJOR,0)
117
 
118
#undef TTY_DEBUG_HANGUP
119
 
120
#define TTY_PARANOIA_CHECK
121
#define CHECK_TTY_COUNT
122
 
123
/*extern void set_vesa_blanking(const unsigned long arg);*/
124
 
125
struct termios tty_std_termios;         /* for the benefit of tty drivers  */
126
struct tty_driver *tty_drivers;         /* linked list of tty drivers */
127
struct tty_ldisc ldiscs[NR_LDISCS];     /* line disc dispatch table     */
128
 
129
int kmsg_redirect;
130
struct tty_struct * redirect;
131
struct wait_queue * keypress_wait;
132
 
133
static void initialize_tty_struct(struct tty_struct *tty);
134
 
135
static int tty_read(struct inode *, struct file *, char *, int);
136
static int tty_write(struct inode *, struct file *, const char *, int);
137
static int tty_select(struct inode *, struct file *, int, select_table *);
138
static int tty_open(struct inode *, struct file *);
139
static void tty_release(struct inode *, struct file *);
140
static int tty_ioctl(struct inode * inode, struct file * file,
141
                     unsigned int cmd, unsigned long arg);
142
static int tty_fasync(struct inode * inode, struct file * filp, int on);
143
 
144
#ifndef MIN
145
#define MIN(a,b)        ((a) < (b) ? (a) : (b))
146
#endif
147
 
148
/*
149
 * These two routines return the name of tty.  tty_name() should NOT
150
 * be used in interrupt drivers, since it's not re-entrant.  Use
151
 * _tty_name() instead.
152
 */
153
char *_tty_name(struct tty_struct *tty, char *buf)
154
{
155
        if (tty)
156
                sprintf(buf, "%s%d", tty->driver.name,
157
                        MINOR(tty->device) - tty->driver.minor_start +
158
                        tty->driver.name_base);
159
        else
160
                strcpy(buf, "NULL tty");
161
        return buf;
162
}
163
 
164
char *tty_name(struct tty_struct *tty)
165
{
166
        static char buf[64];
167
 
168
        return(_tty_name(tty, buf));
169
}
170
 
171
inline int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
172
                              const char *routine)
173
{
174
#ifdef TTY_PARANOIA_CHECK
175
        static const char *badmagic =
176
                "Warning: bad magic number for tty struct (%s) in %s\n";
177
        static const char *badtty =
178
                "Warning: null TTY for (%s) in %s\n";
179
 
180
        if (!tty) {
181
                printk(badtty, kdevname(device), routine);
182
                return 1;
183
        }
184
        if (tty->magic != TTY_MAGIC) {
185
                printk(badmagic, kdevname(device), routine);
186
                return 1;
187
        }
188
#endif
189
        return 0;
190
}
191
 
192
static int check_tty_count(struct tty_struct *tty, const char *routine)
193
{
194
#ifdef CHECK_TTY_COUNT
195
        struct file *f;
196
        int i, count = 0;
197
 
198
        for (f = first_file, i=0; i<nr_files; i++, f = f->f_next) {
199
                if (!f->f_count)
200
                        continue;
201
                if (f->private_data == tty) {
202
                        count++;
203
                }
204
        }
205
        if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
206
            tty->driver.subtype == PTY_TYPE_SLAVE &&
207
            tty->link && tty->link->count)
208
                count++;
209
        if (tty->count != count) {
210
                printk("Warning: dev (%s) tty->count(%d) != #fd's(%d) in %s\n",
211
                       kdevname(tty->device), tty->count, count, routine);
212
                return count;
213
       }
214
#endif
215
        return 0;
216
}
217
 
218
int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
219
{
220
        if (disc < N_TTY || disc >= NR_LDISCS)
221
                return -EINVAL;
222
 
223
        if (new_ldisc) {
224
                ldiscs[disc] = *new_ldisc;
225
                ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
226
                ldiscs[disc].num = disc;
227
        } else
228
                memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
229
 
230
        return 0;
231
}
232
 
233
/* Set the discipline of a tty line. */
234
static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
235
{
236
        int     retval = 0;
237
        struct  tty_ldisc o_ldisc;
238
 
239
        if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
240
                return -EINVAL;
241
#ifdef CONFIG_KERNELD
242
        /* Eduardo Blanco <ejbs@cs.cs.com.uy> */
243
        if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) {
244
                char modname [20];
245
                sprintf(modname, "tty-ldisc-%d", ldisc);
246
                request_module (modname);
247
        }
248
#endif
249
        if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED))
250
                return -EINVAL;
251
 
252
        if (tty->ldisc.num == ldisc)
253
                return 0;        /* We are already in the desired discipline */
254
        o_ldisc = tty->ldisc;
255
 
256
        tty_wait_until_sent(tty, 0);
257
 
258
        /* Shutdown the current discipline. */
259
        if (tty->ldisc.close)
260
                (tty->ldisc.close)(tty);
261
 
262
        /* Now set up the new line discipline. */
263
        tty->ldisc = ldiscs[ldisc];
264
        tty->termios->c_line = ldisc;
265
        if (tty->ldisc.open)
266
                retval = (tty->ldisc.open)(tty);
267
        if (retval < 0) {
268
                tty->ldisc = o_ldisc;
269
                tty->termios->c_line = tty->ldisc.num;
270
                if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
271
                        tty->ldisc = ldiscs[N_TTY];
272
                        tty->termios->c_line = N_TTY;
273
                        if (tty->ldisc.open) {
274
                                int r = tty->ldisc.open(tty);
275
 
276
                                if (r < 0)
277
                                        panic("Couldn't open N_TTY ldisc for "
278
                                              "%s --- error %d.",
279
                                              tty_name(tty), r);
280
                        }
281
                }
282
        }
283
        if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc)
284
                tty->driver.set_ldisc(tty);
285
        return retval;
286
}
287
 
288
/*
289
 * This routine returns a tty driver structure, given a device number
290
 */
291
struct tty_driver *get_tty_driver(kdev_t device)
292
{
293
        int     major, minor;
294
        struct tty_driver *p;
295
 
296
        minor = MINOR(device);
297
        major = MAJOR(device);
298
 
299
        for (p = tty_drivers; p; p = p->next) {
300
                if (p->major != major)
301
                        continue;
302
                if (minor < p->minor_start)
303
                        continue;
304
                if (minor >= p->minor_start + p->num)
305
                        continue;
306
                return p;
307
        }
308
        return NULL;
309
}
310
 
311
/*
312
 * If we try to write to, or set the state of, a terminal and we're
313
 * not in the foreground, send a SIGTTOU.  If the signal is blocked or
314
 * ignored, go ahead and perform the operation.  (POSIX 7.2)
315
 */
316
int tty_check_change(struct tty_struct * tty)
317
{
318
        if (current->tty != tty)
319
                return 0;
320
        if (tty->pgrp <= 0) {
321
                printk("tty_check_change: tty->pgrp <= 0!\n");
322
                return 0;
323
        }
324
        if (current->pgrp == tty->pgrp)
325
                return 0;
326
        if (is_ignored(SIGTTOU))
327
                return 0;
328
        if (is_orphaned_pgrp(current->pgrp))
329
                return -EIO;
330
        (void) kill_pg(current->pgrp,SIGTTOU,1);
331
        return -ERESTARTSYS;
332
}
333
 
334
static int hung_up_tty_read(struct inode * inode, struct file * file, char * buf, int count)
335
{
336
        return 0;
337
}
338
 
339
static int hung_up_tty_write(struct inode * inode, struct file * file, const char * buf, int count)
340
{
341
        return -EIO;
342
}
343
 
344
static int hung_up_tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
345
{
346
        return 1;
347
}
348
 
349
static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
350
                             unsigned int cmd, unsigned long arg)
351
{
352
        return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
353
}
354
 
355
static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
356
{
357
        return -ESPIPE;
358
}
359
 
360
static struct file_operations tty_fops = {
361
        tty_lseek,
362
        tty_read,
363
        tty_write,
364
        NULL,           /* tty_readdir */
365
        tty_select,
366
        tty_ioctl,
367
        NULL,           /* tty_mmap */
368
        tty_open,
369
        tty_release,
370
        NULL,           /* tty_fsync */
371
        tty_fasync
372
};
373
 
374
static struct file_operations hung_up_tty_fops = {
375
        tty_lseek,
376
        hung_up_tty_read,
377
        hung_up_tty_write,
378
        NULL,           /* hung_up_tty_readdir */
379
        hung_up_tty_select,
380
        hung_up_tty_ioctl,
381
        NULL,           /* hung_up_tty_mmap */
382
        NULL,           /* hung_up_tty_open */
383
        tty_release,    /* hung_up_tty_release */
384
        NULL,           /* hung_up_tty_fsync  */
385
        NULL            /* hung_up_tty_fasync */
386
};
387
 
388
void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
389
{
390
        int i;
391
        struct file * filp;
392
        struct task_struct *p;
393
 
394
        if (!tty)
395
                return;
396
        check_tty_count(tty, "do_tty_hangup");
397
        for (filp = first_file, i=0; i<nr_files; i++, filp = filp->f_next) {
398
                if (!filp->f_count)
399
                        continue;
400
                if (filp->private_data != tty)
401
                        continue;
402
                if (!filp->f_inode)
403
                        continue;
404
                if (filp->f_inode->i_rdev == CONSOLE_DEV)
405
                        continue;
406
                if (filp->f_op != &tty_fops)
407
                        continue;
408
                tty_fasync(filp->f_inode, filp, 0);
409
                filp->f_op = fops;
410
        }
411
 
412
        if (tty->ldisc.flush_buffer)
413
                tty->ldisc.flush_buffer(tty);
414
        if (tty->driver.flush_buffer)
415
                tty->driver.flush_buffer(tty);
416
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
417
            tty->ldisc.write_wakeup)
418
                (tty->ldisc.write_wakeup)(tty);
419
        wake_up_interruptible(&tty->write_wait);
420
        wake_up_interruptible(&tty->read_wait);
421
 
422
        /*
423
         * Shutdown the current line discipline, and reset it to
424
         * N_TTY.
425
         */
426
        if (tty->ldisc.num != ldiscs[N_TTY].num) {
427
                if (tty->ldisc.close)
428
                        (tty->ldisc.close)(tty);
429
                tty->ldisc = ldiscs[N_TTY];
430
                tty->termios->c_line = N_TTY;
431
                if (tty->ldisc.open) {
432
                        i = (tty->ldisc.open)(tty);
433
                        if (i < 0)
434
                                printk("do_tty_hangup: N_TTY open: error %d\n",
435
                                       -i);
436
                }
437
        }
438
 
439
        for_each_task(p) {
440
                if ((tty->session > 0) && (p->session == tty->session) &&
441
                    p->leader) {
442
                        send_sig(SIGHUP,p,1);
443
                        send_sig(SIGCONT,p,1);
444
                        if (tty->pgrp > 0)
445
                                p->tty_old_pgrp = tty->pgrp;
446
                }
447
                if (p->tty == tty)
448
                        p->tty = NULL;
449
        }
450
        tty->flags = 0;
451
        tty->session = 0;
452
        tty->pgrp = -1;
453
        tty->ctrl_status = 0;
454
        if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS)
455
                *tty->termios = tty->driver.init_termios;
456
        if (tty->driver.hangup)
457
                (tty->driver.hangup)(tty);
458
}
459
 
460
void tty_hangup(struct tty_struct * tty)
461
{
462
#ifdef TTY_DEBUG_HANGUP
463
        printk("%s hangup...\n", tty_name(tty));
464
#endif
465
        do_tty_hangup(tty, &hung_up_tty_fops);
466
}
467
 
468
void tty_vhangup(struct tty_struct * tty)
469
{
470
#ifdef TTY_DEBUG_HANGUP
471
        printk("%s vhangup...\n", tty_name(tty));
472
#endif
473
        do_tty_hangup(tty, &hung_up_tty_fops);
474
}
475
 
476
int tty_hung_up_p(struct file * filp)
477
{
478
        return (filp->f_op == &hung_up_tty_fops);
479
}
480
 
481
/*
482
 * This function is typically called only by the session leader, when
483
 * it wants to disassociate itself from its controlling tty.
484
 *
485
 * It performs the following functions:
486
 *      (1)  Sends a SIGHUP and SIGCONT to the foreground process group
487
 *      (2)  Clears the tty from being controlling the session
488
 *      (3)  Clears the controlling tty for all processes in the
489
 *              session group.
490
 *
491
 * The argument on_exit is set to 1 if called when a process is
492
 * exiting; it is 0 if called by the ioctl TIOCNOTTY.
493
 */
494
void disassociate_ctty(int on_exit)
495
{
496
        struct tty_struct *tty = current->tty;
497
        struct task_struct *p;
498
        int tty_pgrp = -1;
499
 
500
        if (tty) {
501
                tty_pgrp = tty->pgrp;
502
                if (on_exit && tty->driver.type != TTY_DRIVER_TYPE_PTY)
503
                        tty_vhangup(tty);
504
        } else {
505
                if (current->tty_old_pgrp) {
506
                        kill_pg(current->tty_old_pgrp, SIGHUP, on_exit);
507
                        kill_pg(current->tty_old_pgrp, SIGCONT, on_exit);
508
                }
509
                return;
510
        }
511
        if (tty_pgrp > 0) {
512
                kill_pg(tty_pgrp, SIGHUP, on_exit);
513
                if (!on_exit)
514
                        kill_pg(tty_pgrp, SIGCONT, on_exit);
515
        }
516
 
517
        current->tty_old_pgrp = 0;
518
        tty->session = 0;
519
        tty->pgrp = -1;
520
 
521
        for_each_task(p)
522
                if (p->session == current->session)
523
                        p->tty = NULL;
524
}
525
 
526
void wait_for_keypress(void)
527
{
528
        sleep_on(&keypress_wait);
529
}
530
 
531
void stop_tty(struct tty_struct *tty)
532
{
533
        if (tty->stopped)
534
                return;
535
        tty->stopped = 1;
536
        if (tty->link && tty->link->packet) {
537
                tty->ctrl_status &= ~TIOCPKT_START;
538
                tty->ctrl_status |= TIOCPKT_STOP;
539
                wake_up_interruptible(&tty->link->read_wait);
540
        }
541
        if (tty->driver.stop)
542
                (tty->driver.stop)(tty);
543
}
544
 
545
void start_tty(struct tty_struct *tty)
546
{
547
        if (!tty->stopped)
548
                return;
549
        tty->stopped = 0;
550
        if (tty->link && tty->link->packet) {
551
                tty->ctrl_status &= ~TIOCPKT_STOP;
552
                tty->ctrl_status |= TIOCPKT_START;
553
                wake_up_interruptible(&tty->link->read_wait);
554
        }
555
        if (tty->driver.start)
556
                (tty->driver.start)(tty);
557
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
558
            tty->ldisc.write_wakeup)
559
                (tty->ldisc.write_wakeup)(tty);
560
        wake_up_interruptible(&tty->write_wait);
561
}
562
 
563
static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
564
{
565
        int i;
566
        struct tty_struct * tty;
567
 
568
        tty = (struct tty_struct *)file->private_data;
569
        if (tty_paranoia_check(tty, inode->i_rdev, "tty_read"))
570
                return -EIO;
571
        if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
572
                return -EIO;
573
 
574
        /* This check not only needs to be done before reading, but also
575
           whenever read_chan() gets woken up after sleeping, so I've
576
           moved it to there.  This should only be done for the N_TTY
577
           line discipline, anyway.  Same goes for write_chan(). -- jlc. */
578
#if 0
579
        if ((inode->i_rdev != CONSOLE_DEV) && /* don't stop on /dev/console */
580
            (tty->pgrp > 0) &&
581
            (current->tty == tty) &&
582
            (tty->pgrp != current->pgrp))
583
                if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
584
                        return -EIO;
585
                else {
586
                        (void) kill_pg(current->pgrp, SIGTTIN, 1);
587
                        return -ERESTARTSYS;
588
                }
589
#endif
590
        if (tty->ldisc.read)
591
                /* XXX casts are for what kernel-wide prototypes should be. */
592
                i = (tty->ldisc.read)(tty,file,(unsigned char *)buf,(unsigned int)count);
593
        else
594
                i = -EIO;
595
        if (i > 0)
596
                inode->i_atime = CURRENT_TIME;
597
        return i;
598
}
599
 
600
/*
601
 * Split writes up in sane blocksizes to avoid
602
 * denial-of-service type attacks
603
 */
604
static inline int do_tty_write(
605
        int (*write)(struct tty_struct *, struct file *, const unsigned char *, unsigned int),
606
        struct inode *inode,
607
        struct tty_struct *tty,
608
        struct file *file,
609
        const unsigned char *buf,
610
        unsigned int count)
611
{
612
        int ret = 0, written = 0;
613
 
614
        for (;;) {
615
                /* why should this depend on the page size? (PAGE_SIZE*2) */
616
                unsigned int size = 8192;
617
                if (size > count)
618
                        size = count;
619
                ret = write(tty, file, buf, size);
620
                if (ret <= 0)
621
                        break;
622
                written += ret;
623
                buf += ret;
624
                count -= ret;
625
                if (!count)
626
                        break;
627
                ret = -ERESTARTSYS;
628
                if (current->signal & ~current->blocked)
629
                        break;
630
                if (need_resched)
631
                        schedule();
632
        }
633
        if (written) {
634
                inode->i_mtime = CURRENT_TIME;
635
                ret = written;
636
        }
637
        return ret;
638
}
639
 
640
 
641
static int tty_write(struct inode * inode, struct file * file, const char * buf, int count)
642
{
643
        int is_console;
644
        struct tty_struct * tty;
645
 
646
        is_console = (inode->i_rdev == CONSOLE_DEV);
647
 
648
        if (is_console && redirect)
649
                tty = redirect;
650
        else
651
                tty = (struct tty_struct *)file->private_data;
652
        if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
653
                return -EIO;
654
        if (!tty || !tty->driver.write || (tty->flags & (1 << TTY_IO_ERROR)))
655
                return -EIO;
656
#if 0
657
        if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
658
            (current->tty == tty) && (tty->pgrp != current->pgrp)) {
659
                if (is_orphaned_pgrp(current->pgrp))
660
                        return -EIO;
661
                if (!is_ignored(SIGTTOU)) {
662
                        (void) kill_pg(current->pgrp, SIGTTOU, 1);
663
                        return -ERESTARTSYS;
664
                }
665
        }
666
#endif
667
        if (!tty->ldisc.write)
668
                return -EIO;
669
        return do_tty_write(tty->ldisc.write,
670
                inode, tty, file,
671
                (const unsigned char *)buf,
672
                (unsigned int)count);
673
}
674
 
675
/* Semaphore to protect creating and releasing a tty */
676
static struct semaphore tty_sem = MUTEX;
677
static void down_tty_sem(int index)
678
{
679
        down(&tty_sem);
680
}
681
static void up_tty_sem(int index)
682
{
683
        up(&tty_sem);
684
}
685
static void release_mem(struct tty_struct *tty, int idx);
686
 
687
/*
688
 * Rewritten to remove races and properly clean up after a failed open.
689
 * The new code protects the open with a semaphore, so it's really
690
 * quite straightforward.  The semaphore locking can probably be
691
 * relaxed for the (most common) case of reopening a tty.
692
 */
693
static int init_dev(kdev_t device, struct tty_struct **ret_tty)
694
{
695
        struct tty_struct *tty, *o_tty;
696
        struct termios *tp, **tp_loc, *o_tp, **o_tp_loc;
697
        struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
698
        struct tty_driver *driver;
699
        int retval;
700
        int idx;
701
 
702
        driver = get_tty_driver(device);
703
        if (!driver)
704
                return -ENODEV;
705
 
706
        idx = MINOR(device) - driver->minor_start;
707
 
708
        /*
709
         * Check whether we need to acquire the tty semaphore to avoid
710
         * race conditions.  For now, play it safe.
711
         */
712
        down_tty_sem(idx);
713
 
714
        /* check whether we're reopening an existing tty */
715
        tty = driver->table[idx];
716
        if(tty) goto fast_track;
717
 
718
        /*
719
         * First time open is complex, especially for PTY devices.
720
         * This code guarantees that either everything succeeds and the
721
         * TTY is ready for operation, or else the table slots are vacated
722
         * and the allocated memory released.  (Except that the termios
723
         * and locked termios may be retained.)
724
         */
725
 
726
        o_tty = NULL;
727
        tp = o_tp = NULL;
728
        ltp = o_ltp = NULL;
729
 
730
        tty = alloc_tty_struct (GFP_KERNEL);
731
        if(!tty)
732
                goto fail_no_mem;
733
        initialize_tty_struct(tty);
734
        tty->device = device;
735
        tty->driver = *driver;
736
 
737
        tp_loc = &driver->termios[idx];
738
        if (!*tp_loc) {
739
                tp = (struct termios *) kmalloc(sizeof(struct termios),
740
                                                GFP_KERNEL);
741
                if (!tp)
742
                        goto free_mem_out;
743
                *tp = driver->init_termios;
744
        }
745
 
746
        ltp_loc = &driver->termios_locked[idx];
747
        if (!*ltp_loc) {
748
                ltp = (struct termios *) kmalloc(sizeof(struct termios),
749
                                                 GFP_KERNEL);
750
                if (!ltp)
751
                        goto free_mem_out;
752
                memset(ltp, 0, sizeof(struct termios));
753
        }
754
 
755
        if (driver->type == TTY_DRIVER_TYPE_PTY) {
756
                o_tty = alloc_tty_struct (GFP_KERNEL);
757
                if (!o_tty)
758
                        goto free_mem_out;
759
                initialize_tty_struct(o_tty);
760
                o_tty->device = (kdev_t) MKDEV(driver->other->major,
761
                                        driver->other->minor_start + idx);
762
                o_tty->driver = *driver->other;
763
 
764
                o_tp_loc  = &driver->other->termios[idx];
765
                if (!*o_tp_loc) {
766
                        o_tp = (struct termios *)
767
                                kmalloc(sizeof(struct termios), GFP_KERNEL);
768
                        if (!o_tp)
769
                                goto free_mem_out;
770
                        *o_tp = driver->other->init_termios;
771
                }
772
 
773
                o_ltp_loc = &driver->other->termios_locked[idx];
774
                if (!*o_ltp_loc) {
775
                        o_ltp = (struct termios *)
776
                                kmalloc(sizeof(struct termios), GFP_KERNEL);
777
                        if (!o_ltp)
778
                                goto free_mem_out;
779
                        memset(o_ltp, 0, sizeof(struct termios));
780
                }
781
 
782
                /*
783
                 * Everything allocated ... set up the o_tty structure.
784
                 */
785
                driver->other->table[idx] = o_tty;
786
                if (!*o_tp_loc)
787
                        *o_tp_loc = o_tp;
788
                if (!*o_ltp_loc)
789
                        *o_ltp_loc = o_ltp;
790
                o_tty->termios = *o_tp_loc;
791
                o_tty->termios_locked = *o_ltp_loc;
792
                (*driver->other->refcount)++;
793
                if (driver->subtype == PTY_TYPE_MASTER)
794
                        o_tty->count++;
795
 
796
                /* Establish the links in both directions */
797
                tty->link   = o_tty;
798
                o_tty->link = tty;
799
        }
800
 
801
        /*
802
         * All structures have been allocated, so now we install them.
803
         * Failures after this point use release_mem to clean up, so
804
         * there's no need to null out the local pointers.
805
         */
806
        driver->table[idx] = tty;
807
        if (!*tp_loc)
808
                *tp_loc = tp;
809
        if (!*ltp_loc)
810
                *ltp_loc = ltp;
811
        tty->termios = *tp_loc;
812
        tty->termios_locked = *ltp_loc;
813
        (*driver->refcount)++;
814
        tty->count++;
815
 
816
        /*
817
         * Structures all installed ... call the ldisc open routines.
818
         * If we fail here just call release_mem to clean up.  No need
819
         * to decrement the use counts, as release_mem doesn't care.
820
         */
821
        if (tty->ldisc.open) {
822
                retval = (tty->ldisc.open)(tty);
823
                if (retval)
824
                        goto release_mem_out;
825
        }
826
        if (o_tty && o_tty->ldisc.open) {
827
                retval = (o_tty->ldisc.open)(o_tty);
828
                if (retval) {
829
                        if (tty->ldisc.close)
830
                                (tty->ldisc.close)(tty);
831
                        goto release_mem_out;
832
                }
833
        }
834
        goto success;
835
 
836
        /*
837
         * This fast open can be used if the tty is already open.
838
         * No memory is allocated, and the only failures are from
839
         * attempting to open a closing tty or attempting multiple
840
         * opens on a pty master.
841
         */
842
fast_track:
843
        retval = -EIO;
844
        if (test_bit(TTY_CLOSING, &tty->flags))
845
                goto end_init;
846
 
847
        if (driver->type == TTY_DRIVER_TYPE_PTY &&
848
            driver->subtype == PTY_TYPE_MASTER) {
849
                /*
850
                 * special case for PTY masters: only one open permitted,
851
                 * and the slave side open count is incremented as well.
852
                 */
853
                if (tty->count)
854
                        goto end_init;
855
                tty->link->count++;
856
        }
857
        tty->count++;
858
        tty->driver = *driver; /* N.B. why do this every time?? */
859
 
860
success:
861
        retval = 0;
862
        *ret_tty = tty;
863
 
864
        /* All paths come through here to release the semaphore */
865
end_init:
866
        up_tty_sem(idx);
867
        return retval;
868
 
869
        /* Release locally allocated memory ... nothing placed in slots */
870
free_mem_out:
871
        if (o_tp)
872
                kfree_s(o_tp, sizeof(struct termios));
873
        if (o_tty)
874
                free_tty_struct(o_tty);
875
        if (ltp)
876
                kfree_s(ltp, sizeof(struct termios));
877
        if (tp)
878
                kfree_s(tp, sizeof(struct termios));
879
        free_tty_struct(tty);
880
 
881
fail_no_mem:
882
        retval = -ENOMEM;
883
        goto end_init;
884
 
885
        /* call the tty release_mem routine to clean out this slot */
886
release_mem_out:
887
        printk("init_dev: ldisc open failed, clearing slot %d\n", idx);
888
        release_mem(tty, idx);
889
        goto end_init;
890
}
891
 
892
/*
893
 * Releases memory associated with a tty structure, and clears out the
894
 * driver table slots.
895
 */
896
static void release_mem(struct tty_struct *tty, int idx)
897
{
898
        struct tty_struct *o_tty;
899
        struct termios *tp;
900
 
901
        if ((o_tty = tty->link) != NULL) {
902
                o_tty->driver.table[idx] = NULL;
903
                if (o_tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) {
904
                        tp = o_tty->driver.termios[idx];
905
                        o_tty->driver.termios[idx] = NULL;
906
                        kfree_s(tp, sizeof(struct termios));
907
                }
908
                o_tty->magic = 0;
909
                (*o_tty->driver.refcount)--;
910
                free_tty_struct(o_tty);
911
        }
912
 
913
        tty->driver.table[idx] = NULL;
914
        if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) {
915
                tp = tty->driver.termios[idx];
916
                tty->driver.termios[idx] = NULL;
917
                kfree_s(tp, sizeof(struct termios));
918
        }
919
        tty->magic = 0;
920
        (*tty->driver.refcount)--;
921
        free_tty_struct(tty);
922
}
923
 
924
/*
925
 * Even releasing the tty structures is a tricky business.. We have
926
 * to be very careful that the structures are all released at the
927
 * same time, as interrupts might otherwise get the wrong pointers.
928
 */
929
static void release_dev(struct file * filp)
930
{
931
        struct tty_struct *tty, *o_tty;
932
        int     pty_master, tty_closing, o_tty_closing, do_sleep;
933
        int     idx;
934
 
935
        tty = (struct tty_struct *)filp->private_data;
936
        if (tty_paranoia_check(tty, filp->f_inode->i_rdev, "release_dev"))
937
                return;
938
 
939
        check_tty_count(tty, "release_dev");
940
 
941
        tty_fasync(filp->f_inode, filp, 0);
942
 
943
        idx = MINOR(tty->device) - tty->driver.minor_start;
944
        pty_master = (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
945
                      tty->driver.subtype == PTY_TYPE_MASTER);
946
        o_tty = tty->link;
947
 
948
#ifdef TTY_PARANOIA_CHECK
949
        if (idx < 0 || idx >= tty->driver.num) {
950
                printk("release_dev: bad idx when trying to free (%s)\n",
951
                       kdevname(tty->device));
952
                return;
953
        }
954
        if (tty != tty->driver.table[idx]) {
955
                printk("release_dev: driver.table[%d] not tty for (%s)\n",
956
                       idx, kdevname(tty->device));
957
                return;
958
        }
959
        if (tty->termios != tty->driver.termios[idx]) {
960
                printk("release_dev: driver.termios[%d] not termios "
961
                       "for (%s)\n",
962
                       idx, kdevname(tty->device));
963
                return;
964
        }
965
        if (tty->termios_locked != tty->driver.termios_locked[idx]) {
966
                printk("release_dev: driver.termios_locked[%d] not "
967
                       "termios_locked for (%s)\n",
968
                       idx, kdevname(tty->device));
969
                return;
970
        }
971
#endif
972
 
973
#ifdef TTY_DEBUG_HANGUP
974
        printk("release_dev of %s (tty count=%d)...", tty_name(tty),
975
               tty->count);
976
#endif
977
 
978
#ifdef TTY_PARANOIA_CHECK
979
        if (tty->driver.other) {
980
                if (o_tty != tty->driver.other->table[idx]) {
981
                        printk("release_dev: other->table[%d] not o_tty for ("
982
                               "%s)\n",
983
                               idx, kdevname(tty->device));
984
                        return;
985
                }
986
                if (o_tty->termios != tty->driver.other->termios[idx]) {
987
                        printk("release_dev: other->termios[%d] not o_termios "
988
                               "for (%s)\n",
989
                               idx, kdevname(tty->device));
990
                        return;
991
                }
992
                if (o_tty->termios_locked !=
993
                      tty->driver.other->termios_locked[idx]) {
994
                        printk("release_dev: other->termios_locked[%d] not "
995
                               "o_termios_locked for (%s)\n",
996
                               idx, kdevname(tty->device));
997
                        return;
998
                }
999
                if (o_tty->link != tty) {
1000
                        printk("release_dev: bad pty pointers\n");
1001
                        return;
1002
                }
1003
        }
1004
#endif
1005
 
1006
        if (tty->driver.close)
1007
                tty->driver.close(tty, filp);
1008
 
1009
        /*
1010
         * Sanity check: if tty->count is going to zero, there shouldn't be
1011
         * any waiters on tty->read_wait or tty->write_wait.  We test the
1012
         * wait queues and kick everyone out _before_ actually starting to
1013
         * close.  This ensures that we won't block while releasing the tty
1014
         * structure.
1015
         *
1016
         * The test for the o_tty closing is necessary, since the master and
1017
         * slave sides may close in any order.  If the slave side closes out
1018
         * first, its count will be one, since the master side holds an open.
1019
         * Thus this test wouldn't be triggered at the time the slave closes,
1020
         * so we do it now.
1021
         *
1022
         * Note that it's possible for the tty to be opened again while we're
1023
         * flushing out waiters.  By recalculating the closing flags before
1024
         * each iteration we avoid any problems.
1025
         */
1026
        while (1) {
1027
                tty_closing = tty->count <= 1;
1028
                o_tty_closing = o_tty &&
1029
                        (o_tty->count <= (pty_master ? 1 : 0));
1030
                do_sleep = 0;
1031
 
1032
                if (tty_closing) {
1033
                        if (waitqueue_active(&tty->read_wait)) {
1034
                                wake_up(&tty->read_wait);
1035
                                do_sleep++;
1036
                        }
1037
                        if (waitqueue_active(&tty->write_wait)) {
1038
                                wake_up(&tty->write_wait);
1039
                                do_sleep++;
1040
                        }
1041
                }
1042
                if (o_tty_closing) {
1043
                        if (waitqueue_active(&o_tty->read_wait)) {
1044
                                wake_up(&o_tty->read_wait);
1045
                                do_sleep++;
1046
                        }
1047
                        if (waitqueue_active(&o_tty->write_wait)) {
1048
                                wake_up(&o_tty->write_wait);
1049
                                do_sleep++;
1050
                        }
1051
                }
1052
                if (!do_sleep)
1053
                        break;
1054
 
1055
                printk("release_dev: %s: read/write wait queue active!\n",
1056
                       tty_name(tty));
1057
                schedule();
1058
        }
1059
 
1060
        /*
1061
         * The closing flags are now consistent with the open counts on
1062
         * both sides, and we've completed the last operation that could
1063
         * block, so it's safe to proceed with closing.
1064
         */
1065
 
1066
        if (pty_master) {
1067
                if (--o_tty->count < 0) {
1068
                        printk("release_dev: bad pty slave count (%d) for %s\n",
1069
                               o_tty->count, tty_name(o_tty));
1070
                        o_tty->count = 0;
1071
                }
1072
        }
1073
        if (--tty->count < 0) {
1074
                printk("release_dev: bad tty->count (%d) for %s\n",
1075
                       tty->count, tty_name(tty));
1076
                tty->count = 0;
1077
        }
1078
 
1079
        /*
1080
         * Perform some housekeeping before deciding whether to return.
1081
         *
1082
         * Set the TTY_CLOSING flag if this was the last open.  In the
1083
         * case of a pty we may have to wait around for the other side
1084
         * to close, and TTY_CLOSING makes sure we can't be reopened.
1085
         */
1086
        if(tty_closing)
1087
                set_bit(TTY_CLOSING, &tty->flags);
1088
        if(o_tty_closing)
1089
                set_bit(TTY_CLOSING, &o_tty->flags);
1090
 
1091
        /*
1092
         * If _either_ side is closing, make sure there aren't any
1093
         * processes that still think tty or o_tty is their controlling
1094
         * tty.  Also, clear redirect if it points to either tty.
1095
         */
1096
        if (tty_closing || o_tty_closing) {
1097
                struct task_struct *p;
1098
 
1099
                for_each_task(p) {
1100
                        if (p->tty == tty || (o_tty && p->tty == o_tty))
1101
                                p->tty = NULL;
1102
                }
1103
 
1104
                if (redirect == tty || (o_tty && redirect == o_tty))
1105
                        redirect = NULL;
1106
        }
1107
 
1108
        /* check whether both sides are closing ... */
1109
        if (!tty_closing || (o_tty && !o_tty_closing))
1110
                return;
1111
        filp->private_data = 0;
1112
 
1113
#ifdef TTY_DEBUG_HANGUP
1114
        printk("freeing tty structure...");
1115
#endif
1116
 
1117
        /*
1118
         * Shutdown the current line discipline, and reset it to N_TTY.
1119
         * N.B. why reset ldisc when we're releasing the memory??
1120
         */
1121
        if (tty->ldisc.close)
1122
                (tty->ldisc.close)(tty);
1123
        tty->ldisc = ldiscs[N_TTY];
1124
        tty->termios->c_line = N_TTY;
1125
        if (o_tty) {
1126
                if (o_tty->ldisc.close)
1127
                        (o_tty->ldisc.close)(o_tty);
1128
                o_tty->ldisc = ldiscs[N_TTY];
1129
        }
1130
 
1131
        /*
1132
         * Make sure that the tty's task queue isn't activated.  If it
1133
         * is, take it out of the linked list.  The tqueue isn't used by
1134
         * pty's, so skip the test for them.
1135
         */
1136
        if (tty->driver.type != TTY_DRIVER_TYPE_PTY) {
1137
                cli();
1138
                if (tty->flip.tqueue.sync) {
1139
                        struct tq_struct *tq, *prev;
1140
 
1141
                        for (tq=tq_timer, prev=0; tq; prev=tq, tq=tq->next) {
1142
                                if (tq == &tty->flip.tqueue) {
1143
                                        if (prev)
1144
                                                prev->next = tq->next;
1145
                                        else
1146
                                                tq_timer = tq->next;
1147
                                        break;
1148
                                }
1149
                        }
1150
                }
1151
                sti();
1152
        }
1153
 
1154
        /*
1155
         * The release_mem function takes care of the details of clearing
1156
         * the slots and preserving the termios structure.
1157
         */
1158
        release_mem(tty, idx);
1159
}
1160
 
1161
/*
1162
 * tty_open and tty_release keep up the tty count that contains the
1163
 * number of opens done on a tty. We cannot use the inode-count, as
1164
 * different inodes might point to the same tty.
1165
 *
1166
 * Open-counting is needed for pty masters, as well as for keeping
1167
 * track of serial lines: DTR is dropped when the last close happens.
1168
 * (This is not done solely through tty->count, now.  - Ted 1/27/92)
1169
 *
1170
 * The termios state of a pty is reset on first open so that
1171
 * settings don't persist across reuse.
1172
 */
1173
static int tty_open(struct inode * inode, struct file * filp)
1174
{
1175
        struct tty_struct *tty;
1176
        int minor;
1177
        int noctty, retval;
1178
        kdev_t device;
1179
 
1180
retry_open:
1181
        noctty = filp->f_flags & O_NOCTTY;
1182
        device = inode->i_rdev;
1183
        if (device == TTY_DEV) {
1184
                if (!current->tty)
1185
                        return -ENXIO;
1186
                device = current->tty->device;
1187
                /* noctty = 1; */
1188
        }
1189
        if (device == CONSOLE_DEV) {
1190
                device = MKDEV(TTY_MAJOR, vtdata.fgconsole->num);
1191
                noctty = 1;
1192
        }
1193
        minor = MINOR(device);
1194
 
1195
        retval = init_dev(device, &tty);
1196
        if (retval)
1197
                return retval;
1198
        filp->private_data = tty;
1199
        check_tty_count(tty, "tty_open");
1200
        if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1201
            tty->driver.subtype == PTY_TYPE_MASTER)
1202
                noctty = 1;
1203
#ifdef TTY_DEBUG_HANGUP
1204
        printk("opening %s...", tty_name(tty));
1205
#endif
1206
        if (tty->driver.open)
1207
                retval = tty->driver.open(tty, filp);
1208
        else
1209
                retval = -ENODEV;
1210
 
1211
        if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
1212
                retval = -EBUSY;
1213
 
1214
        if (retval) {
1215
#ifdef TTY_DEBUG_HANGUP
1216
                printk("error %d in opening %s...", retval, tty_name(tty));
1217
#endif
1218
 
1219
                release_dev(filp);
1220
                if (retval != -ERESTARTSYS)
1221
                        return retval;
1222
                if (current->signal & ~current->blocked)
1223
                        return retval;
1224
                schedule();
1225
                /*
1226
                 * Need to reset f_op in case a hangup happened.
1227
                 */
1228
                filp->f_op = &tty_fops;
1229
                goto retry_open;
1230
        }
1231
        if (!noctty &&
1232
            current->leader &&
1233
            !current->tty &&
1234
            tty->session == 0) {
1235
                current->tty = tty;
1236
                current->tty_old_pgrp = 0;
1237
                tty->session = current->session;
1238
                tty->pgrp = current->pgrp;
1239
        }
1240
        return 0;
1241
}
1242
 
1243
static void tty_release(struct inode * inode, struct file * filp)
1244
{
1245
        release_dev(filp);
1246
}
1247
 
1248
static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
1249
{
1250
        struct tty_struct * tty;
1251
 
1252
        tty = (struct tty_struct *)filp->private_data;
1253
        if (tty_paranoia_check(tty, inode->i_rdev, "tty_select"))
1254
                return 0;
1255
 
1256
        if (tty->ldisc.select)
1257
                return (tty->ldisc.select)(tty, inode, filp, sel_type, wait);
1258
        return 0;
1259
}
1260
 
1261
/*
1262
 * fasync_helper() is used by some character device drivers (mainly mice)
1263
 * to set up the fasync queue. It returns negative on error, 0 if it did
1264
 * no changes and positive if it added/deleted the entry.
1265
 */
1266
int fasync_helper(struct inode * inode, struct file * filp, int on, struct fasync_struct **fapp)
1267
{
1268
        struct fasync_struct *fa, **fp;
1269
        unsigned long flags;
1270
 
1271
        for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
1272
                if (fa->fa_file == filp)
1273
                        break;
1274
        }
1275
 
1276
        if (on) {
1277
                if (fa)
1278
                        return 0;
1279
                fa = (struct fasync_struct *)kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
1280
                if (!fa)
1281
                        return -ENOMEM;
1282
                fa->magic = FASYNC_MAGIC;
1283
                fa->fa_file = filp;
1284
                save_flags_cli (flags);
1285
                fa->fa_next = *fapp;
1286
                *fapp = fa;
1287
                restore_flags(flags);
1288
                return 1;
1289
        }
1290
        if (!fa)
1291
                return 0;
1292
        save_flags_cli (flags);
1293
        *fp = fa->fa_next;
1294
        restore_flags(flags);
1295
        kfree(fa);
1296
        return 1;
1297
}
1298
 
1299
static int tty_fasync(struct inode * inode, struct file * filp, int on)
1300
{
1301
        struct tty_struct * tty;
1302
        int retval;
1303
 
1304
        tty = (struct tty_struct *)filp->private_data;
1305
        if (tty_paranoia_check(tty, inode->i_rdev, "tty_fasync"))
1306
                return 0;
1307
 
1308
        retval = fasync_helper(inode, filp, on, &tty->fasync);
1309
        if (retval <= 0)
1310
                return retval;
1311
 
1312
        if (on) {
1313
                if (!waitqueue_active(&tty->read_wait))
1314
                        tty->minimum_to_wake = 1;
1315
                if (filp->f_owner.pid == 0) {
1316
                        filp->f_owner.pid = (-tty->pgrp) ? : current->pid;
1317
                        filp->f_owner.uid = current->uid;
1318
                        filp->f_owner.euid = current->euid;
1319
                }
1320
        } else {
1321
                if (!tty->fasync && !waitqueue_active(&tty->read_wait))
1322
                        tty->minimum_to_wake = N_TTY_BUF_SIZE;
1323
        }
1324
        return 0;
1325
}
1326
 
1327
#if 0
1328
/*
1329
 * XXX does anyone use this anymore?!?
1330
 */
1331
static int do_get_ps_info(unsigned long arg)
1332
{
1333
        struct tstruct {
1334
                int flag;
1335
                int present[NR_TASKS];
1336
                struct task_struct tasks[NR_TASKS];
1337
        };
1338
        struct tstruct *ts = (struct tstruct *)arg;
1339
        struct task_struct **p;
1340
        char *c, *d;
1341
        int i, n = 0;
1342
 
1343
        i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct tstruct));
1344
        if (i)
1345
                return i;
1346
        for (p = &FIRST_TASK ; p <= &LAST_TASK ; p++, n++)
1347
                if (*p)
1348
                {
1349
                        c = (char *)(*p);
1350
                        d = (char *)(ts->tasks+n);
1351
                        for (i=0 ; i<sizeof(struct task_struct) ; i++)
1352
                                put_user(*c++, d++);
1353
                        put_user(1, ts->present+n);
1354
                }
1355
                else
1356
                        put_user(0, ts->present+n);
1357
        return(0);
1358
}
1359
#endif
1360
 
1361
static int tty_ioctl(struct inode * inode, struct file * file,
1362
                     unsigned int cmd, unsigned long arg)
1363
{
1364
        int     retval;
1365
        struct tty_struct * tty;
1366
        struct tty_struct * real_tty;
1367
        struct winsize tmp_ws;
1368
        pid_t pgrp;
1369
        unsigned char   ch;
1370
        char    mbz = 0;
1371
 
1372
        tty = (struct tty_struct *)file->private_data;
1373
        if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
1374
                return -EINVAL;
1375
 
1376
        if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1377
            tty->driver.subtype == PTY_TYPE_MASTER)
1378
                real_tty = tty->link;
1379
        else
1380
                real_tty = tty;
1381
 
1382
        switch (cmd) {
1383
                case TIOCSTI:
1384
                        if ((current->tty != tty) && !suser())
1385
                                return -EPERM;
1386
                        retval = verify_area(VERIFY_READ, (void *) arg, 1);
1387
                        if (retval)
1388
                                return retval;
1389
                        ch = get_user((char *) arg);
1390
                        tty->ldisc.receive_buf(tty, &ch, &mbz, 1);
1391
                        return 0;
1392
                case TIOCGWINSZ:
1393
                        retval = verify_area(VERIFY_WRITE, (void *) arg,
1394
                                             sizeof (struct winsize));
1395
                        if (retval)
1396
                                return retval;
1397
                        memcpy_tofs((struct winsize *) arg, &tty->winsize,
1398
                                    sizeof (struct winsize));
1399
                        return 0;
1400
                case TIOCSWINSZ:
1401
                        retval = verify_area(VERIFY_READ, (void *) arg,
1402
                                             sizeof (struct winsize));
1403
                        if (retval)
1404
                                return retval;
1405
                        memcpy_fromfs(&tmp_ws, (struct winsize *) arg,
1406
                                      sizeof (struct winsize));
1407
                        if (memcmp(&tmp_ws, &tty->winsize,
1408
                                   sizeof(struct winsize))) {
1409
                                if (tty->pgrp > 0)
1410
                                        kill_pg(tty->pgrp, SIGWINCH, 1);
1411
                                if ((real_tty->pgrp != tty->pgrp) &&
1412
                                    (real_tty->pgrp > 0))
1413
                                        kill_pg(real_tty->pgrp, SIGWINCH, 1);
1414
                        }
1415
                        tty->winsize = tmp_ws;
1416
                        real_tty->winsize = tmp_ws;
1417
                        return 0;
1418
                case TIOCCONS:
1419
                        if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE) {
1420
                                if (!suser())
1421
                                        return -EPERM;
1422
                                redirect = NULL;
1423
                                return 0;
1424
                        }
1425
                        if (redirect)
1426
                                return -EBUSY;
1427
                        redirect = real_tty;
1428
                        return 0;
1429
                case FIONBIO:
1430
                        retval = verify_area(VERIFY_READ, (void *) arg, sizeof(int));
1431
                        if (retval)
1432
                                return retval;
1433
                        arg = get_user((unsigned int *) arg);
1434
                        if (arg)
1435
                                file->f_flags |= O_NONBLOCK;
1436
                        else
1437
                                file->f_flags &= ~O_NONBLOCK;
1438
                        return 0;
1439
                case TIOCEXCL:
1440
                        set_bit(TTY_EXCLUSIVE, &tty->flags);
1441
                        return 0;
1442
                case TIOCNXCL:
1443
                        clear_bit(TTY_EXCLUSIVE, &tty->flags);
1444
                        return 0;
1445
                case TIOCNOTTY:
1446
                        if (current->tty != tty)
1447
                                return -ENOTTY;
1448
                        if (current->leader)
1449
                                disassociate_ctty(0);
1450
                        current->tty = NULL;
1451
                        return 0;
1452
                case TIOCSCTTY:
1453
                        if (current->leader &&
1454
                            (current->session == tty->session))
1455
                                return 0;
1456
                        /*
1457
                         * The process must be a session leader and
1458
                         * not have a controlling tty already.
1459
                         */
1460
                        if (!current->leader || current->tty)
1461
                                return -EPERM;
1462
                        if (tty->session > 0) {
1463
                                /*
1464
                                 * This tty is already the controlling
1465
                                 * tty for another session group!
1466
                                 */
1467
                                if ((arg == 1) && suser()) {
1468
                                        /*
1469
                                         * Steal it away
1470
                                         */
1471
                                        struct task_struct *p;
1472
 
1473
                                        for_each_task(p)
1474
                                                if (p->tty == tty)
1475
                                                        p->tty = NULL;
1476
                                } else
1477
                                        return -EPERM;
1478
                        }
1479
                        current->tty = tty;
1480
                        current->tty_old_pgrp = 0;
1481
                        tty->session = current->session;
1482
                        tty->pgrp = current->pgrp;
1483
                        return 0;
1484
                case TIOCGPGRP:
1485
                        /*
1486
                         * (tty == real_tty) is a cheap way of
1487
                         * testing if the tty is NOT a master pty.
1488
                         */
1489
                        if (tty == real_tty && current->tty != real_tty)
1490
                                return -ENOTTY;
1491
                        retval = verify_area(VERIFY_WRITE, (void *) arg,
1492
                                             sizeof (pid_t));
1493
                        if (retval)
1494
                                return retval;
1495
                        put_user(real_tty->pgrp, (pid_t *) arg);
1496
                        return 0;
1497
                case TIOCSPGRP:
1498
                        retval = tty_check_change(real_tty);
1499
                        if (retval == -EIO)
1500
                                return -ENOTTY;
1501
                        if (retval)
1502
                                return retval;
1503
                        if (!current->tty ||
1504
                            (current->tty != real_tty) ||
1505
                            (real_tty->session != current->session))
1506
                                return -ENOTTY;
1507
                        pgrp = get_user((pid_t *) arg);
1508
                        if (pgrp < 0)
1509
                                return -EINVAL;
1510
                        if (session_of_pgrp(pgrp) != current->session)
1511
                                return -EPERM;
1512
                        real_tty->pgrp = pgrp;
1513
                        return 0;
1514
                case TIOCGETD:
1515
                        retval = verify_area(VERIFY_WRITE, (void *) arg,
1516
                                             sizeof (int));
1517
                        if (retval)
1518
                                return retval;
1519
                        put_user(tty->ldisc.num, (int *) arg);
1520
                        return 0;
1521
                case TIOCSETD:
1522
                        retval = tty_check_change(tty);
1523
                        if (retval)
1524
                                return retval;
1525
                        retval = verify_area(VERIFY_READ, (void *) arg,
1526
                                             sizeof (int));
1527
                        if (retval)
1528
                                return retval;
1529
                        arg = get_user((int *) arg);
1530
                        return tty_set_ldisc(tty, arg);
1531
                case TIOCLINUX:
1532
                        if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
1533
                                return -EINVAL;
1534
                        if (current->tty != tty && !suser())
1535
                                return -EPERM;
1536
                        retval = verify_area(VERIFY_READ, (void *) arg, 1);
1537
                        if (retval)
1538
                                return retval;
1539
                        switch (retval = get_user((char *)arg))
1540
                        {
1541
                                case 0:
1542
                                case 8:
1543
                                case 9:
1544
                                        printk("TIOCLINUX (0/8/9) ioctl is gone - use /dev/vcs\n");
1545
                                        return -EINVAL;
1546
#if 0
1547
                                case 1:
1548
                                        printk("Deprecated TIOCLINUX (1) ioctl\n");
1549
                                        return do_get_ps_info(arg);
1550
#endif
1551
                                case 2:
1552
                                        return set_selection(arg, tty);
1553
                                case 3:
1554
                                        return paste_selection(tty);
1555
                                case 4:
1556
                                        vt_do_unblankscreen ();
1557
                                        return 0;
1558
                                case 5:
1559
                                        return sel_loadlut(arg);
1560
                                case 6:
1561
                        /*
1562
                         * Make it possible to react to Shift+Mousebutton.
1563
                         * Note that 'shift_state' is an undocumented
1564
                         * kernel-internal variable; programs not closely
1565
                         * related to the kernel should not use this.
1566
                         */
1567
                                        retval = verify_area(VERIFY_WRITE, (void *) arg, 1);
1568
                                        if (retval)
1569
                                                return retval;
1570
                                        put_user(shift_state,(char *) arg);
1571
                                        return 0;
1572
                                case 7:
1573
                                        retval = verify_area(VERIFY_WRITE, (void *) arg, 1);
1574
                                        if (retval)
1575
                                                return retval;
1576
                                        put_user(mouse_reporting(),(char *) arg);
1577
                                        return 0;
1578
/*                              case 10:
1579
                                        set_vesa_blanking(arg);
1580
                                        return 0;*/
1581
                                case 11:        /* set kmsg redirect */
1582
                                        if (!suser())
1583
                                                return -EPERM;
1584
                                        retval = verify_area(VERIFY_READ,
1585
                                                (void *) arg+1, 1);
1586
                                        if (retval)
1587
                                                return retval;
1588
                                        kmsg_redirect = get_user((char *)arg+1);
1589
                                        return 0;
1590
                                case 12:        /* get fg console */
1591
                                        return vtdata.fgconsole->num;
1592
                                default:
1593
                                        return -EINVAL;
1594
                        }
1595
 
1596
                case TIOCTTYGSTRUCT:
1597
                        retval = verify_area(VERIFY_WRITE, (void *) arg,
1598
                                                sizeof(struct tty_struct));
1599
                        if (retval)
1600
                                return retval;
1601
                        memcpy_tofs((struct tty_struct *) arg,
1602
                                    tty, sizeof(struct tty_struct));
1603
                        return 0;
1604
                default:
1605
                        if (tty->driver.ioctl) {
1606
                                retval = (tty->driver.ioctl)(tty, file,
1607
                                                             cmd, arg);
1608
                                if (retval != -ENOIOCTLCMD)
1609
                                        return retval;
1610
                        }
1611
                        if (tty->ldisc.ioctl) {
1612
                                retval = (tty->ldisc.ioctl)(tty, file,
1613
                                                            cmd, arg);
1614
                                if (retval != -ENOIOCTLCMD)
1615
                                        return retval;
1616
                        }
1617
                        return -EINVAL;
1618
                }
1619
}
1620
 
1621
 
1622
/*
1623
 * This implements the "Secure Attention Key" ---  the idea is to
1624
 * prevent trojan horses by killing all processes associated with this
1625
 * tty when the user hits the "Secure Attention Key".  Required for
1626
 * super-paranoid applications --- see the Orange Book for more details.
1627
 *
1628
 * This code could be nicer; ideally it should send a HUP, wait a few
1629
 * seconds, then send a INT, and then a KILL signal.  But you then
1630
 * have to coordinate with the init process, since all processes associated
1631
 * with the current tty must be dead before the new getty is allowed
1632
 * to spawn.
1633
 */
1634
void do_SAK( struct tty_struct *tty)
1635
{
1636
#ifdef TTY_SOFT_SAK
1637
        tty_hangup(tty);
1638
#else
1639
        struct task_struct **p;
1640
        int session;
1641
        int             i;
1642
        struct file     *filp;
1643
 
1644
        if (!tty)
1645
                return;
1646
        session  = tty->session;
1647
        if (tty->ldisc.flush_buffer)
1648
                tty->ldisc.flush_buffer(tty);
1649
        if (tty->driver.flush_buffer)
1650
                tty->driver.flush_buffer(tty);
1651
        for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1652
                if (!(*p))
1653
                        continue;
1654
                if (((*p)->tty == tty) ||
1655
                    ((session > 0) && ((*p)->session == session)))
1656
                        send_sig(SIGKILL, *p, 1);
1657
                else if ((*p)->files) {
1658
                        for (i=0; i < NR_OPEN; i++) {
1659
                                filp = (*p)->files->fd[i];
1660
                                if (filp && (filp->f_op == &tty_fops) &&
1661
                                    (filp->private_data == tty)) {
1662
                                        send_sig(SIGKILL, *p, 1);
1663
                                        break;
1664
                                }
1665
                        }
1666
                }
1667
        }
1668
#endif
1669
}
1670
 
1671
/*
1672
 * This routine is called out of the software interrupt to flush data
1673
 * from the flip buffer to the line discipline.
1674
 */
1675
static void flush_to_ldisc(void *private_)
1676
{
1677
        struct tty_struct *tty = (struct tty_struct *) private_;
1678
        unsigned char   *cp;
1679
        char            *fp;
1680
        int             count;
1681
 
1682
        if (tty->flip.buf_num) {
1683
                cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
1684
                fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
1685
                tty->flip.buf_num = 0;
1686
 
1687
                cli();
1688
                tty->flip.char_buf_ptr = tty->flip.char_buf;
1689
                tty->flip.flag_buf_ptr = tty->flip.flag_buf;
1690
        } else {
1691
                cp = tty->flip.char_buf;
1692
                fp = tty->flip.flag_buf;
1693
                tty->flip.buf_num = 1;
1694
 
1695
                cli();
1696
                tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
1697
                tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
1698
        }
1699
        count = tty->flip.count;
1700
        tty->flip.count = 0;
1701
        sti();
1702
 
1703
#if 0
1704
        if (count > tty->max_flip_cnt)
1705
                tty->max_flip_cnt = count;
1706
#endif
1707
        tty->ldisc.receive_buf(tty, cp, fp, count);
1708
}
1709
 
1710
/*
1711
 * This subroutine initializes a tty structure.
1712
 */
1713
static void initialize_tty_struct(struct tty_struct *tty)
1714
{
1715
        memset(tty, 0, sizeof(struct tty_struct));
1716
        tty->magic = TTY_MAGIC;
1717
        tty->ldisc = ldiscs[N_TTY];
1718
        tty->pgrp = -1;
1719
        tty->flip.char_buf_ptr = tty->flip.char_buf;
1720
        tty->flip.flag_buf_ptr = tty->flip.flag_buf;
1721
        tty->flip.tqueue.routine = flush_to_ldisc;
1722
        tty->flip.tqueue.data = tty;
1723
}
1724
 
1725
/*
1726
 * The default put_char routine if the driver did not define one.
1727
 */
1728
void tty_default_put_char(struct tty_struct *tty, unsigned char ch)
1729
{
1730
        tty->driver.write(tty, 0, &ch, 1);
1731
}
1732
 
1733
/*
1734
 * Called by a tty driver to register itself.
1735
 */
1736
int tty_register_driver(struct tty_driver *driver)
1737
{
1738
        int error;
1739
 
1740
        if (driver->flags & TTY_DRIVER_INSTALLED)
1741
                return 0;
1742
 
1743
        error = register_chrdev(driver->major, driver->name, &tty_fops);
1744
        if (error < 0)
1745
                return error;
1746
        else if(driver->major == 0)
1747
                driver->major = error;
1748
 
1749
        if (!driver->put_char)
1750
                driver->put_char = tty_default_put_char;
1751
 
1752
        driver->prev = 0;
1753
        driver->next = tty_drivers;
1754
        if (tty_drivers) tty_drivers->prev = driver;
1755
        tty_drivers = driver;
1756
        return error;
1757
}
1758
 
1759
/*
1760
 * Called by a tty driver to unregister itself.
1761
 */
1762
int tty_unregister_driver(struct tty_driver *driver)
1763
{
1764
        int     retval;
1765
        struct tty_driver *p;
1766
        int     found = 0;
1767
        const char *othername = NULL;
1768
 
1769
        if (*driver->refcount)
1770
                return -EBUSY;
1771
 
1772
        for (p = tty_drivers; p; p = p->next) {
1773
                if (p == driver)
1774
                        found++;
1775
                else if (p->major == driver->major)
1776
                        othername = p->name;
1777
        }
1778
 
1779
        if (!found)
1780
                return -ENOENT;
1781
 
1782
        if (othername == NULL) {
1783
                retval = unregister_chrdev(driver->major, driver->name);
1784
                if (retval)
1785
                        return retval;
1786
        } else
1787
                register_chrdev(driver->major, othername, &tty_fops);
1788
 
1789
        if (driver->prev)
1790
                driver->prev->next = driver->next;
1791
        else
1792
                tty_drivers = driver->next;
1793
 
1794
        if (driver->next)
1795
                driver->next->prev = driver->prev;
1796
 
1797
        return 0;
1798
}
1799
 
1800
 
1801
/*
1802
 * Initialize the console device. This is called *early*, so
1803
 * we can't necessarily depend on lots of kernel help here.
1804
 * Just do some early initializations, and do the complex setup
1805
 * later.
1806
 */
1807
long console_init(long kmem_start, long kmem_end)
1808
{
1809
        /* Setup the default TTY line discipline. */
1810
        memset(ldiscs, 0, sizeof(ldiscs));
1811
        (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
1812
 
1813
        /*
1814
         * Set up the standard termios.  Individual tty drivers may
1815
         * deviate from this; this is used as a template.
1816
         */
1817
        memset(&tty_std_termios, 0, sizeof(struct termios));
1818
        memcpy(tty_std_termios.c_cc, INIT_C_CC, NCCS);
1819
        tty_std_termios.c_iflag = ICRNL | IXON;
1820
        tty_std_termios.c_oflag = OPOST | ONLCR;
1821
        tty_std_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL;
1822
        tty_std_termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
1823
                ECHOCTL | ECHOKE | IEXTEN;
1824
 
1825
        /*
1826
         * set up the console device so that later boot sequences can
1827
         * inform about problems etc..
1828
         */
1829
#ifdef CONFIG_CONSOLE
1830
        /*
1831
         * set up the console device so that later boot sequences can
1832
         * inform about problems etc..
1833
         */
1834
        return vt_pre_init(kmem_start);
1835
#else /* !CONFIG_CONSOLE */
1836
        return kmem_start;
1837
#endif /* !CONFIG_CONSOLE */
1838
}
1839
 
1840
static struct tty_driver dev_tty_driver, dev_console_driver;
1841
 
1842
/*
1843
 * Ok, now we can initialize the rest of the tty devices and can count
1844
 * on memory allocations, interrupts etc..
1845
 */
1846
int tty_init(void)
1847
{
1848
        if (sizeof(struct tty_struct) > PAGE_SIZE)
1849
                panic("size of tty structure > PAGE_SIZE!");
1850
        vt_post_init ();
1851
 
1852
        /*
1853
         * dev_tty_driver and dev_console_driver are actually magic
1854
         * devices which get redirected at open time.  Nevertheless,
1855
         * we register them so that register_chrdev is called
1856
         * appropriately.
1857
         */
1858
        memset(&dev_tty_driver, 0, sizeof(struct tty_driver));
1859
        dev_tty_driver.magic = TTY_DRIVER_MAGIC;
1860
        dev_tty_driver.name = "tty";
1861
        dev_tty_driver.name_base = 0;
1862
        dev_tty_driver.major = TTY_MAJOR;
1863
        dev_tty_driver.minor_start = 0;
1864
        dev_tty_driver.num = 1;
1865
 
1866
        if (tty_register_driver(&dev_tty_driver))
1867
                panic("Couldn't register /dev/tty driver\n");
1868
 
1869
        dev_console_driver = dev_tty_driver;
1870
        dev_console_driver.name = "console";
1871
        dev_console_driver.major = TTYAUX_MAJOR;
1872
 
1873
        if (tty_register_driver(&dev_console_driver))
1874
                panic("Couldn't register /dev/console driver\n");
1875
 
1876
#ifndef CONFIG_ARCH_EBSA110
1877
        kbd_init();
1878
#endif
1879
#ifdef CONFIG_SERIAL
1880
        rs_init();
1881
#endif
1882
#ifdef CONFIG_SERIAL_TRIO
1883
        rs_trio_init();
1884
#endif
1885
        pty_init();
1886
        vcs_init();
1887
        return 0;
1888
}
1889
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.