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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_59/] [or1ksim/] [peripheral/] [channels/] [xterm.c] - Blame information for rev 1070

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

Line No. Rev Author Line
1 1070 rprescott
/* xterm.c -- Definition of functions and structures for
2
   peripheral to communicate with host through an xterm.
3
   Inspired from SWI-Prolog by Jan Wielemaker (GPL too)
4
   even if there is really few in common.
5
 
6
   Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
7
 
8
This file is part of OpenRISC 1000 Architectural Simulator.
9
 
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 2 of the License, or
13
(at your option) any later version.
14
 
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
GNU General Public License for more details.
19
 
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23
 
24
/*
25
 *  I really dislike using stuff beginning with '_'
26
 *  They are suppose to be reserved for the compiler
27
 *  as explained in C standards.
28
 */
29
#define _XOPEN_SOURCE           /* grantpt() and al. */
30
#define _GNU_SOURCE             /* on_exit */
31
 
32
#include <sys/types.h>          /* waitpid() */
33
#include <sys/wait.h>           /* waitpid() */
34
#include <stdio.h>              /* sprintf() */
35
#include <stdlib.h>             /* kill(), on_exit() */
36
#include <unistd.h>             /* close() */
37
#include <fcntl.h>              /* O_RDWR */
38
#include <string.h>             /* strchr() */
39
#include <sys/stropts.h>        /* grantpt(), unlockpt() */
40
#include <termios.h>            /* struct termios and al. */
41
#include <signal.h>             /* signal() and al. */
42
#include <libgen.h>             /* basename() */
43
#include <errno.h>              /* errno and al. */
44
 
45
#include "channel.h"
46
#include "generic.h"
47
#include "fd.h"
48
 
49
 
50
struct xterm_channel
51
{
52
        struct fd_channel fds;
53
        int pid;
54
};
55
 
56
 
57
static void xterm_close(void * data)
58
{
59
        struct xterm_channel * xt = data;
60
 
61
        if(!xt)
62
                return;
63
 
64
        if(xt->fds.fdin != -1)
65
                close(xt->fds.fdin);
66
 
67
        if(xt->pid != -1)
68
        {
69
                kill(xt->pid, SIGKILL);
70
                waitpid(xt->pid, NULL, 0);
71
        }
72
 
73
        xt->fds.fdin = -1;
74
        xt->fds.fdout = -1;
75
        xt->pid = -1;
76
}
77
 
78
static void xterm_exit(int i, void * data)
79
{
80
        xterm_close(data);
81
}
82
 
83
static void * xterm_init(const char * input)
84
{
85
        struct xterm_channel * retval = malloc(sizeof(struct xterm_channel));
86
        if(retval)
87
        {
88
                retval->fds.fdin = -1;
89
                retval->fds.fdout = -1;
90
                retval->pid = -1;
91
                /* reset cause exit(1), leaving an xterm opened */
92
                on_exit(xterm_exit, retval);
93
        }
94
        return (void*)retval;
95
}
96
 
97
 
98
 
99
static int xterm_open(void * data)
100
{
101
        struct xterm_channel * xt = data;
102
        int master, retval;
103
        char * slavename;
104
        struct termios termio;
105
        char arg[64], * fin;
106
 
107
        if(!data)
108
        {
109
                errno = ENODEV;
110
                return -1;
111
        }
112
 
113
 
114
        master = open("/dev/ptmx", O_RDWR);
115
 
116
        if(master < 0)
117
                return -1;
118
 
119
        grantpt(master);
120
        unlockpt(master);
121
        slavename = (char*)ptsname(master);
122
 
123
        if(!slavename)
124
        {
125
                errno = ENOTTY;
126
                goto closemastererror;
127
        }
128
 
129
        xt->fds.fdout = xt->fds.fdin = open(slavename, O_RDWR);
130
        if(xt->fds.fdout < 0) goto closemastererror;
131
 
132
        retval = ioctl(xt->fds.fdin, I_PUSH, "ptem");
133
        if(retval < 0) goto closeslaveerror;
134
 
135
        retval = ioctl(xt->fds.fdin, I_PUSH, "ldterm");
136
        if(retval < 0) goto closeslaveerror;
137
 
138
        retval = tcgetattr(xt->fds.fdin, &termio);
139
        if(retval < 0) goto closeslaveerror;
140
 
141
 
142
        termio.c_lflag &= ~ECHO;
143
        retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
144
        if(retval < 0) goto closeslaveerror;
145
 
146
        xt->pid = fork();
147
 
148
        if(xt->pid == -1) goto closeslaveerror;
149
 
150
        if(xt->pid == 0)
151
        {
152
                /* Ctrl-C on sim still kill the xterm, grrr */
153
                signal(SIGINT, SIG_IGN);
154
 
155
                fin = slavename+strlen(slavename)-2;
156
                if (strchr(fin, '/' ))
157
                {
158
                        sprintf(arg, "-S%s/%d",
159
                                basename(slavename),
160
                                master);
161
                }
162
                else
163
                {
164
                      sprintf(arg, "-S%c%c%d", fin[0], fin[1], master);
165
                }
166
                execlp("xterm", "xterm", arg, NULL);
167
                write(master, "\n", 1);
168
                exit(1);
169
        }
170
 
171
        do retval = read(xt->fds.fdin, &arg, 1);
172
        while(retval >= 0 && arg[0] != '\n');
173
 
174
        if(retval < 0) goto closeslaveerror;
175
 
176
        termio.c_lflag |= ECHO;
177
        retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
178
 
179
        if(retval < 0) goto closeslaveerror;
180
 
181
        return 0;
182
 
183
closeslaveerror:
184
        close(xt->fds.fdin);
185
 
186
closemastererror:
187
        close(master);
188
        xt->pid = xt->fds.fdin = xt->fds.fdout = -1;
189
        return -1;
190
}
191
 
192
struct channel_ops xterm_channel_ops =
193
{
194
        init:   xterm_init,
195
        open:   xterm_open,
196
        close:  xterm_close,
197
        read:   fd_read,
198
        write:  fd_write,
199
        free:   generic_free,
200
};
201
 
202
/*
203
 * Local variables:
204
 * c-file-style: "linux"
205
 * End:
206
 */
207
 

powered by: WebSVN 2.1.0

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