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