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

Subversion Repositories or1k

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

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 1118 sfurman
 
51 1070 rprescott
struct xterm_channel
52
{
53
        struct fd_channel fds;
54
        int pid;
55 1118 sfurman
        char** argv;
56 1070 rprescott
};
57
 
58
 
59
static void xterm_close(void * data)
60
{
61
        struct xterm_channel * xt = data;
62
 
63
        if(!xt)
64
                return;
65
 
66
        if(xt->fds.fdin != -1)
67
                close(xt->fds.fdin);
68
 
69
        if(xt->pid != -1)
70
        {
71
                kill(xt->pid, SIGKILL);
72
                waitpid(xt->pid, NULL, 0);
73
        }
74
 
75 1118 sfurman
        if (xt->argv)
76
                free (xt->argv);
77
 
78 1070 rprescott
        xt->fds.fdin = -1;
79
        xt->fds.fdout = -1;
80
        xt->pid = -1;
81 1118 sfurman
        xt->argv = NULL;
82
 
83 1070 rprescott
}
84
 
85
static void xterm_exit(int i, void * data)
86
{
87
        xterm_close(data);
88
}
89
 
90 1118 sfurman
#define MAX_XTERM_ARGS 100
91 1070 rprescott
static void * xterm_init(const char * input)
92
{
93
        struct xterm_channel * retval = malloc(sizeof(struct xterm_channel));
94
        if(retval)
95
        {
96 1122 sfurman
                int i;
97
                char *arglist;
98
 
99 1070 rprescott
                retval->fds.fdin = -1;
100
                retval->fds.fdout = -1;
101
                retval->pid = -1;
102
                /* reset cause exit(1), leaving an xterm opened */
103 1118 sfurman
                on_exit(xterm_exit, retval);
104
 
105 1122 sfurman
                i = 2;
106
                arglist = (char*)input;
107 1118 sfurman
                retval->argv = malloc(sizeof(char*) * MAX_XTERM_ARGS);
108
                if (!retval->argv) {
109
                        free(retval);
110
                        return NULL;
111
                }
112
                /* Assume xterm arguments are separated by whitespace */
113
                while (retval->argv[i++] = strtok(arglist, " \t\n")) {
114
                        arglist = NULL;
115
                        if (i == MAX_XTERM_ARGS - 1) {
116
                                free(retval);
117
                                return NULL;
118
                        }
119
                }
120
 
121 1070 rprescott
        }
122
        return (void*)retval;
123
}
124
 
125
 
126
 
127
static int xterm_open(void * data)
128
{
129
        struct xterm_channel * xt = data;
130
        int master, retval;
131
        char * slavename;
132
        struct termios termio;
133
        char arg[64], * fin;
134
 
135
        if(!data)
136
        {
137
                errno = ENODEV;
138
                return -1;
139
        }
140
 
141
        master = open("/dev/ptmx", O_RDWR);
142
 
143
        if(master < 0)
144
                return -1;
145
 
146
        grantpt(master);
147
        unlockpt(master);
148
        slavename = (char*)ptsname(master);
149
 
150
        if(!slavename)
151
        {
152
                errno = ENOTTY;
153
                goto closemastererror;
154
        }
155
 
156
        xt->fds.fdout = xt->fds.fdin = open(slavename, O_RDWR);
157
        if(xt->fds.fdout < 0) goto closemastererror;
158
 
159 1118 sfurman
#ifndef linux
160
        /* Linux does not support STREAMS-style line discipline, even with LiS. */
161 1070 rprescott
        retval = ioctl(xt->fds.fdin, I_PUSH, "ptem");
162
        if(retval < 0) goto closeslaveerror;
163
 
164
        retval = ioctl(xt->fds.fdin, I_PUSH, "ldterm");
165
        if(retval < 0) goto closeslaveerror;
166 1118 sfurman
#endif
167 1070 rprescott
 
168
        retval = tcgetattr(xt->fds.fdin, &termio);
169
        if(retval < 0) goto closeslaveerror;
170
        termio.c_lflag &= ~ECHO;
171
        retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
172
        if(retval < 0) goto closeslaveerror;
173
 
174
        xt->pid = fork();
175
 
176
        if(xt->pid == -1) goto closeslaveerror;
177
 
178
        if(xt->pid == 0)
179
        {
180
                /* Ctrl-C on sim still kill the xterm, grrr */
181
                signal(SIGINT, SIG_IGN);
182
 
183
                fin = slavename+strlen(slavename)-2;
184
                if (strchr(fin, '/' ))
185
                {
186
                        sprintf(arg, "-S%s/%d",
187
                                basename(slavename),
188
                                master);
189
                }
190
                else
191
                {
192
                      sprintf(arg, "-S%c%c%d", fin[0], fin[1], master);
193
                }
194 1118 sfurman
                xt->argv[0] = "xterm";
195
                xt->argv[1] = arg;
196
                execvp("xterm", xt->argv);
197 1070 rprescott
                write(master, "\n", 1);
198
                exit(1);
199
        }
200
 
201
        do retval = read(xt->fds.fdin, &arg, 1);
202
        while(retval >= 0 && arg[0] != '\n');
203
        if(retval < 0) goto closeslaveerror;
204
 
205
        termio.c_lflag |= ECHO;
206
        retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
207
 
208
        if(retval < 0) goto closeslaveerror;
209
 
210
        return 0;
211
 
212
closeslaveerror:
213
        close(xt->fds.fdin);
214
 
215
closemastererror:
216
        close(master);
217
        xt->pid = xt->fds.fdin = xt->fds.fdout = -1;
218
        return -1;
219
}
220
 
221
struct channel_ops xterm_channel_ops =
222
{
223
        init:   xterm_init,
224
        open:   xterm_open,
225
        close:  xterm_close,
226
        read:   fd_read,
227
        write:  fd_write,
228
        free:   generic_free,
229
};
230
 
231
/*
232
 * Local variables:
233
 * c-file-style: "linux"
234
 * End:
235
 */
236
 

powered by: WebSVN 2.1.0

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