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 f8262fdcf..2edc019ac 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" SRCREV_pn-opkg-utils-native ??= "4747" SRCREV_pn-opkg-utils ??= "4747" SRCREV_pn-oprofileui ??= "197" +SRCREV_pn-tcf-agent ??= "1078" SRCREV_pn-osc-native ??= "9096" SRCREV_pn-owl-video ??= "394" SRCREV_pn-pkgconfig ??= "66d49f1375fec838bcd301bb4ca2ef76cee0e47c" diff --git a/meta/packages/tasks/task-poky-tools.bb b/meta/packages/tasks/task-poky-tools.bb index bebda285f..3872cd563 100644 --- a/meta/packages/tasks/task-poky-tools.bb +++ b/meta/packages/tasks/task-poky-tools.bb @@ -31,6 +31,7 @@ KEXECTOOLS_powerpc ?= "" RDEPENDS_task-poky-tools-debug = "\ gdb \ gdbserver \ + tcf-agent \ strace" 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 000000000..66d403b62 --- /dev/null +++ b/meta/packages/tcf-agent/tcf-agent/fix_tcf-agent.init.patch @@ -0,0 +1,92 @@ +--- a/Makefile ++++ b/Makefile +@@ -32,7 +32,7 @@ + install -d -m 755 $(INSTALLROOT)$(SBIN) + install -d -m 755 $(INSTALLROOT)$(INIT) + install -c $(BINDIR)/agent -m 755 $(INSTALLROOT)$(SBIN)/tcf-agent +- install -c $(TCF_AGENT_DIR)/main/tcf-agent.init -m 755 $(INSTALLROOT)$(INIT)/tcf-agent ++ install -c tcf-agent.init -m 755 $(INSTALLROOT)$(INIT)/tcf-agent + + clean: + rm -rf $(BINDIR) +--- /dev/null ++++ b/tcf-agent.init +@@ -0,0 +1,78 @@ ++#!/bin/sh ++### BEGIN INIT INFO ++# Provides: tcf-agent ++# Default-Start: 3 5 ++# Default-Stop: 0 1 2 6 ++# Short-Description: Target Communication Framework agent ++### END INIT INFO ++ ++DAEMON_PATH=/usr/sbin/tcf-agent ++DAEMON_NAME=`basename $DAEMON_PATH` ++ ++. /etc/init.d/functions ++ ++test -x $DAEMON_PATH || exit 0 ++ ++PATH=/sbin:/usr/sbin:/bin:/usr/bin ++export PATH ++ ++RETVAL=0 ++ ++case "$1" in ++ start) ++ echo -n "Starting $DAEMON_NAME: " ++ $DAEMON_PATH -d -L- -l0 -s SSL: ++ RETVAL=$? ++ if [ $RETVAL -eq 0 ] ; then ++ echo "OK" ++ touch /var/lock/subsys/$DAEMON_NAME ++ else ++ echo "FAIL" ++ fi ++ ;; ++ ++ stop) ++ echo -n "Stopping $DAEMON_NAME: " ++ count=0 ++ while [ -n "`/bin/pidof $DAEMON_PATH`" -a $count -lt 10 ] ; do ++ killproc $DAEMON_PATH >& /dev/null ++ sleep 1 ++ RETVAL=$? ++ if [ $RETVAL != 0 -o -n "`/bin/pidof $DAEMON_PATH`" ] ; then ++ sleep 3 ++ fi ++ count=`expr $count + 1` ++ done ++ rm -f /var/lock/subsys/$DAEMON_NAME ++ if [ -n "`/bin/pidof $DAEMON_PATH`" ] ; then ++ echo "FAIL" ++ else ++ echo "OK" ++ fi ++ ;; ++ ++ restart) ++ $0 stop ++ sleep 1 ++ $0 start ++ ;; ++ ++ status) ++ if [ -n "`/bin/pidof $DAEMON_PATH`" ] ; then ++ echo "$DAEMON_NAME is running" ++ else ++ echo "$DAEMON_NAME is not running" ++ fi ++ ;; ++ ++ condrestart) ++ [ -f /var/lock/subsys/$DAEMON_NAME ] && $0 restart ++ ;; ++ ++ *) ++ echo "usage: $0 { start | stop | restart | condrestart | status }" ++ ;; ++esac ++ ++exit $RETVAL ++ 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 000000000..b88b5e70c --- /dev/null +++ b/meta/packages/tcf-agent/tcf-agent/terminals_agent.patch @@ -0,0 +1,1025 @@ +Index: org.eclipse.tm.tcf.terminals.agent/terminals.c +=================================================================== +--- org.eclipse.tm.tcf.terminals.agent/terminals.c (revision 0) ++++ org.eclipse.tm.tcf.terminals.agent/terminals.c (revision 0) +@@ -0,0 +1,846 @@ ++/******************************************************************************* ++ * Copyright (c) 2008 Wind River Systems, Inc. and others. ++ * All rights reserved. This program and the accompanying materials ++ * are made available under the terms of the Eclipse Public License v1.0 ++ * and Eclipse Distribution License v1.0 which accompany this distribution. ++ * The Eclipse Public License is available at ++ * http://www.eclipse.org/legal/epl-v10.html ++ * and the Eclipse Distribution License is available at ++ * http://www.eclipse.org/org/documents/edl-v10.php. ++ * ++ * Contributors: ++ * Wind River Systems - initial API and implementation ++ *******************************************************************************/ ++ ++/* ++ * Sample TCF service implementation. ++ */ ++ ++#include <config.h> ++#include <stdlib.h> ++#include <stdio.h> ++#include <string.h> ++#include <errno.h> ++#include <fcntl.h> ++#include <signal.h> ++#include <assert.h> ++#include <termios.h> ++#ifndef TIOCGWINSZ ++#include <sys/ioctl.h> ++#endif ++#include <framework/myalloc.h> ++#include <framework/protocol.h> ++#include <framework/trace.h> ++#include <framework/context.h> ++#include <framework/json.h> ++#include <framework/asyncreq.h> ++#include <framework/exceptions.h> ++#include <framework/waitpid.h> ++#include <framework/signames.h> ++#include <services/streamsservice.h> ++#include <terminals.h> ++ ++#define TERMINALS_DEBUG 1 ++ ++#define TERMINALS_NO_LOGIN 0 ++ ++static const char * TERMINALS = "Terminals"; ++ ++#if defined(WIN32) ++# include <tlhelp32.h> ++# ifdef _MSC_VER ++# pragma warning(disable:4201) /* nonstandard extension used : nameless struct/union (in winternl.h) */ ++# include <winternl.h> ++# else ++# include <ntdef.h> ++# endif ++# ifndef STATUS_INFO_LENGTH_MISMATCH ++# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) ++# endif ++# ifndef SystemHandleInformation ++# define SystemHandleInformation 16 ++# endif ++# error("unsupported WIN32!") ++#elif defined(_WRS_KERNEL) ++# include <symLib.h> ++# include <sysSymTbl.h> ++# include <ioLib.h> ++# include <ptyDrv.h> ++# include <taskHookLib.h> ++# error("unsupported WRS!") ++#else ++# include <sys/stat.h> ++# include <unistd.h> ++# include <dirent.h> ++# if TERMINALS_NO_LOGIN ++# define TERM_LAUNCH_EXEC "/bin/bash" ++# define TERM_LAUNCH_ARGS {TERM_LAUNCH_EXEC, NULL} ++# else ++# define TERM_LAUNCH_EXEC "/bin/login" ++# define TERM_LAUNCH_ARGS {TERM_LAUNCH_EXEC, "-p", NULL} ++# endif ++#endif ++ ++#define PIPE_SIZE 0x1000 ++#define TERM_PROP_DEF_SIZE 256 ++ ++typedef struct Terminal ++{ ++ LINK link; ++ int pid; /*pid of the login process of the terminal*/ ++ TCFBroadcastGroup * bcg; ++ int inp; ++ int out; ++ int err; ++ struct TerminalInput * inp_struct; ++ struct TerminalOutput * out_struct; ++ struct TerminalOutput * err_struct; ++ char inp_id[256]; ++ char out_id[256]; ++ char err_id[256]; ++ ++ char pty_type[TERM_PROP_DEF_SIZE]; ++ char encoding[TERM_PROP_DEF_SIZE]; ++ unsigned long width; ++ unsigned long height; ++ long exit_code; ++ ++ Channel *channel; ++} Terminal; ++ ++typedef struct TerminalOutput ++{ ++ Terminal * prs; ++ AsyncReqInfo req; ++ int req_posted; ++ char buf[PIPE_SIZE]; ++ size_t buf_pos; ++ int eos; ++ VirtualStream * vstream; ++} TerminalOutput; ++ ++typedef struct TerminalInput ++{ ++ Terminal * prs; ++ AsyncReqInfo req; ++ int req_posted; ++ char buf[PIPE_SIZE]; ++ size_t buf_pos; ++ size_t buf_len; ++ int eos; ++ VirtualStream * vstream; ++} TerminalInput; ++ ++#define link2term(A) ((Terminal *)((char *)(A) - offsetof(Terminal, link))) ++ ++static LINK terms_list; ++#if defined(_WRS_KERNEL) ++static SEM_ID prs_list_lock = NULL; ++#endif ++ ++static Terminal * find_terminal(int pid) ++{ ++ LINK * qhp = &terms_list; ++ LINK * qp = qhp->next; ++ ++ while (qp != qhp) { ++ Terminal * prs = link2term(qp); ++ if (prs->pid == pid) ++ return prs; ++ qp = qp->next; ++ } ++ return NULL; ++} ++ ++static char * tid2id(int tid) ++{ ++ static char s[64]; ++ char * p = s + sizeof(s); ++ unsigned long n = (long) tid; ++ *(--p) = 0; ++ do { ++ *(--p) = (char) (n % 10 + '0'); ++ n = n / 10; ++ } while (n != 0); ++ ++ *(--p) = 'T'; ++ return p; ++} ++ ++static int id2tid(const char * id) ++{ ++ int tid = 0; ++ if (id == NULL) ++ return 0; ++ if (id[0] != 'T') ++ return 0; ++ if (id[1] == 0) ++ return 0; ++ tid = (unsigned) strtol(id + 1, (char **) &id, 10); ++ if (id[0] != 0) ++ return 0; ++ return tid; ++} ++ ++static void write_context(OutputStream * out, int tid) ++{ ++ Terminal * prs = find_terminal(tid); ++ ++ write_stream(out, '{'); ++ ++ if (prs != NULL) { ++ if (*prs->pty_type) { ++ json_write_string(out, "PtyType"); ++ write_stream(out, ':'); ++ json_write_string(out, prs->pty_type); ++ write_stream(out, ','); ++ } ++ ++ if (*prs->encoding) { ++ json_write_string(out, "Encoding"); ++ write_stream(out, ':'); ++ json_write_string(out, prs->encoding); ++ write_stream(out, ','); ++ } ++ ++ json_write_string(out, "Width"); ++ write_stream(out, ':'); ++ json_write_ulong(out, prs->width); ++ write_stream(out, ','); ++ ++ json_write_string(out, "Height"); ++ write_stream(out, ':'); ++ json_write_ulong(out, prs->height); ++ write_stream(out, ','); ++ ++ if (*prs->inp_id) { ++ json_write_string(out, "StdInID"); ++ write_stream(out, ':'); ++ json_write_string(out, prs->inp_id); ++ write_stream(out, ','); ++ } ++ if (*prs->out_id) { ++ json_write_string(out, "StdOutID"); ++ write_stream(out, ':'); ++ json_write_string(out, prs->out_id); ++ write_stream(out, ','); ++ } ++ if (*prs->err_id) { ++ json_write_string(out, "StdErrID"); ++ write_stream(out, ':'); ++ json_write_string(out, prs->err_id); ++ write_stream(out, ','); ++ } ++ } ++ ++ json_write_string(out, "ID"); ++ write_stream(out, ':'); ++ json_write_string(out, tid2id(tid)); ++ ++ write_stream(out, '}'); ++} ++ ++static void send_event_terminal_exited(OutputStream * out, Terminal * prs) ++{ ++ write_stringz(out, "E"); ++ write_stringz(out, TERMINALS); ++ write_stringz(out, "exited"); ++ ++ json_write_string(out, tid2id(prs->pid)); ++ write_stream(out, 0); ++ ++ json_write_ulong(out, prs->exit_code); ++ write_stream(out, 0); ++ ++ write_stream(out, MARKER_EOM); ++} ++ ++static void send_event_terminal_win_size_changed(OutputStream * out, ++ Terminal * prs) ++{ ++ write_stringz(out, "E"); ++ write_stringz(out, TERMINALS); ++ write_stringz(out, "winSizeChanged"); ++ ++ json_write_string(out, tid2id(prs->pid)); ++ write_stream(out, 0); ++ ++ json_write_long(out, prs->width); ++ write_stream(out, 0); ++ ++ json_write_long(out, prs->height); ++ write_stream(out, 0); ++ ++ write_stream(out, MARKER_EOM); ++} ++ ++static int kill_term(Terminal *term) ++{ ++ int err = 0; ++ ++#if defined(WIN32) ++ HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, term->pid); ++ if (h == NULL) ++ { ++ err = set_win32_errno(GetLastError()); ++ } ++ else ++ { ++ if (!TerminateProcess(h, 1)) err = set_win32_errno(GetLastError()); ++ if (!CloseHandle(h) && !err) err = set_win32_errno(GetLastError()); ++ } ++#else ++ if (kill(term->pid, SIGTERM) < 0) ++ err = errno; ++#endif ++ return err; ++} ++ ++static void command_exit(char * token, Channel * c) ++{ ++ int err = 0; ++ char id[256]; ++ unsigned tid; ++ Terminal *term = NULL; ++ ++ json_read_string(&c->inp, id, sizeof(id)); ++ if (read_stream(&c->inp) != 0) ++ exception(ERR_JSON_SYNTAX); ++ if (read_stream(&c->inp) != MARKER_EOM) ++ exception(ERR_JSON_SYNTAX); ++ ++ tid = id2tid(id); ++ write_stringz(&c->out, "R"); ++ write_stringz(&c->out, token); ++ ++ if (tid == 0) { ++ err = ERR_INV_CONTEXT; ++ } else { ++ term = find_terminal(tid); ++ if (term == NULL) { ++ err = ERR_INV_CONTEXT; ++ } else { ++ err = kill_term(term); ++ } ++ } ++ ++ write_errno(&c->out, err); ++ write_stream(&c->out, MARKER_EOM); ++} ++ ++static void terminal_exited(Terminal * prs) ++{ ++ Trap trap; ++ ++ if (set_trap(&trap)) { ++ send_event_terminal_exited(&prs->bcg->out, prs); ++ clear_trap(&trap); ++ } else { ++ trace(LOG_ALWAYS, "Exception sending terminal exited event: %d %s", ++ trap.error, errno_to_str(trap.error)); ++ } ++ ++#if defined(_WRS_KERNEL) ++ semTake(prs_list_lock, WAIT_FOREVER); ++#endif ++ list_remove(&prs->link); ++ close(prs->inp); ++ close(prs->out); ++ if (prs->out != prs->err) ++ close(prs->err); ++ if (prs->inp_struct) { ++ TerminalInput * inp = prs->inp_struct; ++ if (!inp->req_posted) { ++ virtual_stream_delete(inp->vstream); ++ loc_free(inp); ++ } else { ++ inp->prs = NULL; ++ } ++ } ++ if (prs->out_struct) ++ prs->out_struct->prs = NULL; ++ if (prs->err_struct) ++ prs->err_struct->prs = NULL; ++ loc_free(prs); ++#if defined(_WRS_KERNEL) ++ semGive(prs_list_lock); ++#endif ++} ++ ++static void terminal_input_streams_callback(VirtualStream * stream, ++ int event_code, void * args) ++{ ++ TerminalInput * inp = (TerminalInput *) args; ++ ++ assert(inp->vstream == stream); ++ if (!inp->req_posted) { ++ if (inp->buf_pos >= inp->buf_len && !inp->eos) { ++ inp->buf_pos = inp->buf_len = 0; ++ virtual_stream_get_data(stream, inp->buf, sizeof(inp->buf), ++ &inp->buf_len, &inp->eos); ++ } ++ if (inp->buf_pos < inp->buf_len) { ++ inp->req.u.fio.bufp = inp->buf + inp->buf_pos; ++ inp->req.u.fio.bufsz = inp->buf_len - inp->buf_pos; ++ inp->req_posted = 1; ++ async_req_post(&inp->req); ++ } ++ } ++} ++ ++static void write_terminal_input_done(void * x) ++{ ++ AsyncReqInfo * req = (AsyncReqInfo *) x; ++ TerminalInput * inp = (TerminalInput *) req->client_data; ++ ++ inp->req_posted = 0; ++ if (inp->prs == NULL) { ++ /* Process has exited */ ++ virtual_stream_delete(inp->vstream); ++ loc_free(inp); ++ } else { ++ int wr = inp->req.u.fio.rval; ++ ++ if (wr < 0) { ++ int err = inp->req.error; ++ trace(LOG_ALWAYS, "Can't write terminal input stream: %d %s", err, ++ errno_to_str(err)); ++ inp->buf_pos = inp->buf_len = 0; ++ } else { ++ inp->buf_pos += wr; ++ } ++ ++ terminal_input_streams_callback(inp->vstream, 0, inp); ++ } ++} ++ ++static void write_terminal_input(Terminal * prs) ++{ ++ TerminalInput * inp = prs->inp_struct = (TerminalInput *) loc_alloc_zero( ++ sizeof(TerminalInput)); ++ inp->prs = prs; ++ inp->req.client_data = inp; ++ inp->req.done = write_terminal_input_done; ++ inp->req.type = AsyncReqWrite; ++ inp->req.u.fio.fd = prs->inp; ++ virtual_stream_create(TERMINALS, tid2id(prs->pid), PIPE_SIZE, ++ VS_ENABLE_REMOTE_WRITE, terminal_input_streams_callback, inp, ++ &inp->vstream); ++ virtual_stream_get_id(inp->vstream, prs->inp_id, sizeof(prs->inp_id)); ++} ++ ++static void terminal_output_streams_callback(VirtualStream * stream, ++ int event_code, void * args) ++{ ++ TerminalOutput * out = (TerminalOutput *) args; ++ ++ assert(out->vstream == stream); ++ if (!out->req_posted) { ++ int buf_len = out->req.u.fio.rval; ++ int err = 0; ++ int eos = 0; ++ ++ if (buf_len < 0) { ++ buf_len = 0; ++ err = out->req.error; ++ } ++ if (buf_len == 0) ++ eos = 1; ++ if (out->prs == NULL) { ++ eos = 1; ++ err = 0; ++ } ++ ++ assert(buf_len <= (int)sizeof(out->buf)); ++ assert(out->buf_pos <= (size_t)buf_len); ++ assert(out->req.u.fio.bufp == out->buf); ++#ifdef __linux__ ++ if (err == EIO) ++ err = 0; ++#endif ++ if (err) ++ trace(LOG_ALWAYS, "Can't read terminal output stream: %d %s", err, ++ errno_to_str(err)); ++ ++ if (out->buf_pos < (size_t) buf_len || out->eos != eos) { ++ size_t done = 0; ++ virtual_stream_add_data(stream, out->buf + out->buf_pos, buf_len ++ - out->buf_pos, &done, eos); ++ out->buf_pos += done; ++ if (eos) ++ out->eos = 1; ++ } ++ ++ if (out->buf_pos >= (size_t) buf_len) { ++ if (!eos) { ++ out->req_posted = 1; ++ async_req_post(&out->req); ++ } else if (virtual_stream_is_empty(stream)) { ++ if (out->prs != NULL) { ++ if (out == out->prs->out_struct) ++ out->prs->out_struct = NULL; ++ if (out == out->prs->err_struct) ++ out->prs->err_struct = NULL; ++ } ++ virtual_stream_delete(stream); ++ loc_free(out); ++ } ++ } ++ } // end if(!out->req_posted) ++} ++ ++static void read_terminal_output_done(void * x) ++{ ++ AsyncReqInfo * req = (AsyncReqInfo *) x; ++ TerminalOutput * out = (TerminalOutput *) req->client_data; ++ ++ out->buf_pos = 0; ++ out->req_posted = 0; ++ terminal_output_streams_callback(out->vstream, 0, out); ++} ++ ++static TerminalOutput * read_terminal_output(Terminal * prs, int fd, char * id, ++ size_t id_size) ++{ ++ TerminalOutput * out = (TerminalOutput *) loc_alloc_zero( ++ sizeof(TerminalOutput)); ++ out->prs = prs; ++ out->req.client_data = out; ++ out->req.done = read_terminal_output_done; ++ out->req.type = AsyncReqRead; ++ out->req.u.fio.bufp = out->buf; ++ out->req.u.fio.bufsz = sizeof(out->buf); ++ out->req.u.fio.fd = fd; ++ virtual_stream_create(TERMINALS, tid2id(prs->pid), PIPE_SIZE, ++ VS_ENABLE_REMOTE_READ, terminal_output_streams_callback, out, ++ &out->vstream); ++ virtual_stream_get_id(out->vstream, id, id_size); ++ out->req_posted = 1; ++ async_req_post(&out->req); ++ return out; ++} ++ ++static char **envp_add(char **old_envp, int old_envp_len, char *env) ++{ ++ char **new_envp = NULL; ++ int i; ++ int env_size; ++ int old_envp_size; ++ ++ assert(old_envp || (old_envp==NULL && old_envp_len==0)); ++ assert(env); ++ assert(*env); ++ ++ for (i = 0, old_envp_size = 0; i < old_envp_len; i++) { ++ old_envp_size += sizeof(char *); //size of env pointer ++ old_envp_size += strlen(old_envp[i]) + 1; //size of env string, including trailing '\0' ++ } ++ assert((old_envp && old_envp[i]==NULL) || (old_envp==NULL)); ++ old_envp_size += sizeof(char *);//last null pointer ++ ++ env_size = strlen(env); //new env string size ++ ++ new_envp = loc_alloc(old_envp_size + sizeof(char *) + env_size + 1); ++ if (new_envp != NULL) { ++ new_envp[0] = (char *) new_envp + old_envp_size + sizeof(char *); //setting new env ptr ++ strcpy(new_envp[0], env); //copy new env string ++ if (old_envp) { ++ memcpy(&new_envp[1], old_envp, old_envp_size); //copy old envp ++ } else { ++ new_envp[1] = NULL; ++ } ++ } ++ return new_envp; ++} ++ ++static int start_terminal(Channel * c, char *pty_type, char *encoding, ++ char ** envp, int envp_len, char * exe, char ** args, int *pid, ++ Terminal ** prs) ++{ ++ int err = 0; ++ int fd_tty_master = -1; ++ char * tty_slave_name = NULL; ++ struct winsize size; ++ char **newenvp = envp; ++ ++ memset(&size, 0, sizeof(struct winsize)); ++ fd_tty_master = posix_openpt(O_RDWR | O_NOCTTY); ++ if (fd_tty_master < 0 || grantpt(fd_tty_master) < 0 || unlockpt( ++ fd_tty_master) < 0) ++ err = errno; ++ if (!err) { ++ tty_slave_name = ptsname(fd_tty_master); ++ if (tty_slave_name == NULL) ++ err = EINVAL; ++ } ++ ++ if (ioctl(fd_tty_master, TIOCGWINSZ, (char *) &size) < 0) ++ err = errno; ++ ++ if (!err && fd_tty_master < 3) { ++ int fd0 = fd_tty_master; ++ if ((fd_tty_master = dup(fd_tty_master)) < 0 || close(fd0)) ++ err = errno; ++ } ++ ++ if (!err) { ++ *pid = fork(); ++ if (*pid < 0) ++ err = errno; ++ if (*pid == 0) { ++ int fd = -1; ++ int fd_tty_slave = -1; ++ ++ if (*pty_type) { ++ char env_term[TERM_PROP_DEF_SIZE]; ++ snprintf(env_term, sizeof(env_term), "TERM=%s", pty_type); ++ newenvp = envp_add(envp, envp_len, env_term); ++ if (newenvp == NULL) { ++ err = ENOMEM; ++ } else if (envp) { ++ loc_free(envp); ++ envp = NULL; ++ } ++ } ++ ++ setsid(); ++ ++ if (!err && (fd = sysconf(_SC_OPEN_MAX)) < 0) ++ err = errno; ++ if (!err && (fd_tty_slave = open(tty_slave_name, O_RDWR)) < 0) ++ err = errno; ++#if defined(TIOCSCTTY) ++ if (!err && (ioctl(fd_tty_slave, TIOCSCTTY, (char *) 0)) < 0) ++ err = errno; ++#endif ++ if (!err && dup2(fd_tty_slave, 0) < 0) ++ err = errno; ++ if (!err && dup2(fd_tty_slave, 1) < 0) ++ err = errno; ++ if (!err && dup2(fd_tty_slave, 2) < 0) ++ err = errno; ++ while (!err && fd > 3) ++ close(--fd); ++ if (!err) { ++ execve(exe, args, newenvp); ++ err = errno; ++ } ++ if (newenvp) ++ loc_free(newenvp); ++ err = 1; ++ if (err < 1) ++ err = EINVAL; ++ else if (err > 0xff) ++ err = EINVAL; ++ exit(err); ++ } ++ } ++ ++ if (!err) { ++ *prs = (Terminal *) loc_alloc_zero(sizeof(Terminal)); ++ (*prs)->inp = fd_tty_master; ++ (*prs)->out = fd_tty_master; ++ (*prs)->err = fd_tty_master; ++ (*prs)->pid = *pid; ++ (*prs)->bcg = c->bcg; ++ (*prs)->channel = c; ++ if (*pty_type) ++ snprintf((*prs)->pty_type, sizeof((*prs)->pty_type), "%s", pty_type); ++ if (*encoding) ++ snprintf((*prs)->encoding, sizeof((*prs)->encoding), "%s", encoding); ++ (*prs)->width = size.ws_row; ++ (*prs)->height = size.ws_col; ++ list_add_first(&(*prs)->link, &terms_list); ++ } ++ ++ if (!err) ++ return 0; ++ errno = err; ++ return -1; ++} ++ ++static void command_get_context(char * token, Channel * c) ++{ ++ int err = 0; ++ char id[256]; ++ int tid; ++ Terminal *term; ++ ++ json_read_string(&c->inp, id, sizeof(id)); ++ if (read_stream(&c->inp) != 0) ++ exception(ERR_JSON_SYNTAX); ++ if (read_stream(&c->inp) != MARKER_EOM) ++ exception(ERR_JSON_SYNTAX); ++ ++ tid = id2tid(id); ++ write_stringz(&c->out, "R"); ++ write_stringz(&c->out, token); ++ ++ if (tid == 0) { ++ err = ERR_INV_CONTEXT; ++ } else { ++ term = find_terminal(tid); ++ if (term == NULL) { ++ err = ERR_INV_CONTEXT; ++ } else { ++ write_context(&c->out, tid); ++ write_stream(&c->out, 0); ++ } ++ } ++ ++ write_errno(&c->out, err); ++ write_stream(&c->out, MARKER_EOM); ++} ++ ++static void command_launch(char * token, Channel * c) ++{ ++ int pid = 0; ++ int err = 0; ++ char encoding[TERM_PROP_DEF_SIZE]; ++ char pty_type[TERM_PROP_DEF_SIZE]; ++ char *args[] = TERM_LAUNCH_ARGS; ++ ++ char ** envp = NULL; ++ int envp_len = 0; ++ ++ Terminal * prs = NULL; ++ Trap trap; ++ ++ if (set_trap(&trap)) { ++ json_read_string(&c->inp, pty_type, sizeof(pty_type)); ++ if (read_stream(&c->inp) != 0) ++ exception(ERR_JSON_SYNTAX); ++ json_read_string(&c->inp, encoding, sizeof(encoding)); ++ if (read_stream(&c->inp) != 0) ++ exception(ERR_JSON_SYNTAX); ++ envp = json_read_alloc_string_array(&c->inp, &envp_len); ++ if (read_stream(&c->inp) != 0) ++ exception(ERR_JSON_SYNTAX); ++ if (read_stream(&c->inp) != MARKER_EOM) ++ exception(ERR_JSON_SYNTAX); ++ ++ if (err == 0 && start_terminal(c, pty_type, encoding, envp, envp_len, ++ TERM_LAUNCH_EXEC, args, &pid, &prs) < 0) ++ err = errno; ++ if (prs != NULL) { ++ write_terminal_input(prs); ++ prs->out_struct = read_terminal_output(prs, prs->out, prs->out_id, ++ sizeof(prs->out_id)); ++ if (prs->out != prs->err) ++ prs->err_struct = read_terminal_output(prs, prs->err, ++ prs->err_id, sizeof(prs->err_id)); ++ } ++ if (!err) { ++ add_waitpid_process(pid); ++ } ++ //write result back ++ { ++ write_stringz(&c->out, "R"); ++ write_stringz(&c->out, token); ++ write_errno(&c->out, err); ++ if (err || pid == 0) { ++ write_stringz(&c->out, "null"); ++ } else { ++ write_context(&c->out, pid); ++ write_stream(&c->out, 0); ++ } ++ write_stream(&c->out, MARKER_EOM); ++ } ++ clear_trap(&trap); ++ } ++ ++ loc_free(envp); ++ ++ if (trap.error) ++ exception(trap.error); ++} ++ ++static void command_set_win_size(char * token, Channel * c) ++{ ++ int err = 0; ++ struct winsize size; ++ char id[256]; ++ unsigned tid; ++ Terminal *term = NULL; ++ ++ json_read_string(&c->inp, id, sizeof(id)); ++ if (read_stream(&c->inp) != 0) ++ exception(ERR_JSON_SYNTAX); ++ size.ws_col=json_read_ulong(&c->inp); ++ if (read_stream(&c->inp) != 0) ++ exception(ERR_JSON_SYNTAX); ++ size.ws_row=json_read_ulong(&c->inp); ++ if (read_stream(&c->inp) != 0) ++ exception(ERR_JSON_SYNTAX); ++ if (read_stream(&c->inp) != MARKER_EOM) ++ exception(ERR_JSON_SYNTAX); ++ ++ tid = id2tid(id); ++ ++ if(tid==0 || (term=find_terminal(tid))==NULL) { ++ err=ERR_INV_CONTEXT; ++ }else if (term->width != size.ws_col || term->height != size.ws_row) { ++ if(ioctl(term->inp,TIOCSWINSZ,&size)<0) { ++ err=errno; ++ } ++ if(!err) { ++ term->width=size.ws_col; ++ term->height=size.ws_row; ++ send_event_terminal_win_size_changed(&term->channel->out,term); ++ } ++ } ++ ++ write_stringz(&c->out, "R"); ++ write_stringz(&c->out, token); ++ write_errno(&c->out, err); ++ write_stream(&c->out, MARKER_EOM); ++ ++} ++ ++static void waitpid_listener(int pid, int exited, int exit_code, int signal, ++ int event_code, int syscall, void * args) ++{ ++ if (exited) { ++ Terminal * prs = find_terminal(pid); ++ if (prs) { ++ if (signal != 0) ++ prs->exit_code = -signal; ++ else ++ prs->exit_code = exit_code; ++ terminal_exited(prs); ++ } ++ } ++} ++ ++static void channel_close_listener(Channel * c) ++{ ++ LINK * l = NULL; ++ ++ for (l = terms_list.next; l != &terms_list;) { ++ Terminal * term = link2term(l); ++ l = l->next; ++ if (term->channel == c) { ++ trace(LOG_ALWAYS, "Terminal is left launched: T%d", term->pid); ++ kill_term(term); ++ } ++ } ++} ++ ++void ini_terminals_service(Protocol * proto) ++{ ++#if defined(_WRS_KERNEL) ++ prs_list_lock = semMCreate(SEM_Q_PRIORITY); ++ if (prs_list_lock == NULL) check_error(errno); ++ if (taskCreateHookAdd((FUNCPTR)task_create_hook) != OK) check_error(errno); ++ if (taskDeleteHookAdd((FUNCPTR)task_delete_hook) != OK) check_error(errno); ++#endif ++ list_init(&terms_list); ++ ++ add_waitpid_listener(waitpid_listener, NULL); ++ add_channel_close_listener(channel_close_listener); ++ ++ add_command_handler(proto, TERMINALS, "getContext", command_get_context); ++ add_command_handler(proto, TERMINALS, "launch", command_launch); ++ add_command_handler(proto, TERMINALS, "exit", command_exit); ++ add_command_handler(proto, TERMINALS, "setWinSize", command_set_win_size); ++} +Index: org.eclipse.tm.tcf.terminals.agent/main/services-ext.h +=================================================================== +--- org.eclipse.tm.tcf.terminals.agent/main/services-ext.h (revision 0) ++++ org.eclipse.tm.tcf.terminals.agent/main/services-ext.h (revision 0) +@@ -0,0 +1,25 @@ ++/******************************************************************************* ++ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. ++ * All rights reserved. This program and the accompanying materials ++ * are made available under the terms of the Eclipse Public License v1.0 ++ * and Eclipse Distribution License v1.0 which accompany this distribution. ++ * The Eclipse Public License is available at ++ * http://www.eclipse.org/legal/epl-v10.html ++ * and the Eclipse Distribution License is available at ++ * http://www.eclipse.org/org/documents/edl-v10.php. ++ * ++ * Contributors: ++ * Wind River Systems - initial API and implementation ++ *******************************************************************************/ ++ ++/* ++ * Services initialization code extension point. ++ * If the agent is built with additional user-defined services, ++ * a customized version of services-ext.h file can be added to compiler headers search paths. ++ */ ++ ++#include "terminals.h" ++ ++static void ini_ext_services(Protocol * proto, TCFBroadcastGroup * bcg) { ++ ini_terminals_service(proto); ++} +Index: org.eclipse.tm.tcf.terminals.agent/terminals.h +=================================================================== +--- org.eclipse.tm.tcf.terminals.agent/terminals.h (revision 0) ++++ org.eclipse.tm.tcf.terminals.agent/terminals.h (revision 0) +@@ -0,0 +1,27 @@ ++/******************************************************************************* ++ * Copyright (c) 2008 Wind River Systems, Inc. and others. ++ * All rights reserved. This program and the accompanying materials ++ * are made available under the terms of the Eclipse Public License v1.0 ++ * and Eclipse Distribution License v1.0 which accompany this distribution. ++ * The Eclipse Public License is available at ++ * http://www.eclipse.org/legal/epl-v10.html ++ * and the Eclipse Distribution License is available at ++ * http://www.eclipse.org/org/documents/edl-v10.php. ++ * ++ * Contributors: ++ * Wind River Systems - initial API and implementation ++ *******************************************************************************/ ++ ++/* ++ * Sample TCF service header file. ++ */ ++ ++#ifndef TERMINALS_H_ ++#define TERMINALS_H_ ++ ++#include <config.h> ++#include <framework/protocol.h> ++ ++extern void ini_terminals_service(Protocol * proto); ++ ++#endif /*TERMINALS_H_*/ +Index: org.eclipse.tm.tcf.terminals.agent/config.h +=================================================================== +--- org.eclipse.tm.tcf.terminals.agent/config.h (revision 0) ++++ org.eclipse.tm.tcf.terminals.agent/config.h (revision 0) +@@ -0,0 +1,63 @@ ++/******************************************************************************* ++ * Copyright (c) 2008 Wind River Systems, Inc. and others. ++ * All rights reserved. This program and the accompanying materials ++ * are made available under the terms of the Eclipse Public License v1.0 ++ * and Eclipse Distribution License v1.0 which accompany this distribution. ++ * The Eclipse Public License is available at ++ * http://www.eclipse.org/legal/epl-v10.html ++ * and the Eclipse Distribution License is available at ++ * http://www.eclipse.org/org/documents/edl-v10.php. ++ * ++ * Contributors: ++ * Wind River Systems - initial API and implementation ++ *******************************************************************************/ ++ ++/* ++ * This file contains "define" statements that control agent configuration. ++ * SERVICE_* definitions control which service implementations are included into the agent. ++ * ++ * This is example agent configuration. It includes only few standard services, ++ * and one example service: Day Time. ++ */ ++ ++#ifndef D_config ++#define D_config ++ ++#include <framework/mdep.h> ++ ++#if defined(WIN32) || defined(__CYGWIN__) ++# define TARGET_UNIX 0 ++#elif defined(_WRS_KERNEL) ++# define TARGET_UNIX 0 ++#else ++# define TARGET_UNIX 1 ++#endif ++ ++#define SERVICE_Locator 1 ++#define SERVICE_Processes 1 ++#define SERVICE_Streams 1 ++#define SERVICE_FileSystem 1 ++#define SERVICE_SysMonitor TARGET_UNIX ++ ++#define ENABLE_ZeroCopy 1 ++ ++#if !defined(ENABLE_Splice) ++# if ENABLE_ZeroCopy ++# include <fcntl.h> ++# if defined(SPLICE_F_MOVE) ++# define ENABLE_Splice 1 ++# else ++# define ENABLE_Splice 0 ++# endif ++# else ++# define ENABLE_Splice 0 ++# endif ++#endif ++ ++#define ENABLE_SSL 0 ++ ++#define ENABLE_Trace 1 ++#define ENABLE_Discovery 1 ++ ++ ++#endif /* D_config */ +Index: org.eclipse.tm.tcf.terminals.agent/Makefile +=================================================================== +--- org.eclipse.tm.tcf.terminals.agent/Makefile (revision 0) ++++ org.eclipse.tm.tcf.terminals.agent/Makefile (revision 0) +@@ -0,0 +1,39 @@ ++TCF_AGENT_DIR=../agent ++ ++include $(TCF_AGENT_DIR)/Makefile.inc ++ ++override CFLAGS += $(foreach dir,$(INCDIRS),-I$(dir)) $(OPTS) ++ ++HFILES := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.h)) $(HFILES) ++CFILES := $(sort $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c)) $(CFILES)) ++ ++#no using SSL ++LIBS = -lpthread -lrt ++ ++EXECS = $(BINDIR)/agent$(EXTEXE) ++ ++all: $(EXECS) ++ ++$(BINDIR)/libtcf$(EXTLIB) : $(OFILES) ++ $(AR) rcs $@ $^ ++ ++$(BINDIR)/agent$(EXTEXE): $(BINDIR)/main/main$(EXTOBJ) $(BINDIR)/libtcf$(EXTLIB) ++ $(CC) $(CFLAGS) -o $@ $(BINDIR)/main/main$(EXTOBJ) $(BINDIR)/libtcf$(EXTLIB) $(LIBS) ++ ++$(BINDIR)/%$(EXTOBJ): %.c $(HFILES) Makefile ++ @mkdir -p $(dir $@) ++ $(CC) $(CFLAGS) -c -o $@ $< ++ ++$(BINDIR)/%$(EXTOBJ): $(TCF_AGENT_DIR)/%.c $(HFILES) Makefile ++ @mkdir -p $(dir $@) ++ $(CC) $(CFLAGS) -c -o $@ $< ++ ++install: all ++ install -d -m 755 $(INSTALLROOT)$(SBIN) ++ install -d -m 755 $(INSTALLROOT)$(INIT) ++ install -c $(BINDIR)/agent -m 755 $(INSTALLROOT)$(SBIN)/tcf-agent ++ install -c $(TCF_AGENT_DIR)/main/tcf-agent.init -m 755 $(INSTALLROOT)$(INIT)/tcf-agent ++ ++clean: ++ rm -rf $(BINDIR) ++ 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 000000000..b4c70ec8b --- /dev/null +++ b/meta/packages/tcf-agent/tcf-agent_svn.bb @@ -0,0 +1,36 @@ +DESCRIPTION = "Target Communication Framework" +HOMEPAGE = "http://dsdp.eclipse.org/dsdp/tm/" +BUGTRACKER = "https://bugs.eclipse.org/bugs/" + +LICENSE = "EPLv1.0 | EDLv1.0" +LIC_FILES_CHKSUM = "file://../epl-v10.html;md5=7aa4215a330a0a4f6a1cbf8da1a0879f \ + file://../agent/edl-v10.html;md5=522a390a83dc186513f0500543ad3679" + +PV = "0.3.0+svnr${SRCREV}" +PR = "r0" + +SRC_URI = "svn://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/;module=tags/0.3.0/;proto=http \ + file://terminals_agent.patch \ + file://fix_tcf-agent.init.patch" + +S = "${WORKDIR}/tags/0.3.0/tcf-agent" + +inherit update-rc.d + +INITSCRIPT_NAME = "tcf-agent" +INITSCRIPT_PARAMS = "start 999 3 5 . stop 20 0 1 2 6 ." + +# mangling needed for make +MAKE_ARCH = `echo ${TARGET_ARCH} | sed s,i.86,i686,` +MAKE_OS = `echo ${TARGET_OS} | sed s,linux,GNU/Linux,` + +EXTRA_OEMAKE = "MACHINE=${MAKE_ARCH} OPSYS=${MAKE_OS} 'CC=${CC}' 'AR=${AR}'" + +do_compile() { + oe_runmake +} + +do_install() { + oe_runmake install INSTALLROOT=${D} +} + |