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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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