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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [peripheral/] [channels/] [xterm.c] - Blame information for rev 1765

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 1244 hpanther
#if HAVE_CONFIG_H
30
#include <config.h>
31
#endif
32
 
33 1070 rprescott
#define _XOPEN_SOURCE           /* grantpt() and al. */
34
#define _GNU_SOURCE             /* on_exit */
35
 
36
#include <sys/types.h>          /* waitpid() */
37
#include <sys/wait.h>           /* waitpid() */
38
#include <stdio.h>              /* sprintf() */
39
#include <stdlib.h>             /* kill(), on_exit() */
40
#include <unistd.h>             /* close() */
41
#include <fcntl.h>              /* O_RDWR */
42
#include <string.h>             /* strchr() */
43 1146 phoenix
 
44
#ifndef __CYGWIN__
45 1244 hpanther
#if HAVE_SYS_STROPTS_H
46 1070 rprescott
#include <sys/stropts.h>        /* grantpt(), unlockpt() */
47 1244 hpanther
#endif
48 1146 phoenix
#include <libgen.h>             /* basename() */
49
#endif /* __CYGWIN__ */
50
 
51 1070 rprescott
#include <termios.h>            /* struct termios and al. */
52
#include <signal.h>             /* signal() and al. */
53
#include <errno.h>              /* errno and al. */
54
 
55
#include "channel.h"
56
#include "generic.h"
57
#include "fd.h"
58
 
59
struct xterm_channel
60
{
61
        struct fd_channel fds;
62
        int pid;
63 1118 sfurman
        char** argv;
64 1070 rprescott
};
65
 
66 1146 phoenix
#ifdef __CYGWIN__
67
char *basename(const char *filename)
68
{
69
        char *p = strrchr (filename, '/');
70
 
71
        return p ? p + 1 : (char *) filename;
72
}
73
#endif /* __CYGWIN__ */
74 1070 rprescott
 
75
static void xterm_close(void * data)
76
{
77
        struct xterm_channel * xt = data;
78
 
79
        if(!xt)
80
                return;
81
 
82
        if(xt->fds.fdin != -1)
83
                close(xt->fds.fdin);
84
 
85
        if(xt->pid != -1)
86
        {
87
                kill(xt->pid, SIGKILL);
88
                waitpid(xt->pid, NULL, 0);
89
        }
90
 
91 1118 sfurman
        if (xt->argv)
92
                free (xt->argv);
93
 
94 1070 rprescott
        xt->fds.fdin = -1;
95
        xt->fds.fdout = -1;
96
        xt->pid = -1;
97 1118 sfurman
        xt->argv = NULL;
98
 
99 1070 rprescott
}
100
 
101 1557 nogj
#if defined(HAS_ON_EXIT)
102 1070 rprescott
static void xterm_exit(int i, void * data)
103
{
104
        xterm_close(data);
105
}
106 1557 nogj
#endif
107 1070 rprescott
 
108 1118 sfurman
#define MAX_XTERM_ARGS 100
109 1070 rprescott
static void * xterm_init(const char * input)
110
{
111
        struct xterm_channel * retval = malloc(sizeof(struct xterm_channel));
112
        if(retval)
113
        {
114 1122 sfurman
                int i;
115
                char *arglist;
116
 
117 1070 rprescott
                retval->fds.fdin = -1;
118
                retval->fds.fdout = -1;
119
                retval->pid = -1;
120 1244 hpanther
 
121
#if defined(HAS_ON_EXIT)
122 1070 rprescott
                /* reset cause exit(1), leaving an xterm opened */
123 1118 sfurman
                on_exit(xterm_exit, retval);
124 1244 hpanther
#endif
125
 
126 1122 sfurman
                i = 2;
127
                arglist = (char*)input;
128 1118 sfurman
                retval->argv = malloc(sizeof(char*) * MAX_XTERM_ARGS);
129
                if (!retval->argv) {
130
                        free(retval);
131
                        return NULL;
132
                }
133
                /* Assume xterm arguments are separated by whitespace */
134 1308 phoenix
                while ((retval->argv[i++] = strtok(arglist, " \t\n"))) {
135 1118 sfurman
                        arglist = NULL;
136
                        if (i == MAX_XTERM_ARGS - 1) {
137
                                free(retval);
138
                                return NULL;
139
                        }
140
                }
141
 
142 1070 rprescott
        }
143
        return (void*)retval;
144
}
145
 
