diff options
| -rw-r--r-- | meta/conf/distro/include/poky-default-revisions.inc | 1 | ||||
| -rw-r--r-- | meta/packages/tasks/task-poky-tools.bb | 1 | ||||
| -rw-r--r-- | meta/packages/tcf-agent/tcf-agent/fix_tcf-agent.init.patch | 92 | ||||
| -rw-r--r-- | meta/packages/tcf-agent/tcf-agent/terminals_agent.patch | 1025 | ||||
| -rw-r--r-- | meta/packages/tcf-agent/tcf-agent_svn.bb | 36 |
5 files changed, 1155 insertions, 0 deletions
diff --git a/meta/conf/distro/include/poky-default-revisions.inc b/meta/conf/distro/include/poky-default-revisions.inc index f8262fdcfb..2edc019acc 100644 --- a/meta/conf/distro/include/poky-default-revisions.inc +++ b/meta/conf/distro/include/poky-default-revisions.inc | |||
| @@ -102,6 +102,7 @@ SRCREV_pn-ohm ??= "edfe25d49d67884bf004de7ae0724c162bb5e65e" | |||
| 102 | SRCREV_pn-opkg-utils-native ??= "4747" | 102 | SRCREV_pn-opkg-utils-native ??= "4747" |
| 103 | SRCREV_pn-opkg-utils ??= "4747" | 103 | SRCREV_pn-opkg-utils ??= "4747" |
| 104 | SRCREV_pn-oprofileui ??= "197" | 104 | SRCREV_pn-oprofileui ??= "197" |
| 105 | SRCREV_pn-tcf-agent ??= "1078" | ||
| 105 | SRCREV_pn-osc-native ??= "9096" | 106 | SRCREV_pn-osc-native ??= "9096" |
| 106 | SRCREV_pn-owl-video ??= "394" | 107 | SRCREV_pn-owl-video ??= "394" |
| 107 | SRCREV_pn-pkgconfig ??= "66d49f1375fec838bcd301bb4ca2ef76cee0e47c" | 108 | SRCREV_pn-pkgconfig ??= "66d49f1375fec838bcd301bb4ca2ef76cee0e47c" |
diff --git a/meta/packages/tasks/task-poky-tools.bb b/meta/packages/tasks/task-poky-tools.bb index bebda285f0..3872cd5633 100644 --- a/meta/packages/tasks/task-poky-tools.bb +++ b/meta/packages/tasks/task-poky-tools.bb | |||
| @@ -31,6 +31,7 @@ KEXECTOOLS_powerpc ?= "" | |||
| 31 | RDEPENDS_task-poky-tools-debug = "\ | 31 | RDEPENDS_task-poky-tools-debug = "\ |
| 32 | gdb \ | 32 | gdb \ |
| 33 | gdbserver \ | 33 | gdbserver \ |
| 34 | tcf-agent \ | ||
| 34 | strace" | 35 | strace" |
| 35 | 36 | ||
| 36 | RDEPENDS_task-poky-tools-profile = "\ | 37 | RDEPENDS_task-poky-tools-profile = "\ |
diff --git a/meta/packages/tcf-agent/tcf-agent/fix_tcf-agent.init.patch b/meta/packages/tcf-agent/tcf-agent/fix_tcf-agent.init.patch new file mode 100644 index 0000000000..66d403b623 --- /dev/null +++ b/meta/packages/tcf-agent/tcf-agent/fix_tcf-agent.init.patch | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | --- a/Makefile | ||
| 2 | +++ b/Makefile | ||
| 3 | @@ -32,7 +32,7 @@ | ||
| 4 | install -d -m 755 $(INSTALLROOT)$(SBIN) | ||
| 5 | install -d -m 755 $(INSTALLROOT)$(INIT) | ||
| 6 | install -c $(BINDIR)/agent -m 755 $(INSTALLROOT)$(SBIN)/tcf-agent | ||
| 7 | - install -c $(TCF_AGENT_DIR)/main/tcf-agent.init -m 755 $(INSTALLROOT)$(INIT)/tcf-agent | ||
| 8 | + install -c tcf-agent.init -m 755 $(INSTALLROOT)$(INIT)/tcf-agent | ||
| 9 | |||
| 10 | clean: | ||
| 11 | rm -rf $(BINDIR) | ||
| 12 | --- /dev/null | ||
| 13 | +++ b/tcf-agent.init | ||
| 14 | @@ -0,0 +1,78 @@ | ||
| 15 | +#!/bin/sh | ||
| 16 | +### BEGIN INIT INFO | ||
| 17 | +# Provides: tcf-agent | ||
| 18 | +# Default-Start: 3 5 | ||
| 19 | +# Default-Stop: 0 1 2 6 | ||
| 20 | +# Short-Description: Target Communication Framework agent | ||
| 21 | +### END INIT INFO | ||
| 22 | + | ||
| 23 | +DAEMON_PATH=/usr/sbin/tcf-agent | ||
| 24 | +DAEMON_NAME=`basename $DAEMON_PATH` | ||
| 25 | + | ||
| 26 | +. /etc/init.d/functions | ||
| 27 | + | ||
| 28 | +test -x $DAEMON_PATH || exit 0 | ||
| 29 | + | ||
| 30 | +PATH=/sbin:/usr/sbin:/bin:/usr/bin | ||
| 31 | +export PATH | ||
| 32 | + | ||
| 33 | +RETVAL=0 | ||
| 34 | + | ||
| 35 | +case "$1" in | ||
| 36 | + start) | ||
| 37 | + echo -n "Starting $DAEMON_NAME: " | ||
| 38 | + $DAEMON_PATH -d -L- -l0 -s SSL: | ||
| 39 | + RETVAL=$? | ||
| 40 | + if [ $RETVAL -eq 0 ] ; then | ||
| 41 | + echo "OK" | ||
| 42 | + touch /var/lock/subsys/$DAEMON_NAME | ||
| 43 | + else | ||
| 44 | + echo "FAIL" | ||
| 45 | + fi | ||
| 46 | + ;; | ||
| 47 | + | ||
| 48 | + stop) | ||
| 49 | + echo -n "Stopping $DAEMON_NAME: " | ||
| 50 | + count=0 | ||
| 51 | + while [ -n "`/bin/pidof $DAEMON_PATH`" -a $count -lt 10 ] ; do | ||
| 52 | + killproc $DAEMON_PATH >& /dev/null | ||
| 53 | + sleep 1 | ||
| 54 | + RETVAL=$? | ||
| 55 | + if [ $RETVAL != 0 -o -n "`/bin/pidof $DAEMON_PATH`" ] ; then | ||
| 56 | + sleep 3 | ||
| 57 | + fi | ||
| 58 | + count=`expr $count + 1` | ||
| 59 | + done | ||
| 60 | + rm -f /var/lock/subsys/$DAEMON_NAME | ||
| 61 | + if [ -n "`/bin/pidof $DAEMON_PATH`" ] ; then | ||
| 62 | + echo "FAIL" | ||
| 63 | + else | ||
| 64 | + echo "OK" | ||
| 65 | + fi | ||
| 66 | + ;; | ||
| 67 | + | ||
| 68 | + restart) | ||
| 69 | + $0 stop | ||
| 70 | + sleep 1 | ||
| 71 | + $0 start | ||
| 72 | + ;; | ||
| 73 | + | ||
| 74 | + status) | ||
| 75 | + if [ -n "`/bin/pidof $DAEMON_PATH`" ] ; then | ||
| 76 | + echo "$DAEMON_NAME is running" | ||
| 77 | + else | ||
| 78 | + echo "$DAEMON_NAME is not running" | ||
| 79 | + fi | ||
| 80 | + ;; | ||
| 81 | + | ||
| 82 | + condrestart) | ||
| 83 | + [ -f /var/lock/subsys/$DAEMON_NAME ] && $0 restart | ||
| 84 | + ;; | ||
| 85 | + | ||
| 86 | + *) | ||
| 87 | + echo "usage: $0 { start | stop | restart | condrestart | status }" | ||
| 88 | + ;; | ||
| 89 | +esac | ||
| 90 | + | ||
| 91 | +exit $RETVAL | ||
| 92 | + | ||
diff --git a/meta/packages/tcf-agent/tcf-agent/terminals_agent.patch b/meta/packages/tcf-agent/tcf-agent/terminals_agent.patch new file mode 100644 index 0000000000..b88b5e70cd --- /dev/null +++ b/meta/packages/tcf-agent/tcf-agent/terminals_agent.patch | |||
| @@ -0,0 +1,1025 @@ | |||
| 1 | Index: org.eclipse.tm.tcf.terminals.agent/terminals.c | ||
| 2 | =================================================================== | ||
| 3 | --- org.eclipse.tm.tcf.terminals.agent/terminals.c (revision 0) | ||
| 4 | +++ org.eclipse.tm.tcf.terminals.agent/terminals.c (revision 0) | ||
| 5 | @@ -0,0 +1,846 @@ | ||
| 6 | +/******************************************************************************* | ||
| 7 | + * Copyright (c) 2008 Wind River Systems, Inc. and others. | ||
| 8 | + * All rights reserved. This program and the accompanying materials | ||
| 9 | + * are made available under the terms of the Eclipse Public License v1.0 | ||
| 10 | + * and Eclipse Distribution License v1.0 which accompany this distribution. | ||
| 11 | + * The Eclipse Public License is available at | ||
| 12 | + * http://www.eclipse.org/legal/epl-v10.html | ||
| 13 | + * and the Eclipse Distribution License is available at | ||
| 14 | + * http://www.eclipse.org/org/documents/edl-v10.php. | ||
| 15 | + * | ||
| 16 | + * Contributors: | ||
| 17 | + * Wind River Systems - initial API and implementation | ||
| 18 | + *******************************************************************************/ | ||
| 19 | + | ||
| 20 | +/* | ||
| 21 | + * Sample TCF service implementation. | ||
| 22 | + */ | ||
| 23 | + | ||
| 24 | +#include <config.h> | ||
| 25 | +#include <stdlib.h> | ||
| 26 | +#include <stdio.h> | ||
| 27 | +#include <string.h> | ||
| 28 | +#include <errno.h> | ||
| 29 | +#include <fcntl.h> | ||
| 30 | +#include <signal.h> | ||
| 31 | +#include <assert.h> | ||
| 32 | +#include <termios.h> | ||
| 33 | +#ifndef TIOCGWINSZ | ||
| 34 | +#include <sys/ioctl.h> | ||
| 35 | +#endif | ||
| 36 | +#include <framework/myalloc.h> | ||
| 37 | +#include <framework/protocol.h> | ||
| 38 | +#include <framework/trace.h> | ||
| 39 | +#include <framework/context.h> | ||
| 40 | +#include <framework/json.h> | ||
| 41 | +#include <framework/asyncreq.h> | ||
| 42 | +#include <framework/exceptions.h> | ||
| 43 | +#include <framework/waitpid.h> | ||
| 44 | +#include <framework/signames.h> | ||
| 45 | +#include <services/streamsservice.h> | ||
| 46 | +#include <terminals.h> | ||
| 47 | + | ||
| 48 | +#define TERMINALS_DEBUG 1 | ||
| 49 | + | ||
| 50 | +#define TERMINALS_NO_LOGIN 0 | ||
| 51 | + | ||
| 52 | +static const char * TERMINALS = "Terminals"; | ||
| 53 | + | ||
| 54 | +#if defined(WIN32) | ||
| 55 | +# include <tlhelp32.h> | ||
| 56 | +# ifdef _MSC_VER | ||
| 57 | +# pragma warning(disable:4201) /* nonstandard extension used : nameless struct/union (in winternl.h) */ | ||
| 58 | +# include <winternl.h> | ||
| 59 | +# else | ||
| 60 | +# include <ntdef.h> | ||
| 61 | +# endif | ||
| 62 | +# ifndef STATUS_INFO_LENGTH_MISMATCH | ||
| 63 | +# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) | ||
| 64 | +# endif | ||
| 65 | +# ifndef SystemHandleInformation | ||
| 66 | +# define SystemHandleInformation 16 | ||
| 67 | +# endif | ||
| 68 | +# error("unsupported WIN32!") | ||
| 69 | +#elif defined(_WRS_KERNEL) | ||
| 70 | +# include <symLib.h> | ||
| 71 | +# include <sysSymTbl.h> | ||
| 72 | +# include <ioLib.h> | ||
| 73 | +# include <ptyDrv.h> | ||
| 74 | +# include <taskHookLib.h> | ||
| 75 | +# error("unsupported WRS!") | ||
| 76 | +#else | ||
| 77 | +# include <sys/stat.h> | ||
| 78 | +# include <unistd.h> | ||
| 79 | +# include <dirent.h> | ||
| 80 | +# if TERMINALS_NO_LOGIN | ||
| 81 | +# define TERM_LAUNCH_EXEC "/bin/bash" | ||
| 82 | +# define TERM_LAUNCH_ARGS {TERM_LAUNCH_EXEC, NULL} | ||
| 83 | +# else | ||
| 84 | +# define TERM_LAUNCH_EXEC "/bin/login" | ||
| 85 | +# define TERM_LAUNCH_ARGS {TERM_LAUNCH_EXEC, "-p", NULL} | ||
| 86 | +# endif | ||
| 87 | +#endif | ||
| 88 | + | ||
| 89 | +#define PIPE_SIZE 0x1000 | ||
| 90 | +#define TERM_PROP_DEF_SIZE 256 | ||
| 91 | + | ||
| 92 | +typedef struct Terminal | ||
| 93 | +{ | ||
| 94 | + LINK link; | ||
| 95 | + int pid; /*pid of the login process of the terminal*/ | ||
| 96 | + TCFBroadcastGroup * bcg; | ||
| 97 | + int inp; | ||
| 98 | + int out; | ||
| 99 | + int err; | ||
| 100 | + struct TerminalInput * inp_struct; | ||
| 101 | + struct TerminalOutput * out_struct; | ||
| 102 | + struct TerminalOutput * err_struct; | ||
| 103 | + char inp_id[256]; | ||
| 104 | + char out_id[256]; | ||
| 105 | + char err_id[256]; | ||
| 106 | + | ||
| 107 | + char pty_type[TERM_PROP_DEF_SIZE]; | ||
| 108 | + char encoding[TERM_PROP_DEF_SIZE]; | ||
| 109 | + unsigned long width; | ||
| 110 | + unsigned long height; | ||
| 111 | + long exit_code; | ||
| 112 | + | ||
| 113 | + Channel *channel; | ||
| 114 | +} Terminal; | ||
| 115 | + | ||
| 116 | +typedef struct TerminalOutput | ||
| 117 | +{ | ||
| 118 | + Terminal * prs; | ||
| 119 | + AsyncReqInfo req; | ||
| 120 | + int req_posted; | ||
| 121 | + char buf[PIPE_SIZE]; | ||
| 122 | + size_t buf_pos; | ||
| 123 | + int eos; | ||
| 124 | + VirtualStream * vstream; | ||
| 125 | +} TerminalOutput; | ||
| 126 | + | ||
| 127 | +typedef struct TerminalInput | ||
| 128 | +{ | ||
| 129 | + Terminal * prs; | ||
| 130 | + AsyncReqInfo req; | ||
| 131 | + int req_posted; | ||
| 132 | + char buf[PIPE_SIZE]; | ||
| 133 | + size_t buf_pos; | ||
| 134 | + size_t buf_len; | ||
| 135 | + int eos; | ||
| 136 | + VirtualStream * vstream; | ||
| 137 | +} TerminalInput; | ||
| 138 | + | ||
| 139 | +#define link2term(A) ((Terminal *)((char *)(A) - offsetof(Terminal, link))) | ||
| 140 | + | ||
| 141 | +static LINK terms_list; | ||
| 142 | +#if defined(_WRS_KERNEL) | ||
| 143 | +static SEM_ID prs_list_lock = NULL; | ||
| 144 | +#endif | ||
| 145 | + | ||
| 146 | +static Terminal * find_terminal(int pid) | ||
| 147 | +{ | ||
| 148 | + LINK * qhp = &terms_list; | ||
| 149 | + LINK * qp = qhp->next; | ||
| 150 | + | ||
| 151 | + while (qp != qhp) { | ||
| 152 | + Terminal * prs = link2term(qp); | ||
| 153 | + if (prs->pid == pid) | ||
| 154 | + return prs; | ||
| 155 | + qp = qp->next; | ||
| 156 | + } | ||
| 157 | + return NULL; | ||
| 158 | +} | ||
| 159 | + | ||
| 160 | +static char * tid2id(int tid) | ||
| 161 | +{ | ||
| 162 | + static char s[64]; | ||
| 163 | + char * p = s + sizeof(s); | ||
| 164 | + unsigned long n = (long) tid; | ||
| 165 | + *(--p) = 0; | ||
| 166 | + do { | ||
| 167 | + *(--p) = (char) (n % 10 + '0'); | ||
| 168 | + n = n / 10; | ||
| 169 | + } while (n != 0); | ||
| 170 | + | ||
| 171 | + *(--p) = 'T'; | ||
| 172 | + return p; | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +static int id2tid(const char * id) | ||
| 176 | +{ | ||
| 177 | + int tid = 0; | ||
| 178 | + if (id == NULL) | ||
| 179 | + return 0; | ||
| 180 | + if (id[0] != 'T') | ||
| 181 | + return 0; | ||
| 182 | + if (id[1] == 0) | ||
| 183 | + return 0; | ||
| 184 | + tid = (unsigned) strtol(id + 1, (char **) &id, 10); | ||
| 185 | + if (id[0] != 0) | ||
| 186 | + return 0; | ||
| 187 | + return tid; | ||
| 188 | +} | ||
| 189 | + | ||
| 190 | +static void write_context(OutputStream * out, int tid) | ||
| 191 | +{ | ||
| 192 | + Terminal * prs = find_terminal(tid); | ||
| 193 | + | ||
| 194 | + write_stream(out, '{'); | ||
| 195 | + | ||
| 196 | + if (prs != NULL) { | ||
| 197 | + if (*prs->pty_type) { | ||
| 198 | + json_write_string(out, "PtyType"); | ||
| 199 | + write_stream(out, ':'); | ||
| 200 | + json_write_string(out, prs->pty_type); | ||
| 201 | + write_stream(out, ','); | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + if (*prs->encoding) { | ||
| 205 | + json_write_string(out, "Encoding"); | ||
| 206 | + write_stream(out, ':'); | ||
| 207 | + json_write_string(out, prs->encoding); | ||
| 208 | + write_stream(out, ','); | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + json_write_string(out, "Width"); | ||
| 212 | + write_stream(out, ':'); | ||
| 213 | + json_write_ulong(out, prs->width); | ||
| 214 | + write_stream(out, ','); | ||
| 215 | + | ||
| 216 | + json_write_string(out, "Height"); | ||
| 217 | + write_stream(out, ':'); | ||
| 218 | + json_write_ulong(out, prs->height); | ||
| 219 | + write_stream(out, ','); | ||
| 220 | + | ||
| 221 | + if (*prs->inp_id) { | ||
| 222 | + json_write_string(out, "StdInID"); | ||
| 223 | + write_stream(out, ':'); | ||
| 224 | + json_write_string(out, prs->inp_id); | ||
| 225 | + write_stream(out, ','); | ||
| 226 | + } | ||
| 227 | + if (*prs->out_id) { | ||
| 228 | + json_write_string(out, "StdOutID"); | ||
| 229 | + write_stream(out, ':'); | ||
| 230 | + json_write_string(out, prs->out_id); | ||
| 231 | + write_stream(out, ','); | ||
| 232 | + } | ||
| 233 | + if (*prs->err_id) { | ||
| 234 | + json_write_string(out, "StdErrID"); | ||
| 235 | + write_stream(out, ':'); | ||
| 236 | + json_write_string(out, prs->err_id); | ||
| 237 | + write_stream(out, ','); | ||
| 238 | + } | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + json_write_string(out, "ID"); | ||
| 242 | + write_stream(out, ':'); | ||
| 243 | + json_write_string(out, tid2id(tid)); | ||
| 244 | + | ||
| 245 | + write_stream(out, '}'); | ||
| 246 | +} | ||
| 247 | + | ||
| 248 | +static void send_event_terminal_exited(OutputStream * out, Terminal * prs) | ||
| 249 | +{ | ||
| 250 | + write_stringz(out, "E"); | ||
| 251 | + write_stringz(out, TERMINALS); | ||
| 252 | + write_stringz(out, "exited"); | ||
| 253 | + | ||
| 254 | + json_write_string(out, tid2id(prs->pid)); | ||
| 255 | + write_stream(out, 0); | ||
| 256 | + | ||
| 257 | + json_write_ulong(out, prs->exit_code); | ||
| 258 | + write_stream(out, 0); | ||
| 259 | + | ||
| 260 | + write_stream(out, MARKER_EOM); | ||
| 261 | +} | ||
| 262 | + | ||
| 263 | +static void send_event_terminal_win_size_changed(OutputStream * out, | ||
| 264 | + Terminal * prs) | ||
| 265 | +{ | ||
| 266 | + write_stringz(out, "E"); | ||
| 267 | + write_stringz(out, TERMINALS); | ||
| 268 | + write_stringz(out, "winSizeChanged"); | ||
| 269 | + | ||
| 270 | + json_write_string(out, tid2id(prs->pid)); | ||
| 271 | + write_stream(out, 0); | ||
| 272 | + | ||
| 273 | + json_write_long(out, prs->width); | ||
| 274 | + write_stream(out, 0); | ||
| 275 | + | ||
| 276 | + json_write_long(out, prs->height); | ||
| 277 | + write_stream(out, 0); | ||
| 278 | + | ||
| 279 | + write_stream(out, MARKER_EOM); | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | +static int kill_term(Terminal *term) | ||
| 283 | +{ | ||
| 284 | + int err = 0; | ||
| 285 | + | ||
| 286 | +#if defined(WIN32) | ||
| 287 | + HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, term->pid); | ||
| 288 | + if (h == NULL) | ||
| 289 | + { | ||
| 290 | + err = set_win32_errno(GetLastError()); | ||
| 291 | + } | ||
| 292 | + else | ||
| 293 | + { | ||
| 294 | + if (!TerminateProcess(h, 1)) err = set_win32_errno(GetLastError()); | ||
| 295 | + if (!CloseHandle(h) && !err) err = set_win32_errno(GetLastError()); | ||
| 296 | + } | ||
| 297 | +#else | ||
| 298 | + if (kill(term->pid, SIGTERM) < 0) | ||
| 299 | + err = errno; | ||
| 300 | +#endif | ||
| 301 | + return err; | ||
| 302 | +} | ||
| 303 | + | ||
| 304 | +static void command_exit(char * token, Channel * c) | ||
| 305 | +{ | ||
| 306 | + int err = 0; | ||
| 307 | + char id[256]; | ||
| 308 | + unsigned tid; | ||
| 309 | + Terminal *term = NULL; | ||
| 310 | + | ||
| 311 | + json_read_string(&c->inp, id, sizeof(id)); | ||
| 312 | + if (read_stream(&c->inp) != 0) | ||
| 313 | + exception(ERR_JSON_SYNTAX); | ||
| 314 | + if (read_stream(&c->inp) != MARKER_EOM) | ||
| 315 | + exception(ERR_JSON_SYNTAX); | ||
| 316 | + | ||
| 317 | + tid = id2tid(id); | ||
| 318 | + write_stringz(&c->out, "R"); | ||
| 319 | + write_stringz(&c->out, token); | ||
| 320 | + | ||
| 321 | + if (tid == 0) { | ||
| 322 | + err = ERR_INV_CONTEXT; | ||
| 323 | + } else { | ||
| 324 | + term = find_terminal(tid); | ||
| 325 | + if (term == NULL) { | ||
| 326 | + err = ERR_INV_CONTEXT; | ||
| 327 | + } else { | ||
| 328 | + err = kill_term(term); | ||
| 329 | + } | ||
| 330 | + } | ||
| 331 | + | ||
| 332 | + write_errno(&c->out, err); | ||
| 333 | + write_stream(&c->out, MARKER_EOM); | ||
| 334 | +} | ||
| 335 | + | ||
| 336 | +static void terminal_exited(Terminal * prs) | ||
| 337 | +{ | ||
| 338 | + Trap trap; | ||
| 339 | + | ||
| 340 | + if (set_trap(&trap)) { | ||
| 341 | + send_event_terminal_exited(&prs->bcg->out, prs); | ||
| 342 | + clear_trap(&trap); | ||
| 343 | + } else { | ||
| 344 | + trace(LOG_ALWAYS, "Exception sending terminal exited event: %d %s", | ||
| 345 | + trap.error, errno_to_str(trap.error)); | ||
| 346 | + } | ||
| 347 | + | ||
| 348 | +#if defined(_WRS_KERNEL) | ||
| 349 | + semTake(prs_list_lock, WAIT_FOREVER); | ||
| 350 | +#endif | ||
| 351 | + list_remove(&prs->link); | ||
| 352 | + close(prs->inp); | ||
| 353 | + close(prs->out); | ||
| 354 | + if (prs->out != prs->err) | ||
| 355 | + close(prs->err); | ||
| 356 | + if (prs->inp_struct) { | ||
| 357 | + TerminalInput * inp = prs->inp_struct; | ||
| 358 | + if (!inp->req_posted) { | ||
| 359 | + virtual_stream_delete(inp->vstream); | ||
| 360 | + loc_free(inp); | ||
| 361 | + } else { | ||
| 362 | + inp->prs = NULL; | ||
| 363 | + } | ||
| 364 | + } | ||
| 365 | + if (prs->out_struct) | ||
| 366 | + prs->out_struct->prs = NULL; | ||
| 367 | + if (prs->err_struct) | ||
| 368 | + prs->err_struct->prs = NULL; | ||
| 369 | + loc_free(prs); | ||
| 370 | +#if defined(_WRS_KERNEL) | ||
| 371 | + semGive(prs_list_lock); | ||
| 372 | +#endif | ||
| 373 | +} | ||
| 374 | + | ||
| 375 | +static void terminal_input_streams_callback(VirtualStream * stream, | ||
| 376 | + int event_code, void * args) | ||
| 377 | +{ | ||
| 378 | + TerminalInput * inp = (TerminalInput *) args; | ||
| 379 | + | ||
| 380 | + assert(inp->vstream == stream); | ||
| 381 | + if (!inp->req_posted) { | ||
| 382 | + if (inp->buf_pos >= inp->buf_len && !inp->eos) { | ||
| 383 | + inp->buf_pos = inp->buf_len = 0; | ||
| 384 | + virtual_stream_get_data(stream, inp->buf, sizeof(inp->buf), | ||
| 385 | + &inp->buf_len, &inp->eos); | ||
| 386 | + } | ||
| 387 | + if (inp->buf_pos < inp->buf_len) { | ||
| 388 | + inp->req.u.fio.bufp = inp->buf + inp->buf_pos; | ||
| 389 | + inp->req.u.fio.bufsz = inp->buf_len - inp->buf_pos; | ||
| 390 | + inp->req_posted = 1; | ||
| 391 | + async_req_post(&inp->req); | ||
| 392 | + } | ||
| 393 | + } | ||
| 394 | +} | ||
| 395 | + | ||
| 396 | +static void write_terminal_input_done(void * x) | ||
| 397 | +{ | ||
| 398 | + AsyncReqInfo * req = (AsyncReqInfo *) x; | ||
| 399 | + TerminalInput * inp = (TerminalInput *) req->client_data; | ||
| 400 | + | ||
| 401 | + inp->req_posted = 0; | ||
| 402 | + if (inp->prs == NULL) { | ||
| 403 | + /* Process has exited */ | ||
| 404 | + virtual_stream_delete(inp->vstream); | ||
| 405 | + loc_free(inp); | ||
| 406 | + } else { | ||
| 407 | + int wr = inp->req.u.fio.rval; | ||
| 408 | + | ||
| 409 | + if (wr < 0) { | ||
| 410 | + int err = inp->req.error; | ||
| 411 | + trace(LOG_ALWAYS, "Can't write terminal input stream: %d %s", err, | ||
| 412 | + errno_to_str(err)); | ||
| 413 | + inp->buf_pos = inp->buf_len = 0; | ||
| 414 | + } else { | ||
| 415 | + inp->buf_pos += wr; | ||
| 416 | + } | ||
| 417 | + | ||
| 418 | + terminal_input_streams_callback(inp->vstream, 0, inp); | ||
| 419 | + } | ||
| 420 | +} | ||
| 421 | + | ||
| 422 | +static void write_terminal_input(Terminal * prs) | ||
| 423 | +{ | ||
| 424 | + TerminalInput * inp = prs->inp_struct = (TerminalInput *) loc_alloc_zero( | ||
| 425 | + sizeof(TerminalInput)); | ||
| 426 | + inp->prs = prs; | ||
| 427 | + inp->req.client_data = inp; | ||
| 428 | + inp->req.done = write_terminal_input_done; | ||
| 429 | + inp->req.type = AsyncReqWrite; | ||
| 430 | + inp->req.u.fio.fd = prs->inp; | ||
| 431 | + virtual_stream_create(TERMINALS, tid2id(prs->pid), PIPE_SIZE, | ||
| 432 | + VS_ENABLE_REMOTE_WRITE, terminal_input_streams_callback, inp, | ||
| 433 | + &inp->vstream); | ||
| 434 | + virtual_stream_get_id(inp->vstream, prs->inp_id, sizeof(prs->inp_id)); | ||
| 435 | +} | ||
| 436 | + | ||
| 437 | +static void terminal_output_streams_callback(VirtualStream * stream, | ||
| 438 | + int event_code, void * args) | ||
| 439 | +{ | ||
| 440 | + TerminalOutput * out = (TerminalOutput *) args; | ||
| 441 | + | ||
| 442 | + assert(out->vstream == stream); | ||
| 443 | + if (!out->req_posted) { | ||
| 444 | + int buf_len = out->req.u.fio.rval; | ||
| 445 | + int err = 0; | ||
| 446 | + int eos = 0; | ||
| 447 | + | ||
| 448 | + if (buf_len < 0) { | ||
| 449 | + buf_len = 0; | ||
| 450 | + err = out->req.error; | ||
| 451 | + } | ||
| 452 | + if (buf_len == 0) | ||
| 453 | + eos = 1; | ||
| 454 | + if (out->prs == NULL) { | ||
| 455 | + eos = 1; | ||
| 456 | + err = 0; | ||
| 457 | + } | ||
| 458 | + | ||
| 459 | + assert(buf_len <= (int)sizeof(out->buf)); | ||
| 460 | + assert(out->buf_pos <= (size_t)buf_len); | ||
| 461 | + assert(out->req.u.fio.bufp == out->buf); | ||
| 462 | +#ifdef __linux__ | ||
| 463 | + if (err == EIO) | ||
| 464 | + err = 0; | ||
| 465 | +#endif | ||
| 466 | + if (err) | ||
| 467 | + trace(LOG_ALWAYS, "Can't read terminal output stream: %d %s", err, | ||
| 468 | + errno_to_str(err)); | ||
| 469 | + | ||
| 470 | + if (out->buf_pos < (size_t) buf_len || out->eos != eos) { | ||
| 471 | + size_t done = 0; | ||
| 472 | + virtual_stream_add_data(stream, out->buf + out->buf_pos, buf_len | ||
| 473 | + - out->buf_pos, &done, eos); | ||
| 474 | + out->buf_pos += done; | ||
| 475 | + if (eos) | ||
| 476 | + out->eos = 1; | ||
| 477 | + } | ||
| 478 | + | ||
| 479 | + if (out->buf_pos >= (size_t) buf_len) { | ||
| 480 | + if (!eos) { | ||
| 481 | + out->req_posted = 1; | ||
| 482 | + async_req_post(&out->req); | ||
| 483 | + } else if (virtual_stream_is_empty(stream)) { | ||
| 484 | + if (out->prs != NULL) { | ||
| 485 | + if (out == out->prs->out_struct) | ||
| 486 | + out->prs->out_struct = NULL; | ||
| 487 | + if (out == out->prs->err_struct) | ||
| 488 | + out->prs->err_struct = NULL; | ||
| 489 | + } | ||
| 490 | + virtual_stream_delete(stream); | ||
| 491 | + loc_free(out); | ||
| 492 | + } | ||
| 493 | + } | ||
| 494 | + } // end if(!out->req_posted) | ||
| 495 | +} | ||
| 496 | + | ||
| 497 | +static void read_terminal_output_done(void * x) | ||
| 498 | +{ | ||
| 499 | + AsyncReqInfo * req = (AsyncReqInfo *) x; | ||
| 500 | + TerminalOutput * out = (TerminalOutput *) req->client_data; | ||
| 501 | + | ||
| 502 | + out->buf_pos = 0; | ||
| 503 | + out->req_posted = 0; | ||
| 504 | + terminal_output_streams_callback(out->vstream, 0, out); | ||
| 505 | +} | ||
| 506 | + | ||
| 507 | +static TerminalOutput * read_terminal_output(Terminal * prs, int fd, char * id, | ||
| 508 | + size_t id_size) | ||
| 509 | +{ | ||
| 510 | + TerminalOutput * out = (TerminalOutput *) loc_alloc_zero( | ||
| 511 | + sizeof(TerminalOutput)); | ||
| 512 | + out->prs = prs; | ||
| 513 | + out->req.client_data = out; | ||
| 514 | + out->req.done = read_terminal_output_done; | ||
| 515 | + out->req.type = AsyncReqRead; | ||
| 516 | + out->req.u.fio.bufp = out->buf; | ||
| 517 | + out->req.u.fio.bufsz = sizeof(out->buf); | ||
| 518 | + out->req.u.fio.fd = fd; | ||
| 519 | + virtual_stream_create(TERMINALS, tid2id(prs->pid), PIPE_SIZE, | ||
| 520 | + VS_ENABLE_REMOTE_READ, terminal_output_streams_callback, out, | ||
| 521 | + &out->vstream); | ||
| 522 | + virtual_stream_get_id(out->vstream, id, id_size); | ||
| 523 | + out->req_posted = 1; | ||
| 524 | + async_req_post(&out->req); | ||
| 525 | + return out; | ||
| 526 | +} | ||
| 527 | + | ||
| 528 | +static char **envp_add(char **old_envp, int old_envp_len, char *env) | ||
| 529 | +{ | ||
| 530 | + char **new_envp = NULL; | ||
| 531 | + int i; | ||
| 532 | + int env_size; | ||
| 533 | + int old_envp_size; | ||
| 534 | + | ||
| 535 | + assert(old_envp || (old_envp==NULL && old_envp_len==0)); | ||
| 536 | + assert(env); | ||
| 537 | + assert(*env); | ||
| 538 | + | ||
| 539 | + for (i = 0, old_envp_size = 0; i < old_envp_len; i++) { | ||
| 540 | + old_envp_size += sizeof(char *); //size of env pointer | ||
| 541 | + old_envp_size += strlen(old_envp[i]) + 1; //size of env string, including trailing '\0' | ||
| 542 | + } | ||
| 543 | + assert((old_envp && old_envp[i]==NULL) || (old_envp==NULL)); | ||
| 544 | + old_envp_size += sizeof(char *);//last null pointer | ||
| 545 | + | ||
| 546 | + env_size = strlen(env); //new env string size | ||
| 547 | + | ||
| 548 | + new_envp = loc_alloc(old_envp_size + sizeof(char *) + env_size + 1); | ||
| 549 | + if (new_envp != NULL) { | ||
| 550 | + new_envp[0] = (char *) new_envp + old_envp_size + sizeof(char *); //setting new env ptr | ||
| 551 | + strcpy(new_envp[0], env); //copy new env string | ||
| 552 | + if (old_envp) { | ||
| 553 | + memcpy(&new_envp[1], old_envp, old_envp_size); //copy old envp | ||
| 554 | + } else { | ||
| 555 | + new_envp[1] = NULL; | ||
| 556 | + } | ||
| 557 | + } | ||
| 558 | + return new_envp; | ||
| 559 | +} | ||
| 560 | + | ||
| 561 | +static int start_terminal(Channel * c, char *pty_type, char *encoding, | ||
| 562 | + char ** envp, int envp_len, char * exe, char ** args, int *pid, | ||
| 563 | + Terminal ** prs) | ||
| 564 | +{ | ||
| 565 | + int err = 0; | ||
| 566 | + int fd_tty_master = -1; | ||
| 567 | + char * tty_slave_name = NULL; | ||
| 568 | + struct winsize size; | ||
| 569 | + char **newenvp = envp; | ||
| 570 | + | ||
| 571 | + memset(&size, 0, sizeof(struct winsize)); | ||
| 572 | + fd_tty_master = posix_openpt(O_RDWR | O_NOCTTY); | ||
| 573 | + if (fd_tty_master < 0 || grantpt(fd_tty_master) < 0 || unlockpt( | ||
| 574 | + fd_tty_master) < 0) | ||
| 575 | + err = errno; | ||
| 576 | + if (!err) { | ||
| 577 | + tty_slave_name = ptsname(fd_tty_master); | ||
| 578 | + if (tty_slave_name == NULL) | ||
| 579 | + err = EINVAL; | ||
| 580 | + } | ||
| 581 | + | ||
| 582 | + if (ioctl(fd_tty_master, TIOCGWINSZ, (char *) &size) < 0) | ||
| 583 | + err = errno; | ||
| 584 | + | ||
| 585 | + if (!err && fd_tty_master < 3) { | ||
| 586 | + int fd0 = fd_tty_master; | ||
| 587 | + if ((fd_tty_master = dup(fd_tty_master)) < 0 || close(fd0)) | ||
| 588 | + err = errno; | ||
| 589 | + } | ||
| 590 | + | ||
| 591 | + if (!err) { | ||
| 592 | + *pid = fork(); | ||
| 593 | + if (*pid < 0) | ||
| 594 | + err = errno; | ||
| 595 | + if (*pid == 0) { | ||
| 596 | + int fd = -1; | ||
| 597 | + int fd_tty_slave = -1; | ||
| 598 | + | ||
| 599 | + if (*pty_type) { | ||
| 600 | + char env_term[TERM_PROP_DEF_SIZE]; | ||
| 601 | + snprintf(env_term, sizeof(env_term), "TERM=%s", pty_type); | ||
| 602 | + newenvp = envp_add(envp, envp_len, env_term); | ||
| 603 | + if (newenvp == NULL) { | ||
| 604 | + err = ENOMEM; | ||
| 605 | + } else if (envp) { | ||
| 606 | + loc_free(envp); | ||
| 607 | + envp = NULL; | ||
| 608 | + } | ||
| 609 | + } | ||
| 610 | + | ||
| 611 | + setsid(); | ||
| 612 | + | ||
| 613 | + if (!err && (fd = sysconf(_SC_OPEN_MAX)) < 0) | ||
| 614 | + err = errno; | ||
| 615 | + if (!err && (fd_tty_slave = open(tty_slave_name, O_RDWR)) < 0) | ||
| 616 | + err = errno; | ||
| 617 | +#if defined(TIOCSCTTY) | ||
| 618 | + if (!err && (ioctl(fd_tty_slave, TIOCSCTTY, (char *) 0)) < 0) | ||
| 619 | + err = errno; | ||
| 620 | +#endif | ||
| 621 | + if (!err && dup2(fd_tty_slave, 0) < 0) | ||
| 622 | + err = errno; | ||
| 623 | + if (!err && dup2(fd_tty_slave, 1) < 0) | ||
| 624 | + err = errno; | ||
| 625 | + if (!err && dup2(fd_tty_slave, 2) < 0) | ||
| 626 | + err = errno; | ||
| 627 | + while (!err && fd > 3) | ||
| 628 | + close(--fd); | ||
| 629 | + if (!err) { | ||
| 630 | + execve(exe, args, newenvp); | ||
| 631 | + err = errno; | ||
| 632 | + } | ||
| 633 | + if (newenvp) | ||
| 634 | + loc_free(newenvp); | ||
| 635 | + err = 1; | ||
| 636 | + if (err < 1) | ||
| 637 | + err = EINVAL; | ||
| 638 | + else if (err > 0xff) | ||
| 639 | + err = EINVAL; | ||
| 640 | + exit(err); | ||
| 641 | + } | ||
| 642 | + } | ||
| 643 | + | ||
| 644 | + if (!err) { | ||
| 645 | + *prs = (Terminal *) loc_alloc_zero(sizeof(Terminal)); | ||
| 646 | + (*prs)->inp = fd_tty_master; | ||
| 647 | + (*prs)->out = fd_tty_master; | ||
| 648 | + (*prs)->err = fd_tty_master; | ||
| 649 | + (*prs)->pid = *pid; | ||
| 650 | + (*prs)->bcg = c->bcg; | ||
| 651 | + (*prs)->channel = c; | ||
| 652 | + if (*pty_type) | ||
| 653 | + snprintf((*prs)->pty_type, sizeof((*prs)->pty_type), "%s", pty_type); | ||
| 654 | + if (*encoding) | ||
| 655 | + snprintf((*prs)->encoding, sizeof((*prs)->encoding), "%s", encoding); | ||
| 656 | + (*prs)->width = size.ws_row; | ||
| 657 | + (*prs)->height = size.ws_col; | ||
| 658 | + list_add_first(&(*prs)->link, &terms_list); | ||
| 659 | + } | ||
| 660 | + | ||
| 661 | + if (!err) | ||
| 662 | + return 0; | ||
| 663 | + errno = err; | ||
| 664 | + return -1; | ||
| 665 | +} | ||
| 666 | + | ||
| 667 | +static void command_get_context(char * token, Channel * c) | ||
| 668 | +{ | ||
| 669 | + int err = 0; | ||
| 670 | + char id[256]; | ||
| 671 | + int tid; | ||
| 672 | + Terminal *term; | ||
| 673 | + | ||
| 674 | + json_read_string(&c->inp, id, sizeof(id)); | ||
| 675 | + if (read_stream(&c->inp) != 0) | ||
| 676 | + exception(ERR_JSON_SYNTAX); | ||
| 677 | + if (read_stream(&c->inp) != MARKER_EOM) | ||
| 678 | + exception(ERR_JSON_SYNTAX); | ||
| 679 | + | ||
| 680 | + tid = id2tid(id); | ||
| 681 | + write_stringz(&c->out, "R"); | ||
| 682 | + write_stringz(&c->out, token); | ||
| 683 | + | ||
| 684 | + if (tid == 0) { | ||
| 685 | + err = ERR_INV_CONTEXT; | ||
| 686 | + } else { | ||
| 687 | + term = find_terminal(tid); | ||
| 688 | + if (term == NULL) { | ||
| 689 | + err = ERR_INV_CONTEXT; | ||
| 690 | + } else { | ||
| 691 | + write_context(&c->out, tid); | ||
| 692 | + write_stream(&c->out, 0); | ||
| 693 | + } | ||
| 694 | + } | ||
| 695 | + | ||
| 696 | + write_errno(&c->out, err); | ||
| 697 | + write_stream(&c->out, MARKER_EOM); | ||
| 698 | +} | ||
| 699 | + | ||
| 700 | +static void command_launch(char * token, Channel * c) | ||
| 701 | +{ | ||
| 702 | + int pid = 0; | ||
| 703 | + int err = 0; | ||
| 704 | + char encoding[TERM_PROP_DEF_SIZE]; | ||
| 705 | + char pty_type[TERM_PROP_DEF_SIZE]; | ||
| 706 | + char *args[] = TERM_LAUNCH_ARGS; | ||
| 707 | + | ||
| 708 | + char ** envp = NULL; | ||
| 709 | + int envp_len = 0; | ||
| 710 | + | ||
| 711 | + Terminal * prs = NULL; | ||
| 712 | + Trap trap; | ||
| 713 | + | ||
| 714 | + if (set_trap(&trap)) { | ||
| 715 | + json_read_string(&c->inp, pty_type, sizeof(pty_type)); | ||
| 716 | + if (read_stream(&c->inp) != 0) | ||
| 717 | + exception(ERR_JSON_SYNTAX); | ||
| 718 | + json_read_string(&c->inp, encoding, sizeof(encoding)); | ||
| 719 | + if (read_stream(&c->inp) != 0) | ||
| 720 | + exception(ERR_JSON_SYNTAX); | ||
| 721 | + envp = json_read_alloc_string_array(&c->inp, &envp_len); | ||
| 722 | + if (read_stream(&c->inp) != 0) | ||
| 723 | + exception(ERR_JSON_SYNTAX); | ||
| 724 | + if (read_stream(&c->inp) != MARKER_EOM) | ||
| 725 | + exception(ERR_JSON_SYNTAX); | ||
| 726 | + | ||
| 727 | + if (err == 0 && start_terminal(c, pty_type, encoding, envp, envp_len, | ||
| 728 | + TERM_LAUNCH_EXEC, args, &pid, &prs) < 0) | ||
| 729 | + err = errno; | ||
| 730 | + if (prs != NULL) { | ||
| 731 | + write_terminal_input(prs); | ||
| 732 | + prs->out_struct = read_terminal_output(prs, prs->out, prs->out_id, | ||
| 733 | + sizeof(prs->out_id)); | ||
| 734 | + if (prs->out != prs->err) | ||
| 735 | + prs->err_struct = read_terminal_output(prs, prs->err, | ||
| 736 | + prs->err_id, sizeof(prs->err_id)); | ||
| 737 | + } | ||
| 738 | + if (!err) { | ||
| 739 | + add_waitpid_process(pid); | ||
| 740 | + } | ||
| 741 | + //write result back | ||
| 742 | + { | ||
| 743 | + write_stringz(&c->out, "R"); | ||
| 744 | + write_stringz(&c->out, token); | ||
| 745 | + write_errno(&c->out, err); | ||
| 746 | + if (err || pid == 0) { | ||
| 747 | + write_stringz(&c->out, "null"); | ||
| 748 | + } else { | ||
| 749 | + write_context(&c->out, pid); | ||
| 750 | + write_stream(&c->out, 0); | ||
| 751 | + } | ||
| 752 | + write_stream(&c->out, MARKER_EOM); | ||
| 753 | + } | ||
| 754 | + clear_trap(&trap); | ||
| 755 | + } | ||
| 756 | + | ||
| 757 | + loc_free(envp); | ||
| 758 | + | ||
| 759 | + if (trap.error) | ||
| 760 | + exception(trap.error); | ||
| 761 | +} | ||
| 762 | + | ||
| 763 | +static void command_set_win_size(char * token, Channel * c) | ||
| 764 | +{ | ||
| 765 | + int err = 0; | ||
| 766 | + struct winsize size; | ||
| 767 | + char id[256]; | ||
| 768 | + unsigned tid; | ||
| 769 | + Terminal *term = NULL; | ||
| 770 | + | ||
| 771 | + json_read_string(&c->inp, id, sizeof(id)); | ||
| 772 | + if (read_stream(&c->inp) != 0) | ||
| 773 | + exception(ERR_JSON_SYNTAX); | ||
| 774 | + size.ws_col=json_read_ulong(&c->inp); | ||
| 775 | + if (read_stream(&c->inp) != 0) | ||
| 776 | + exception(ERR_JSON_SYNTAX); | ||
| 777 | + size.ws_row=json_read_ulong(&c->inp); | ||
| 778 | + if (read_stream(&c->inp) != 0) | ||
| 779 | + exception(ERR_JSON_SYNTAX); | ||
| 780 | + if (read_stream(&c->inp) != MARKER_EOM) | ||
| 781 | + exception(ERR_JSON_SYNTAX); | ||
| 782 | + | ||
| 783 | + tid = id2tid(id); | ||
| 784 | + | ||
| 785 | + if(tid==0 || (term=find_terminal(tid))==NULL) { | ||
| 786 | + err=ERR_INV_CONTEXT; | ||
| 787 | + }else if (term->width != size.ws_col || term->height != size.ws_row) { | ||
| 788 | + if(ioctl(term->inp,TIOCSWINSZ,&size)<0) { | ||
| 789 | + err=errno; | ||
| 790 | + } | ||
| 791 | + if(!err) { | ||
| 792 | + term->width=size.ws_col; | ||
| 793 | + term->height=size.ws_row; | ||
| 794 | + send_event_terminal_win_size_changed(&term->channel->out,term); | ||
| 795 | + } | ||
| 796 | + } | ||
| 797 | + | ||
| 798 | + write_stringz(&c->out, "R"); | ||
| 799 | + write_stringz(&c->out, token); | ||
| 800 | + write_errno(&c->out, err); | ||
| 801 | + write_stream(&c->out, MARKER_EOM); | ||
| 802 | + | ||
| 803 | +} | ||
| 804 | + | ||
| 805 | +static void waitpid_listener(int pid, int exited, int exit_code, int signal, | ||
| 806 | + int event_code, int syscall, void * args) | ||
| 807 | +{ | ||
| 808 | + if (exited) { | ||
| 809 | + Terminal * prs = find_terminal(pid); | ||
| 810 | + if (prs) { | ||
| 811 | + if (signal != 0) | ||
| 812 | + prs->exit_code = -signal; | ||
| 813 | + else | ||
| 814 | + prs->exit_code = exit_code; | ||
| 815 | + terminal_exited(prs); | ||
| 816 | + } | ||
| 817 | + } | ||
| 818 | +} | ||
| 819 | + | ||
| 820 | +static void channel_close_listener(Channel * c) | ||
| 821 | +{ | ||
| 822 | + LINK * l = NULL; | ||
| 823 | + | ||
| 824 | + for (l = terms_list.next; l != &terms_list;) { | ||
| 825 | + Terminal * term = link2term(l); | ||
| 826 | + l = l->next; | ||
| 827 | + if (term->channel == c) { | ||
| 828 | + trace(LOG_ALWAYS, "Terminal is left launched: T%d", term->pid); | ||
| 829 | + kill_term(term); | ||
| 830 | + } | ||
| 831 | + } | ||
| 832 | +} | ||
| 833 | + | ||
| 834 | +void ini_terminals_service(Protocol * proto) | ||
| 835 | +{ | ||
| 836 | +#if defined(_WRS_KERNEL) | ||
| 837 | + prs_list_lock = semMCreate(SEM_Q_PRIORITY); | ||
| 838 | + if (prs_list_lock == NULL) check_error(errno); | ||
| 839 | + if (taskCreateHookAdd((FUNCPTR)task_create_hook) != OK) check_error(errno); | ||
| 840 | + if (taskDeleteHookAdd((FUNCPTR)task_delete_hook) != OK) check_error(errno); | ||
| 841 | +#endif | ||
| 842 | + list_init(&terms_list); | ||
| 843 | + | ||
| 844 | + add_waitpid_listener(waitpid_listener, NULL); | ||
| 845 | + add_channel_close_listener(channel_close_listener); | ||
| 846 | + | ||
| 847 | + add_command_handler(proto, TERMINALS, "getContext", command_get_context); | ||
| 848 | + add_command_handler(proto, TERMINALS, "launch", command_launch); | ||
| 849 | + add_command_handler(proto, TERMINALS, "exit", command_exit); | ||
| 850 | + add_command_handler(proto, TERMINALS, "setWinSize", command_set_win_size); | ||
| 851 | +} | ||
| 852 | Index: org.eclipse.tm.tcf.terminals.agent/main/services-ext.h | ||
| 853 | =================================================================== | ||
| 854 | --- org.eclipse.tm.tcf.terminals.agent/main/services-ext.h (revision 0) | ||
| 855 | +++ org.eclipse.tm.tcf.terminals.agent/main/services-ext.h (revision 0) | ||
| 856 | @@ -0,0 +1,25 @@ | ||
| 857 | +/******************************************************************************* | ||
| 858 | + * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. | ||
| 859 | + * All rights reserved. This program and the accompanying materials | ||
| 860 | + * are made available under the terms of the Eclipse Public License v1.0 | ||
| 861 | + * and Eclipse Distribution License v1.0 which accompany this distribution. | ||
| 862 | + * The Eclipse Public License is available at | ||
| 863 | + * http://www.eclipse.org/legal/epl-v10.html | ||
| 864 | + * and the Eclipse Distribution License is available at | ||
| 865 | + * http://www.eclipse.org/org/documents/edl-v10.php. | ||
| 866 | + * | ||
| 867 | + * Contributors: | ||
| 868 | + * Wind River Systems - initial API and implementation | ||
| 869 | + *******************************************************************************/ | ||
| 870 | + | ||
| 871 | +/* | ||
| 872 | + * Services initialization code extension point. | ||
| 873 | + * If the agent is built with additional user-defined services, | ||
| 874 | + * a customized version of services-ext.h file can be added to compiler headers search paths. | ||
| 875 | + */ | ||
| 876 | + | ||
| 877 | +#include "terminals.h" | ||
| 878 | + | ||
| 879 | +static void ini_ext_services(Protocol * proto, TCFBroadcastGroup * bcg) { | ||
| 880 | + ini_terminals_service(proto); | ||
| 881 | +} | ||
| 882 | Index: org.eclipse.tm.tcf.terminals.agent/terminals.h | ||
| 883 | =================================================================== | ||
| 884 | --- org.eclipse.tm.tcf.terminals.agent/terminals.h (revision 0) | ||
| 885 | +++ org.eclipse.tm.tcf.terminals.agent/terminals.h (revision 0) | ||
| 886 | @@ -0,0 +1,27 @@ | ||
| 887 | +/******************************************************************************* | ||
| 888 | + * Copyright (c) 2008 Wind River Systems, Inc. and others. | ||
| 889 | + * All rights reserved. This program and the accompanying materials | ||
| 890 | + * are made available under the terms of the Eclipse Public License v1.0 | ||
| 891 | + * and Eclipse Distribution License v1.0 which accompany this distribution. | ||
| 892 | + * The Eclipse Public License is available at | ||
| 893 | + * http://www.eclipse.org/legal/epl-v10.html | ||
| 894 | + * and the Eclipse Distribution License is available at | ||
| 895 | + * http://www.eclipse.org/org/documents/edl-v10.php. | ||
| 896 | + * | ||
| 897 | + * Contributors: | ||
| 898 | + * Wind River Systems - initial API and implementation | ||
| 899 | + *******************************************************************************/ | ||
| 900 | + | ||
| 901 | +/* | ||
| 902 | + * Sample TCF service header file. | ||
| 903 | + */ | ||
| 904 | + | ||
| 905 | +#ifndef TERMINALS_H_ | ||
| 906 | +#define TERMINALS_H_ | ||
| 907 | + | ||
| 908 | +#include <config.h> | ||
| 909 | +#include <framework/protocol.h> | ||
| 910 | + | ||
| 911 | +extern void ini_terminals_service(Protocol * proto); | ||
| 912 | + | ||
| 913 | +#endif /*TERMINALS_H_*/ | ||
| 914 | Index: org.eclipse.tm.tcf.terminals.agent/config.h | ||
| 915 | =================================================================== | ||
| 916 | --- org.eclipse.tm.tcf.terminals.agent/config.h (revision 0) | ||
| 917 | +++ org.eclipse.tm.tcf.terminals.agent/config.h (revision 0) | ||
| 918 | @@ -0,0 +1,63 @@ | ||
| 919 | +/******************************************************************************* | ||
| 920 | + * Copyright (c) 2008 Wind River Systems, Inc. and others. | ||
| 921 | + * All rights reserved. This program and the accompanying materials | ||
| 922 | + * are made available under the terms of the Eclipse Public License v1.0 | ||
| 923 | + * and Eclipse Distribution License v1.0 which accompany this distribution. | ||
| 924 | + * The Eclipse Public License is available at | ||
| 925 | + * http://www.eclipse.org/legal/epl-v10.html | ||
| 926 | + * and the Eclipse Distribution License is available at | ||
| 927 | + * http://www.eclipse.org/org/documents/edl-v10.php. | ||
| 928 | + * | ||
| 929 | + * Contributors: | ||
| 930 | + * Wind River Systems - initial API and implementation | ||
| 931 | + *******************************************************************************/ | ||
| 932 | + | ||
| 933 | +/* | ||
| 934 | + * This file contains "define" statements that control agent configuration. | ||
| 935 | + * SERVICE_* definitions control which service implementations are included into the agent. | ||
| 936 | + * | ||
| 937 | + * This is example agent configuration. It includes only few standard services, | ||
| 938 | + * and one example service: Day Time. | ||
| 939 | + */ | ||
| 940 | + | ||
| 941 | +#ifndef D_config | ||
| 942 | +#define D_config | ||
| 943 | + | ||
| 944 | +#include <framework/mdep.h> | ||
| 945 | + | ||
| 946 | +#if defined(WIN32) || defined(__CYGWIN__) | ||
| 947 | +# define TARGET_UNIX 0 | ||
| 948 | +#elif defined(_WRS_KERNEL) | ||
| 949 | +# define TARGET_UNIX 0 | ||
| 950 | +#else | ||
| 951 | +# define TARGET_UNIX 1 | ||
| 952 | +#endif | ||
| 953 | + | ||
| 954 | +#define SERVICE_Locator 1 | ||
| 955 | +#define SERVICE_Processes 1 | ||
| 956 | +#define SERVICE_Streams 1 | ||
| 957 | +#define SERVICE_FileSystem 1 | ||
| 958 | +#define SERVICE_SysMonitor TARGET_UNIX | ||
| 959 | + | ||
| 960 | +#define ENABLE_ZeroCopy 1 | ||
| 961 | + | ||
| 962 | +#if !defined(ENABLE_Splice) | ||
| 963 | +# if ENABLE_ZeroCopy | ||
| 964 | +# include <fcntl.h> | ||
| 965 | +# if defined(SPLICE_F_MOVE) | ||
| 966 | +# define ENABLE_Splice 1 | ||
| 967 | +# else | ||
| 968 | +# define ENABLE_Splice 0 | ||
| 969 | +# endif | ||
| 970 | +# else | ||
| 971 | +# define ENABLE_Splice 0 | ||
| 972 | +# endif | ||
| 973 | +#endif | ||
| 974 | + | ||
| 975 | +#define ENABLE_SSL 0 | ||
| 976 | + | ||
| 977 | +#define ENABLE_Trace 1 | ||
| 978 | +#define ENABLE_Discovery 1 | ||
| 979 | + | ||
| 980 | + | ||
| 981 | +#endif /* D_config */ | ||
| 982 | Index: org.eclipse.tm.tcf.terminals.agent/Makefile | ||
| 983 | =================================================================== | ||
| 984 | --- org.eclipse.tm.tcf.terminals.agent/Makefile (revision 0) | ||
| 985 | +++ org.eclipse.tm.tcf.terminals.agent/Makefile (revision 0) | ||
| 986 | @@ -0,0 +1,39 @@ | ||
| 987 | +TCF_AGENT_DIR=../agent | ||
| 988 | + | ||
| 989 | +include $(TCF_AGENT_DIR)/Makefile.inc | ||
| 990 | + | ||
| 991 | +override CFLAGS += $(foreach dir,$(INCDIRS),-I$(dir)) $(OPTS) | ||
| 992 | + | ||
| 993 | +HFILES := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.h)) $(HFILES) | ||
| 994 | +CFILES := $(sort $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c)) $(CFILES)) | ||
| 995 | + | ||
| 996 | +#no using SSL | ||
| 997 | +LIBS = -lpthread -lrt | ||
| 998 | + | ||
| 999 | +EXECS = $(BINDIR)/agent$(EXTEXE) | ||
| 1000 | + | ||
| 1001 | +all: $(EXECS) | ||
| 1002 | + | ||
| 1003 | +$(BINDIR)/libtcf$(EXTLIB) : $(OFILES) | ||
| 1004 | + $(AR) rcs $@ $^ | ||
| 1005 | + | ||
| 1006 | +$(BINDIR)/agent$(EXTEXE): $(BINDIR)/main/main$(EXTOBJ) $(BINDIR)/libtcf$(EXTLIB) | ||
| 1007 | + $(CC) $(CFLAGS) -o $@ $(BINDIR)/main/main$(EXTOBJ) $(BINDIR)/libtcf$(EXTLIB) $(LIBS) | ||
| 1008 | + | ||
| 1009 | +$(BINDIR)/%$(EXTOBJ): %.c $(HFILES) Makefile | ||
| 1010 | + @mkdir -p $(dir $@) | ||
| 1011 | + $(CC) $(CFLAGS) -c -o $@ $< | ||
| 1012 | + | ||
| 1013 | +$(BINDIR)/%$(EXTOBJ): $(TCF_AGENT_DIR)/%.c $(HFILES) Makefile | ||
| 1014 | + @mkdir -p $(dir $@) | ||
| 1015 | + $(CC) $(CFLAGS) -c -o $@ $< | ||
| 1016 | + | ||
| 1017 | +install: all | ||
| 1018 | + install -d -m 755 $(INSTALLROOT)$(SBIN) | ||
| 1019 | + install -d -m 755 $(INSTALLROOT)$(INIT) | ||
| 1020 | + install -c $(BINDIR)/agent -m 755 $(INSTALLROOT)$(SBIN)/tcf-agent | ||
| 1021 | + install -c $(TCF_AGENT_DIR)/main/tcf-agent.init -m 755 $(INSTALLROOT)$(INIT)/tcf-agent | ||
| 1022 | + | ||
| 1023 | +clean: | ||
| 1024 | + rm -rf $(BINDIR) | ||
| 1025 | + | ||
diff --git a/meta/packages/tcf-agent/tcf-agent_svn.bb b/meta/packages/tcf-agent/tcf-agent_svn.bb new file mode 100644 index 0000000000..b4c70ec8b8 --- /dev/null +++ b/meta/packages/tcf-agent/tcf-agent_svn.bb | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | DESCRIPTION = "Target Communication Framework" | ||
| 2 | HOMEPAGE = "http://dsdp.eclipse.org/dsdp/tm/" | ||
| 3 | BUGTRACKER = "https://bugs.eclipse.org/bugs/" | ||
| 4 | |||
| 5 | LICENSE = "EPLv1.0 | EDLv1.0" | ||
| 6 | LIC_FILES_CHKSUM = "file://../epl-v10.html;md5=7aa4215a330a0a4f6a1cbf8da1a0879f \ | ||
| 7 | file://../agent/edl-v10.html;md5=522a390a83dc186513f0500543ad3679" | ||
| 8 | |||
| 9 | PV = "0.3.0+svnr${SRCREV}" | ||
| 10 | PR = "r0" | ||
| 11 | |||
| 12 | SRC_URI = "svn://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/;module=tags/0.3.0/;proto=http \ | ||
| 13 | file://terminals_agent.patch \ | ||
| 14 | file://fix_tcf-agent.init.patch" | ||
| 15 | |||
| 16 | S = "${WORKDIR}/tags/0.3.0/tcf-agent" | ||
| 17 | |||
| 18 | inherit update-rc.d | ||
| 19 | |||
| 20 | INITSCRIPT_NAME = "tcf-agent" | ||
| 21 | INITSCRIPT_PARAMS = "start 999 3 5 . stop 20 0 1 2 6 ." | ||
| 22 | |||
| 23 | # mangling needed for make | ||
| 24 | MAKE_ARCH = `echo ${TARGET_ARCH} | sed s,i.86,i686,` | ||
| 25 | MAKE_OS = `echo ${TARGET_OS} | sed s,linux,GNU/Linux,` | ||
| 26 | |||
| 27 | EXTRA_OEMAKE = "MACHINE=${MAKE_ARCH} OPSYS=${MAKE_OS} 'CC=${CC}' 'AR=${AR}'" | ||
| 28 | |||
| 29 | do_compile() { | ||
| 30 | oe_runmake | ||
| 31 | } | ||
| 32 | |||
| 33 | do_install() { | ||
| 34 | oe_runmake install INSTALLROOT=${D} | ||
| 35 | } | ||
| 36 | |||
