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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [peripheral/] [channels/] [xterm.c] - Blame information for rev 1767

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 1744 jeremybenn
   Copyright (C) 2008 Embecosm Limited
8
 
9
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
10
 
11
   This file is part of OpenRISC 1000 Architectural Simulator.
12
 
13
   This program is free software; you can redistribute it and/or modify it
14
   under the terms of the GNU General Public License as published by the Free
15
   Software Foundation; either version 3 of the License, or (at your option)
16
   any later version.
17
 
18
   This program is distributed in the hope that it will be useful, but WITHOUT
19
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
21
   more details.
22
 
23
   You should have received a copy of the GNU General Public License along
24
   with this program.  If not, see <http://www.gnu.org/licenses/>. */
25 1070 rprescott
 
26
 
27 1748 jeremybenn
/* This program is commented throughout in a fashion suitable for processing
28
   with Doxygen. */
29
 
30
 
31
/* Autoconf and/or portability configuration */
32
#include "config.h"
33
#include "port.h"
34
 
35
/* System includes */
36
#if defined(HAVE_GRANTPT) && defined(HAVE_UNLOCKPT) && defined(HAVE_PTSNAME)
37 1244 hpanther
#endif
38
 
39 1748 jeremybenn
#include <stdlib.h>
40
#include <unistd.h>
41
#include <signal.h>
42
#include <termios.h>
43
#include <errno.h>
44
#include <stdio.h>
45
#include <fcntl.h>
46
#include <sys/types.h>
47
#include <sys/wait.h>
48 1070 rprescott
 
49 1244 hpanther
#if HAVE_SYS_STROPTS_H
50 1748 jeremybenn
#include <sys/stropts.h>        /* I_PUSH ioctl */
51 1244 hpanther
#endif
52 1748 jeremybenn
 
53
#if HAVE_BASENAME
54 1146 phoenix
#include <libgen.h>             /* basename() */
55 1748 jeremybenn
#endif
56 1146 phoenix
 
57 1748 jeremybenn
/* Package includes */
58 1070 rprescott
#include "channel.h"
59
#include "generic.h"
60
#include "fd.h"
61
 
62 1748 jeremybenn
/*! Data structure to represent the connection to the xterm */
63 1070 rprescott
struct xterm_channel
64
{
65 1748 jeremybenn
  struct fd_channel fds;
66
  int pid;
67
  char **argv;
68 1070 rprescott
};
69
 
70 1748 jeremybenn
/* Forward declaration of static functions */
71
static void  xterm_close (void *data);
72
static void *xterm_init (const char *input);
73
static int   xterm_open (void *data);
74
 
75
/*! Global data structure with the xterm interface functions */
76
struct channel_ops  xterm_channel_ops = {
77
        .init  = xterm_init,
78
        .open  = xterm_open,
79
        .close = xterm_close,
80
        .read  = fd_read,
81
        .write = fd_write,
82
        .free  = generic_free,
83
};
84
 
85
 
86
#if !(HAVE_BASENAME)
87
static char *
88
basename (const char *filename)
89 1146 phoenix
{
90 1748 jeremybenn
  char *p = strrchr (filename, '/');
91
 
92
  return p ? p + 1 : (char *) filename;
93 1146 phoenix
}
94 1748 jeremybenn
#endif /* HAVE_BASENAME */
95 1070 rprescott
 
96 1748 jeremybenn
static void
97
xterm_close (void *data)
98 1070 rprescott
{
99 1748 jeremybenn
  struct xterm_channel *xt = data;
100 1070 rprescott
 
101 1748 jeremybenn
  if (!xt)
102
    return;
103 1070 rprescott
 
104 1748 jeremybenn
  if (xt->fds.fdin != -1)
105
    close (xt->fds.fdin);
106 1070 rprescott
 
107 1748 jeremybenn
  if (xt->pid != -1)
108
    {
109
      kill (xt->pid, SIGKILL);
110
      waitpid (xt->pid, NULL, 0);
111
    }
112 1118 sfurman
 
113 1748 jeremybenn
  if (xt->argv)
114
    free (xt->argv);
115
 
116
  xt->fds.fdin = -1;
117
  xt->fds.fdout = -1;
118
  xt->pid = -1;
119
  xt->argv = NULL;
120
 
121 1070 rprescott
}
122
 
123 1744 jeremybenn
#if defined(HAVE_ON_EXIT)
124 1748 jeremybenn
static void
125
xterm_exit (int i, void *data)
126 1070 rprescott
{
127 1748 jeremybenn
  xterm_close (data);
128 1070 rprescott
}
129 1557 nogj
#endif
130 1070 rprescott
 
131 1118 sfurman
#define MAX_XTERM_ARGS 100
132 1748 jeremybenn
static void *
133
xterm_init (const char *input)
134 1070 rprescott
{
135 1748 jeremybenn
  struct xterm_channel *retval = malloc (sizeof (struct xterm_channel));
136
  if (retval)
137
    {
138
      int i;
139
      char *arglist;
140 1122 sfurman
 
141 1748 jeremybenn
      retval->fds.fdin = -1;
142
      retval->fds.fdout = -1;
143
      retval->pid = -1;
144 1244 hpanther
 
145 1744 jeremybenn
#if defined(HAVE_ON_EXIT)
146 1748 jeremybenn
      /* reset cause exit(1), leaving an xterm opened */
147
      on_exit (xterm_exit, retval);
148 1244 hpanther
#endif
149 1748 jeremybenn
 
150
      i = 2;
151
      arglist = (char *) input;
152
      retval->argv = malloc (sizeof (char *) * MAX_XTERM_ARGS);
153
      if (!retval->argv)
154
        {
155
          free (retval);
156
          return NULL;
157 1070 rprescott
        }
158 1748 jeremybenn
      /* Assume xterm arguments are separated by whitespace */
159
      while ((retval->argv[i++] = strtok (arglist, " \t\n")))
160
        {
161
          arglist = NULL;
162
          if (i == MAX_XTERM_ARGS - 1)
163
            {
164
              free (retval);
165
              return NULL;
166
            }
167
        }
168
 
169
    }
170
  return (void *) retval;
171 1070 rprescott
}
172
 
