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 1118

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

powered by: WebSVN 2.1.0

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