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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_44/] [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
static void xterm_exit(int i, void * data)
102
{
103
        xterm_close(data);
104
}
105
 
106 1118 sfurman
#define MAX_XTERM_ARGS 100
107 1070 rprescott
static void * xterm_init(const char * input)
108
{
109
        struct xterm_channel * retval = malloc(sizeof(struct xterm_channel));
110
        if(retval)
111
        {
112 1122 sfurman
                int i;
113
                char *arglist;
114
 
115 1070 rprescott
                retval->fds.fdin = -1;
116
                retval->fds.fdout = -1;
117
                retval->pid = -1;
118 1244 hpanther
 
119
#if defined(HAS_ON_EXIT)
120 1070 rprescott
                /* reset cause exit(1), leaving an xterm opened */
121 1118 sfurman
                on_exit(xterm_exit, retval);
122 1244 hpanther
#endif
123
 
124 1122 sfurman
                i = 2;
125
                arglist = (char*)input;
126 1118 sfurman
                retval->argv = malloc(sizeof(char*) * MAX_XTERM_ARGS);
127
                if (!retval->argv) {
128
                        free(retval);
129
                        return NULL;
130
                }
131
                /* Assume xterm arguments are separated by whitespace */
132 1308 phoenix
                while ((retval->argv[i++] = strtok(arglist, " \t\n"))) {
133 1118 sfurman
                        arglist = NULL;
134
                        if (i == MAX_XTERM_ARGS - 1) {
135
                                free(retval);
136
                                return NULL;
137
                        }
138
                }
139
 
140 1070 rprescott
        }
141
        return (void*)retval;
142
}
143
 
144
 
145
 
146
static int xterm_open(void * data)
147
{
148 1244 hpanther
#if defined(HAS_GRANTPT) && defined(HAS_UNLOCKPT) && defined(HAS_PTSNAME)
149 1070 rprescott
        struct xterm_channel * xt = data;
150
        int master, retval;
151
        char * slavename;
152
        struct termios termio;
153
        char arg[64], * fin;
154
 
155
        if(!data)
156
        {
157
                errno = ENODEV;
158
                return -1;
159
        }
160
 
161
        master = open("/dev/ptmx", O_RDWR);
162
 
163
        if(master < 0)
164
                return -1;
165
 
166
        grantpt(master);
167
        unlockpt(master);
168
        slavename = (char*)ptsname(master);
169
 
170
        if(!slavename)
171
        {
172
                errno = ENOTTY;
173
                goto closemastererror;
174
        }
175
 
176
        xt->fds.fdout = xt->fds.fdin = open(slavename, O_RDWR);
177
        if(xt->fds.fdout < 0) goto closemastererror;
178
 
179 1244 hpanther
//#if !defined(linux) && !defined(__CYGWIN__)
180
#if defined(I_PUSH)
181 1118 sfurman
        /* Linux does not support STREAMS-style line discipline, even with LiS. */
182 1070 rprescott
        retval = ioctl(xt->fds.fdin, I_PUSH, "ptem");
183
        if(retval < 0) goto closeslaveerror;
184
 
185
        retval = ioctl(xt->fds.fdin, I_PUSH, "ldterm");
186
        if(retval < 0) goto closeslaveerror;
187 1118 sfurman
#endif
188 1070 rprescott
 
189
        retval = tcgetattr(xt->fds.fdin, &termio);
190
        if(retval < 0) goto closeslaveerror;
191
        termio.c_lflag &= ~ECHO;
192
        retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
193
        if(retval < 0) goto closeslaveerror;
194
 
195
        xt->pid = fork();
196
 
197
        if(xt->pid == -1) goto closeslaveerror;
198
 
199
        if(xt->pid == 0)
200
        {
201
                /* Ctrl-C on sim still kill the xterm, grrr */
202
                signal(SIGINT, SIG_IGN);
203
 
204
                fin = slavename+strlen(slavename)-2;
205
                if (strchr(fin, '/' ))
206
                {
207
                        sprintf(arg, "-S%s/%d",
208
                                basename(slavename),
209
                                master);
210
                }
211
                else
212
                {
213
                      sprintf(arg, "-S%c%c%d", fin[0], fin[1], master);
214
                }
215 1118 sfurman
                xt->argv[0] = "xterm";
216
                xt->argv[1] = arg;
217
                execvp("xterm", xt->argv);
218 1070 rprescott
                write(master, "\n", 1);
219
                exit(1);
220
        }
221
 
222
        do retval = read(xt->fds.fdin, &arg, 1);
223
        while(retval >= 0 && arg[0] != '\n');
224
        if(retval < 0) goto closeslaveerror;
225
 
226
        termio.c_lflag |= ECHO;
227
        retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
228
 
229
        if(retval < 0) goto closeslaveerror;
230
 
231
        return 0;
232
 
233
closeslaveerror:
234
        close(xt->fds.fdin);
235
 
236
closemastererror:
237
        close(master);
238
        xt->pid = xt->fds.fdin = xt->fds.fdout = -1;
239
        return -1;
240 1244 hpanther
 
241
#else
242
        /* I don't see how this stuff should be working on a system that doesn't know
243
                grantpt(), unlockpt(), ptsname(). Mac OS X also does not have /dev/ptmx.
244
                -hpanther
245
                */
246
        return -1;
247
#endif
248 1070 rprescott
}
249
 
250
struct channel_ops xterm_channel_ops =
251
{
252
        init:   xterm_init,
253
        open:   xterm_open,
254
        close:  xterm_close,
255
        read:   fd_read,
256
        write:  fd_write,
257
        free:   generic_free,
258
};
259
 
260
/*
261
 * Local variables:
262
 * c-file-style: "linux"
263
 * End:
264
 */
265
 

powered by: WebSVN 2.1.0

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