]> code.ossystems Code Review - openembedded-core.git/commitdiff
tcf-agent: add the latest version 0.3.0+svnr1078
authorDexuan Cui <dexuan.cui@intel.com>
Fri, 23 Jul 2010 12:23:33 +0000 (20:23 +0800)
committerRichard Purdie <rpurdie@linux.intel.com>
Wed, 28 Jul 2010 05:51:33 +0000 (22:51 -0700)
install a proper script /etc/init.d/tcf-agent
make it autostart in runlevels 3 and 5

Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
Signed-off-by: Lianhao Lu <lianhao.lu@intel.com>
Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
meta/conf/distro/include/poky-default-revisions.inc
meta/packages/tasks/task-poky-tools.bb
meta/packages/tcf-agent/tcf-agent/fix_tcf-agent.init.patch [new file with mode: 0644]
meta/packages/tcf-agent/tcf-agent/terminals_agent.patch [new file with mode: 0644]
meta/packages/tcf-agent/tcf-agent_svn.bb [new file with mode: 0644]

index f8262fdcfb9e9d727817ad02f007d52ec0766045..2edc019accbe0beca089bca906575711403efcd2 100644 (file)
@@ -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"
index bebda285f00bad14ac8133b7530e429b5e1664e1..3872cd563375f41ef44f26ef80ae4be60b4ad783 100644 (file)
@@ -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 (file)
index 0000000..66d403b
--- /dev/null
@@ -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 (file)
index 0000000..b88b5e7
--- /dev/null
@@ -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 (file)
index 0000000..b4c70ec
--- /dev/null
@@ -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}
+}
+