173
 
174
 
175 1748 jeremybenn
static int
176
xterm_open (void *data)
177 1070 rprescott
{
178 1722 nogj
#if defined(HAVE_GRANTPT) && defined(HAVE_UNLOCKPT) && defined(HAVE_PTSNAME)
179 1748 jeremybenn
  struct xterm_channel *xt = data;
180
  int master, retval;
181
  char *slavename;
182
  struct termios termio;
183
  char arg[64], *fin;
184 1070 rprescott
 
185 1748 jeremybenn
  if (!data)
186
    {
187
      errno = ENODEV;
188
      return -1;
189
    }
190 1070 rprescott
 
191 1748 jeremybenn
  master = open ("/dev/ptmx", O_RDWR);
192 1070 rprescott
 
193 1748 jeremybenn
  if (master < 0)
194
    return -1;
195 1070 rprescott
 
196 1748 jeremybenn
  grantpt (master);
197
  unlockpt (master);
198
  slavename = (char *) ptsname (master);
199 1070 rprescott
 
200 1748 jeremybenn
  if (!slavename)
201
    {
202
      errno = ENOTTY;
203
      goto closemastererror;
204
    }
205 1070 rprescott
 
206 1748 jeremybenn
  xt->fds.fdout = xt->fds.fdin = open (slavename, O_RDWR);
207
  if (xt->fds.fdout < 0)
208
    goto closemastererror;
209 1070 rprescott
 
210 1751 jeremybenn
#if HAVE_DECL_I_PUSH
211 1748 jeremybenn
  /* These modules must be pushed onto the stream for some non-Linux and
212
     non-Cygwin operating systems. */
213
  retval = ioctl (xt->fds.fdin, I_PUSH, "ptem");
214
  if (retval < 0)
215
    goto closeslaveerror;
216 1070 rprescott
 
217 1748 jeremybenn
  retval = ioctl (xt->fds.fdin, I_PUSH, "ldterm");
218
  if (retval < 0)
219
    goto closeslaveerror;
220 1118 sfurman
#endif
221 1070 rprescott
 
222 1748 jeremybenn
  retval = tcgetattr (xt->fds.fdin, &termio);
223
  if (retval < 0)
224
    goto closeslaveerror;
225
  termio.c_lflag &= ~ECHO;
226
  retval = tcsetattr (xt->fds.fdin, TCSADRAIN, &termio);
227
  if (retval < 0)
228
    goto closeslaveerror;
229 1070 rprescott
 
230 1748 jeremybenn
  xt->pid = fork ();
231 1070 rprescott
 
232 1748 jeremybenn
  if (xt->pid == -1)
233
    goto closeslaveerror;
234
 
235
  if (xt->pid == 0)
236
    {
237
      /* Ctrl-C on sim still kill the xterm, grrr */
238
      signal (SIGINT, SIG_IGN);
239
 
240
      fin = slavename + strlen (slavename) - 2;
241
      if (strchr (fin, '/'))
242 1070 rprescott
        {
243 1748 jeremybenn
          sprintf (arg, "-S%s/%d", basename (slavename), master);
244 1070 rprescott
        }
245 1748 jeremybenn
      else
246
        {
247
          sprintf (arg, "-S%c%c%d", fin[0], fin[1], master);
248
        }
249
      xt->argv[0] = "xterm";
250
      xt->argv[1] = arg;
251
      execvp ("xterm", xt->argv);
252
      write (master, "\n", 1);
253
      exit (1);
254
    }
255 1070 rprescott
 
256 1748 jeremybenn
  do
257
    retval = read (xt->fds.fdin, &arg, 1);
258
  while (retval >= 0 && arg[0] != '\n');
259
  if (retval < 0)
260
    goto closeslaveerror;
261 1070 rprescott
 
262 1748 jeremybenn
  termio.c_lflag |= ECHO;
263
  retval = tcsetattr (xt->fds.fdin, TCSADRAIN, &termio);
264 1070 rprescott
 
265 1748 jeremybenn
  if (retval < 0)
266
    goto closeslaveerror;
267 1070 rprescott
 
268 1748 jeremybenn
  return 0;
269
 
270 1070 rprescott
closeslaveerror:
271 1748 jeremybenn
  close (xt->fds.fdin);
272 1070 rprescott
 
273
closemastererror:
274 1748 jeremybenn
  close (master);
275
  xt->pid = xt->fds.fdin = xt->fds.fdout = -1;
276
  return -1;
277 1244 hpanther
 
278
#else
279 1748 jeremybenn
  /* I don't see how this stuff should be working on a system that doesn't know
280
     grantpt(), unlockpt(), ptsname(). Mac OS X also does not have /dev/ptmx.
281
     -hpanther
282
   */
283
  return -1;
284 1244 hpanther
#endif
285 1070 rprescott
}

powered by: WebSVN 2.1.0

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