146
 
147
 
148
static int xterm_open(void * data)
149
{
150 1244 hpanther
#if defined(HAS_GRANTPT) && defined(HAS_UNLOCKPT) && defined(HAS_PTSNAME)
151 1070 rprescott
        struct xterm_channel * xt = data;
152
        int master, retval;
153
        char * slavename;
154
        struct termios termio;
155
        char arg[64], * fin;
156
 
157
        if(!data)
158
        {
159
                errno = ENODEV;
160
                return -1;
161
        }
162
 
163
        master = open("/dev/ptmx", O_RDWR);
164
 
165
        if(master < 0)
166
                return -1;
167
 
168
        grantpt(master);
169
        unlockpt(master);
170
        slavename = (char*)ptsname(master);
171
 
172
        if(!slavename)
173
        {
174
                errno = ENOTTY;
175
                goto closemastererror;
176
        }
177
 
178
        xt->fds.fdout = xt->fds.fdin = open(slavename, O_RDWR);
179
        if(xt->fds.fdout < 0) goto closemastererror;
180
 
181 1244 hpanther
//#if !defined(linux) && !defined(__CYGWIN__)
182
#if defined(I_PUSH)
183 1118 sfurman
        /* Linux does not support STREAMS-style line discipline, even with LiS. */
184 1070 rprescott
        retval = ioctl(xt->fds.fdin, I_PUSH, "ptem");
185
        if(retval < 0) goto closeslaveerror;
186
 
187
        retval = ioctl(xt->fds.fdin, I_PUSH, "ldterm");
188
        if(retval < 0) goto closeslaveerror;
189 1118 sfurman
#endif
190 1070 rprescott
 
191
        retval = tcgetattr(xt->fds.fdin, &termio);
192
        if(retval < 0) goto closeslaveerror;
193
        termio.c_lflag &= ~ECHO;
194
        retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
195
        if(retval < 0) goto closeslaveerror;
196
 
197
        xt->pid = fork();
198
 
199
        if(xt->pid == -1) goto closeslaveerror;
200
 
201
        if(xt->pid == 0)
202
        {
203
                /* Ctrl-C on sim still kill the xterm, grrr */
204
                signal(SIGINT, SIG_IGN);
205
 
206
                fin = slavename+strlen(slavename)-2;
207
                if (strchr(fin, '/' ))
208
                {
209
                        sprintf(arg, "-S%s/%d",
210
                                basename(slavename),
211
                                master);
212
                }
213
                else
214
                {
215
                      sprintf(arg, "-S%c%c%d", fin[0], fin[1], master);
216
                }
217 1118 sfurman
                xt->argv[0] = "xterm";
218
                xt->argv[1] = arg;
219
                execvp("xterm", xt->argv);
220 1070 rprescott
                write(master, "\n", 1);
221
                exit(1);
222
        }
223
 
224
        do retval = read(xt->fds.fdin, &arg, 1);
225
        while(retval >= 0 && arg[0] != '\n');
226
        if(retval < 0) goto closeslaveerror;
227
 
228
        termio.c_lflag |= ECHO;
229
        retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
230
 
231
        if(retval < 0) goto closeslaveerror;
232
 
233
        return 0;
234
 
235
closeslaveerror:
236
        close(xt->fds.fdin);
237
 
238
closemastererror:
239
        close(master);
240
        xt->pid = xt->fds.fdin = xt->fds.fdout = -1;
241
        return -1;
242 1244 hpanther
 
243
#else
244
        /* I don't see how this stuff should be working on a system that doesn't know
245
                grantpt(), unlockpt(), ptsname(). Mac OS X also does not have /dev/ptmx.
246
                -hpanther
247
                */
248
        return -1;
249
#endif
250 1070 rprescott
}
251
 
252
struct channel_ops xterm_channel_ops =
253
{
254
        init:   xterm_init,
255
        open:   xterm_open,
256
        close:  xterm_close,
257
        read:   fd_read,
258
        write:  fd_write,
259
        free:   generic_free,
260
};
261
 
262
/*
263
 * Local variables:
264
 * c-file-style: "linux"
265
 * End:
266
 */
267
 

powered by: WebSVN 2.1.0

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