diff options
author | Sung-jae Park <nicesj.park@samsung.com> | 2013-02-14 05:17:28 +0000 |
---|---|---|
committer | Sung-jae Park <nicesj.park@samsung.com> | 2013-02-14 05:17:28 +0000 |
commit | f350fef4a102a3e0036f824e73bb3fa2cf542d81 (patch) | |
tree | f65567b30bf31f12eedc0dffcbe786380cd71895 | |
parent | 7f262791e53ad0eb9f680265d3a3a20949b2cf68 (diff) | |
download | data-provider-master-f350fef4a102a3e0036f824e73bb3fa2cf542d81.tar.gz data-provider-master-f350fef4a102a3e0036f824e73bb3fa2cf542d81.tar.bz2 data-provider-master-f350fef4a102a3e0036f824e73bb3fa2cf542d81.zip |
Revise the code.
1. Update the liveinfo tool
Add more functions. Make easy to use the tool
2. Time compensator is updated.
3. Code is revised by myself.
Change-Id: Ib4b64da80727edb394a12e50398ed6f10e97b6e1
-rw-r--r-- | include/util.h | 1 | ||||
-rw-r--r-- | packaging/org.tizen.data-provider-master.spec | 2 | ||||
-rw-r--r-- | src/buffer_handler.c | 2 | ||||
-rw-r--r-- | src/client_life.c | 28 | ||||
-rw-r--r-- | src/client_rpc.c | 18 | ||||
-rw-r--r-- | src/critical_log.c | 54 | ||||
-rw-r--r-- | src/dead_monitor.c | 6 | ||||
-rw-r--r-- | src/fault_manager.c | 1 | ||||
-rw-r--r-- | src/group.c | 35 | ||||
-rw-r--r-- | src/instance.c | 22 | ||||
-rw-r--r-- | src/util.c | 48 | ||||
-rw-r--r-- | util_liveinfo/CMakeLists.txt | 3 | ||||
-rw-r--r-- | util_liveinfo/src/liveinfo.c | 378 |
13 files changed, 498 insertions, 100 deletions
diff --git a/include/util.h b/include/util.h index 1411f4f..e840ef0 100644 --- a/include/util.h +++ b/include/util.h @@ -28,6 +28,7 @@ extern const char *util_uri_to_path(const char *uri); extern void *util_timer_add(double interval, Eina_Bool (*cb)(void *data), void *data); extern void util_timer_interval_set(void *timer, double interval); extern char *util_get_file_kept_in_safe(const char *id); +extern double util_time_delay_for_compensation(double period); #define SCHEMA_FILE "file://" #define SCHEMA_PIXMAP "pixmap://" diff --git a/packaging/org.tizen.data-provider-master.spec b/packaging/org.tizen.data-provider-master.spec index a222154..4986432 100644 --- a/packaging/org.tizen.data-provider-master.spec +++ b/packaging/org.tizen.data-provider-master.spec @@ -1,6 +1,6 @@ Name: org.tizen.data-provider-master Summary: Master service provider for liveboxes. -Version: 0.16.2 +Version: 0.16.3 Release: 1 Group: framework/livebox License: Flora License diff --git a/src/buffer_handler.c b/src/buffer_handler.c index 670497c..78c745d 100644 --- a/src/buffer_handler.c +++ b/src/buffer_handler.c @@ -1266,6 +1266,8 @@ HAPI int buffer_handler_init(void) DbgPrint("Fallback to the S/W Backend\n"); s_info.evt_base = 0; s_info.err_base = 0; + DbgFree(deviceName); + DbgFree(driverName); return 0; } diff --git a/src/client_life.c b/src/client_life.c index cb12b3d..585d45c 100644 --- a/src/client_life.c +++ b/src/client_life.c @@ -86,17 +86,14 @@ static inline void invoke_global_destroy_cb(struct client_node *client) Eina_List *l; Eina_List *n; struct global_event_handler *item; - int ret; EINA_LIST_FOREACH_SAFE(s_info.destroy_event_list, l, n, item) { if (!item->cb) { - DbgPrint("Callback function is not valid\n"); + ErrPrint("Callback function is not valid\n"); continue; } - ret = item->cb(client, item->cbdata); - - if (ret < 0) { + if (item->cb(client, item->cbdata) < 0) { if (eina_list_data_find(s_info.destroy_event_list, item)) { s_info.destroy_event_list = eina_list_remove(s_info.destroy_event_list, item); DbgFree(item); @@ -112,6 +109,11 @@ static inline void invoke_global_create_cb(struct client_node *client) struct global_event_handler *item; EINA_LIST_FOREACH_SAFE(s_info.create_event_list, l, n, item) { + if (!item->cb) { + ErrPrint("Callback function is not valid\n"); + continue; + } + if (item->cb(client, item->cbdata) < 0) { if (eina_list_data_find(s_info.create_event_list, item)) { s_info.create_event_list = eina_list_remove(s_info.create_event_list, item); @@ -140,7 +142,7 @@ static inline void destroy_client_data(struct client_node *client) continue; } - event->cb(client, event->data); + (void)event->cb(client, event->data); if (eina_list_data_find(client->event_destroy_list, event)) { client->event_destroy_list = eina_list_remove(client->event_destroy_list, event); @@ -351,10 +353,8 @@ HAPI int client_deactivated_by_fault(struct client_node *client) if (!client || client->faulted) return 0; - DbgPrint("Client[%p] is faulted(%d), pid(%d)\n", client, client->refcnt, client->pid); + ErrPrint("Client[%p] is faulted(%d), pid(%d)\n", client, client->refcnt, client->pid); client->faulted = 1; - - DbgPrint("Reset PID (%d)\n", client->pid); client->pid = (pid_t)-1; invoke_deactivated_cb(client); @@ -717,15 +717,17 @@ HAPI int client_browse_list(const char *cluster, const char *category, int (*cb) struct client_node *client; int cnt; + if (!cb || !cluster || !category) + return -EINVAL; + cnt = 0; EINA_LIST_FOREACH(s_info.client_list, l, client) { if (!client_is_subscribed(client, cluster, category)) continue; - if (cb) { - if (cb(client, data) < 0) - return -ECANCELED; - } + if (cb(client, data) < 0) + return -ECANCELED; + cnt++; } diff --git a/src/client_rpc.c b/src/client_rpc.c index 61eee13..8266ffe 100644 --- a/src/client_rpc.c +++ b/src/client_rpc.c @@ -31,6 +31,8 @@ #include "conf.h" #include "util.h" +#define RPC_TAG "rpc" + /*! * \note * Static component information structure. @@ -123,7 +125,7 @@ static Eina_Bool command_consumer_cb(void *data) goto out; } - rpc = client_data(command->client, "rpc"); + rpc = client_data(command->client, RPC_TAG); if (!rpc) { ErrPrint("Invalid command\n"); goto out; @@ -163,7 +165,7 @@ HAPI int client_rpc_async_request(struct client_node *client, struct packet *pac struct command *command; struct client_rpc *rpc; - if (!client) + if (!client || !packet) return -EINVAL; if (client_is_faulted(client)) { @@ -172,7 +174,7 @@ HAPI int client_rpc_async_request(struct client_node *client, struct packet *pac return -EFAULT; } - rpc = client_data(client, "rpc"); + rpc = client_data(client, RPC_TAG); if (!rpc) ErrPrint("Client[%p] is not ready for communication (%s)\n", client, packet_command(packet)); @@ -194,7 +196,7 @@ static int deactivated_cb(struct client_node *client, void *data) Eina_List *l; Eina_List *n; - rpc = client_data(client, "rpc"); + rpc = client_data(client, RPC_TAG); if (!rpc) { ErrPrint("client is not valid\n"); return 0; @@ -226,14 +228,14 @@ HAPI int client_rpc_init(struct client_node *client, int handle) return -ENOMEM; } - ret = client_set_data(client, "rpc", rpc); + ret = client_set_data(client, RPC_TAG, rpc); if (ret < 0) { ErrPrint("Failed to set \"rpc\" for client\n"); DbgFree(rpc); return ret; } - DbgPrint("CLIENT: New handle assigned for %d, %d\n", client_pid(client), handle); + DbgPrint("CLIENT: New handle assigned for %d, %d (old: %d)\n", client_pid(client), handle, rpc->handle); rpc->handle = handle; client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, deactivated_cb, NULL); @@ -244,7 +246,7 @@ HAPI int client_rpc_fini(struct client_node *client) { struct client_rpc *rpc; - rpc = client_del_data(client, "rpc"); + rpc = client_del_data(client, RPC_TAG); if (!rpc) return -EINVAL; @@ -257,7 +259,7 @@ HAPI int client_rpc_handle(struct client_node *client) { struct client_rpc *rpc; - rpc = client_data(client, "rpc"); + rpc = client_data(client, RPC_TAG); if (!rpc) { DbgPrint("Client has no RPC\n"); return -EINVAL; diff --git a/src/critical_log.c b/src/critical_log.c index 2af51a8..36e7ccf 100644 --- a/src/critical_log.c +++ b/src/critical_log.c @@ -46,6 +46,36 @@ static struct { +static inline void rotate_log(void) +{ + char *filename; + int namelen; + + if (s_info.nr_of_lines < MAX_LOG_LINE) + return; + + s_info.file_id = (s_info.file_id + 1) % MAX_LOG_FILE; + + namelen = strlen(s_info.filename) + strlen(SLAVE_LOG_PATH) + 20; + filename = malloc(namelen); + if (filename) { + snprintf(filename, namelen, "%s/%d_%s", SLAVE_LOG_PATH, s_info.file_id, s_info.filename); + + if (s_info.fp) + fclose(s_info.fp); + + s_info.fp = fopen(filename, "w+"); + if (!s_info.fp) + ErrPrint("Failed to open a file: %s\n", filename); + + DbgFree(filename); + } + + s_info.nr_of_lines = 0; +} + + + HAPI int critical_log(const char *func, int line, const char *fmt, ...) { va_list ap; @@ -67,29 +97,7 @@ HAPI int critical_log(const char *func, int line, const char *fmt, ...) va_end(ap); s_info.nr_of_lines++; - if (s_info.nr_of_lines == MAX_LOG_LINE) { - char *filename; - int namelen; - - s_info.file_id = (s_info.file_id + 1) % MAX_LOG_FILE; - - namelen = strlen(s_info.filename) + strlen(SLAVE_LOG_PATH) + 20; - filename = malloc(namelen); - if (filename) { - snprintf(filename, namelen, "%s/%d_%s", SLAVE_LOG_PATH, s_info.file_id, s_info.filename); - - if (s_info.fp) - fclose(s_info.fp); - - s_info.fp = fopen(filename, "w+"); - if (!s_info.fp) - ErrPrint("Failed to open a file: %s\n", filename); - - DbgFree(filename); - } - - s_info.nr_of_lines = 0; - } + rotate_log(); return ret; } diff --git a/src/dead_monitor.c b/src/dead_monitor.c index a0133bf..476139b 100644 --- a/src/dead_monitor.c +++ b/src/dead_monitor.c @@ -41,7 +41,6 @@ static int evt_cb(int handle, void *data) slave = slave_find_by_rpc_handle(handle); if (slave) { - DbgPrint("Slave is disconnected %d\n", handle); if (slave_pid(slave) != (pid_t)-1) { if (slave_state(slave) == SLAVE_REQUEST_TO_TERMINATE) slave = slave_deactivated(slave); @@ -49,13 +48,12 @@ static int evt_cb(int handle, void *data) slave = slave_deactivated_by_fault(slave); } - DbgPrint("Slave pointer: %p (0x0 means deleted)\n", slave); + DbgPrint("Slave pointer: %p (0 means deleted)\n", slave); return 0; } client = client_find_by_rpc_handle(handle); if (client) { - DbgPrint("Client is disconnected\n"); if (client_pid(client) != (pid_t)-1) client_deactivated_by_fault(client); @@ -64,7 +62,6 @@ static int evt_cb(int handle, void *data) liveinfo = liveinfo_find_by_handle(handle); if (liveinfo) { - DbgPrint("Utility is disconnected\n"); liveinfo_destroy(liveinfo); return 0; } @@ -76,7 +73,6 @@ static int evt_cb(int handle, void *data) HAPI int dead_init(void) { com_core_add_event_callback(CONNECTOR_DISCONNECTED, evt_cb, NULL); -// aul_listen_app_dead_signal(dead_cb, NULL); return 0; } diff --git a/src/fault_manager.c b/src/fault_manager.c index 5fbcef1..89c2a74 100644 --- a/src/fault_manager.c +++ b/src/fault_manager.c @@ -58,6 +58,7 @@ HAPI int const fault_is_occured(void) static void clear_log_file(struct slave_node *slave) { char filename[BUFSIZ]; + snprintf(filename, sizeof(filename), "%s/slave.%d", SLAVE_LOG_PATH, slave_pid(slave)); unlink(filename); diff --git a/src/group.c b/src/group.c index 4b58aa9..c0697f1 100644 --- a/src/group.c +++ b/src/group.c @@ -411,14 +411,18 @@ HAPI void *group_context_item_del_data(struct context_item *item, const char *ta struct context_item_data *tmp; Eina_List *l; Eina_List *n; - void *data; EINA_LIST_FOREACH_SAFE(item->data_list, l, n, tmp) { if (!strcmp(tmp->tag, tag)) { + void *data; + item->data_list = eina_list_remove(item->data_list, tmp); - DbgFree(tmp->tag); + data = tmp->data; + + DbgFree(tmp->tag); DbgFree(tmp); + return data; } } @@ -428,12 +432,12 @@ HAPI void *group_context_item_del_data(struct context_item *item, const char *ta HAPI const char * const group_category_name(struct category *category) { - return category->name; + return category ? category->name : NULL; } HAPI const char * const group_cluster_name(struct cluster *cluster) { - return cluster->name; + return cluster ? cluster->name : NULL; } HAPI const char *group_cluster_name_by_category(struct category *category) @@ -444,26 +448,33 @@ HAPI const char *group_cluster_name_by_category(struct category *category) static inline char *get_token(char *ptr, int *len) { char *name; + int _len; if (*len == 0) { ErrPrint("Start brace but len = 0\n"); return NULL; } - name = malloc(*len + 1); + _len = *len; + + while (_len > 0 && isspace(ptr[_len])) + _len--; + + if (_len == 0) { + ErrPrint("Token has no string\n"); + return NULL; + } + + name = malloc(_len + 1); if (!name) { ErrPrint("Heap: %s\n", strerror(errno)); return NULL; } - strncpy(name, ptr - *len, *len); - name[(*len)--] = '\0'; - - while (isspace(name[(*len)])) { - name[*len] = '\0'; - (*len)--; - } + strncpy(name, ptr - *len, _len); + name[_len] = '\0'; + *len = _len; return name; } diff --git a/src/instance.c b/src/instance.c index 59e228a..14572c5 100644 --- a/src/instance.c +++ b/src/instance.c @@ -138,28 +138,22 @@ static Eina_Bool update_timer_cb(void *data); static inline void timer_thaw(struct inst_info *inst) { - struct timeval tv; double pending; - double compensate; + double period; + double delay; double sleep_time; ecore_timer_thaw(inst->update_timer); - - if (inst->sleep_at == 0.0f) - return; - + period = ecore_timer_interval_get(inst->update_timer); pending = ecore_timer_pending_get(inst->update_timer); + delay = util_time_delay_for_compensation(period) - pending; + ecore_timer_delay(inst->update_timer, delay); + DbgPrint("Compensated: %lf\n", delay); - if (gettimeofday(&tv, NULL) < 0) { - ErrPrint("Failed to get timeofday: %s\n", strerror(errno)); + if (inst->sleep_at == 0.0f) return; - } - compensate = 60.0f - ((double)(tv.tv_sec % 60) + ((double)tv.tv_usec / 1000000.0f)); - sleep_time = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f) - inst->sleep_at; - - ecore_timer_delay(inst->update_timer, compensate - pending); - DbgPrint("Compensate: %lf\n", compensate - pending); + sleep_time = util_timestamp() - inst->sleep_at; if (sleep_time > pending) { DbgPrint("Update time elapsed\n"); (void)update_timer_cb(inst); @@ -337,49 +337,55 @@ HAPI const char *util_uri_to_path(const char *uri) return uri + len; } -static inline void compensate_timer(Ecore_Timer *timer) +HAPI double util_time_delay_for_compensation(double period) { struct timeval tv; - struct timeval compensator; - double delay; - double pending; + unsigned long long curtime; + unsigned long long _period; + unsigned long long remain; + unsigned int sec; + unsigned int usec; + double ret; - if (ecore_timer_interval_get(timer) <= 1.0f) { - DbgPrint("Doesn't need to sync the timer to start from ZERO sec\n"); - return; - } + gettimeofday(&tv, NULL); + curtime = (unsigned long long)tv.tv_sec * 1000000llu + (unsigned long long)tv.tv_usec; - if (gettimeofday(&tv, NULL) < 0) { - ErrPrint("Error: %s\n", strerror(errno)); - return; - } + sec = (unsigned int)period; + usec = (period - sec) * 1000000; + _period = (unsigned long long)sec * 1000000llu + usec; - compensator.tv_sec = tv.tv_sec % 60; - if (compensator.tv_sec == 0) - compensator.tv_sec = 59; + remain = curtime % _period; - delay = 60.0f - ((double)compensator.tv_sec + ((double)tv.tv_usec / 1000000.0f)); - pending = ecore_timer_pending_get(timer); - ecore_timer_delay(timer, delay - pending); - DbgPrint("COMPENSATED: %lf\n", delay); + sec = (unsigned int)(remain / 1000000llu); + usec = (unsigned int)(remain % 1000000llu); + + ret = (double)sec + (double)usec / 1000000.0f; + return period - ret; } HAPI void *util_timer_add(double interval, Eina_Bool (*cb)(void *data), void *data) { Ecore_Timer *timer; + double delay; timer = ecore_timer_add(interval, cb, data); if (!timer) return NULL; - compensate_timer(timer); + delay = util_time_delay_for_compensation(interval) - interval; + ecore_timer_delay(timer, delay); + DbgPrint("Compensate timer: %lf\n", delay); + return timer; } HAPI void util_timer_interval_set(void *timer, double interval) { + double delay; ecore_timer_interval_set(timer, interval); - compensate_timer(timer); + + delay = util_time_delay_for_compensation(interval) - interval; + ecore_timer_delay(timer, delay); } HAPI char *util_get_file_kept_in_safe(const char *id) diff --git a/util_liveinfo/CMakeLists.txt b/util_liveinfo/CMakeLists.txt index 86cae09..5bab600 100644 --- a/util_liveinfo/CMakeLists.txt +++ b/util_liveinfo/CMakeLists.txt @@ -11,6 +11,9 @@ pkg_check_modules(info_pkgs REQUIRED glib-2.0 gio-2.0 livebox-service + xdamage + xfixes + x11 ) FOREACH(flag ${info_pkgs_CFLAGS}) diff --git a/util_liveinfo/src/liveinfo.c b/util_liveinfo/src/liveinfo.c index e7dbe1a..3f984d7 100644 --- a/util_liveinfo/src/liveinfo.c +++ b/util_liveinfo/src/liveinfo.c @@ -20,10 +20,15 @@ #include <errno.h> #include <libgen.h> #include <sys/types.h> +#include <sys/wait.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> +#include <X11/Xlib.h> +#include <X11/extensions/Xdamage.h> +#include <X11/extensions/Xfixes.h> + #include <glib.h> #include <glib-object.h> @@ -101,6 +106,13 @@ static struct info { int verbose; int age; + + char *history[1024]; + int history_top; + int history_idx; + + struct node *quick_search_node; + int quick_idx; } s_info = { .fifo_handle = -EINVAL, .fd = -EINVAL, @@ -113,6 +125,11 @@ static struct info { .input_fd = STDIN_FILENO, .verbose = 0, .age = 0, + .history = { 0, }, + .history_top = 0, + .history_idx = 0, + .quick_search_node = NULL, + .quick_idx = 0, }; char *optarg; @@ -230,7 +247,7 @@ static inline void ls(void) } info = node_data(node); - printf(" %3d %5s %5.2f ", info->loaded_inst, info->abi ? info->abi : "?", info->ttl); + printf("%6d %3d %5s %5.2f ", info->pid, info->loaded_inst, info->abi ? info->abi : "?", info->ttl); } else if (is_instance) { struct instance *info; struct stat stat; @@ -447,13 +464,20 @@ static void send_inst_list(const char *pkgname) static inline void help(void) { printf("liveinfo - Livebox utility\n"); + printf("------------------------------ [Option] ------------------------------\n"); + printf("-b Batch mode\n"); printf("------------------------------ [Command list] ------------------------------\n"); printf("[32mcd [PATH] - Change directory[0m\n"); printf("[32mls [ | PATH] - List up content as a file[0m\n"); printf("[32mrm [PKG_ID|INST_ID] - Delete package or instance[0m\n"); - printf("[32mcat [FILE] - Open a file to get some detail information[0m\n"); - printf("[32mpull [FILE] - Pull given file to host dir[0m\n"); + printf("[32mstat [path] - Display the information of given path[0m\n"); printf("[32mset [debug] [on|off] Set the control variable of master provider[0m\n"); + printf("[32mx damage Pix x y w h - Create damage event for given pixmap[0m\n"); + printf("[32mx move Pix x y - Move the window[0m\n"); + printf("[32mx resize Pix w h - Resize the window[0m\n"); + printf("[32mx map Pix - Show the window[0m\n"); + printf("[32mx unmap Pix - Hide the window[0m\n"); + printf("[32msh [command] Execute shell command, [command] should be abspath[0m\n"); printf("[32mexit - [0m\n"); printf("[32mquit - [0m\n"); printf("----------------------------------------------------------------------------\n"); @@ -519,6 +543,120 @@ static int get_token(const char *src, char *out) return len; } +static inline int do_stat(const char *cmd) +{ + int i; + struct node *node; + struct node *parent; + char *tmp; + enum stat_type { + PKG_INSTANCE = 0x01, + PKG, + PROVIDER_INSTANCE, + PROVIDER, + ROOT, + } type; + + cmd += 5; + while (*cmd && *cmd == ' ') cmd++; + + if (!*cmd){ + printf("Invalid argument\n"); + return -EINVAL; + } + + node = node_find(*cmd == '/' ? s_info.rootdir : s_info.curdir, cmd); + if (!node) { + printf("Invalid path\n"); + return -EINVAL; + } + + i = 0; + type = ROOT; + parent = node_parent(node); + while (parent) { + if (!node_name(parent)) { + printf("%s has no info\n", node_name(node)); + return -EINVAL; + } else if (!strcmp(node_name(parent), "package")) { + type = (i == 0) ? PKG : PKG_INSTANCE; + break; + } else if (!strcmp(node_name(parent), "provider")){ + type = (i == 0) ? PROVIDER : PROVIDER_INSTANCE; + break; + } + + parent = node_parent(parent); + i++; + if (i > 1) { + printf("%s is invalid path\n", node_name(node)); + return -EINVAL; + } + } + + switch (type){ + case PKG: + tmp = livebox_service_i18n_name(node_name(node), NULL); + printf("Name: %s (", tmp); + free(tmp); + + i = livebox_service_is_enabled(node_name(node)); + printf("%s)\n", i ? "enabled" : "disabled"); + + tmp = livebox_service_i18n_icon(node_name(node), NULL); + printf("Icon: %s\n", tmp); + free(tmp); + + tmp = livebox_service_provider_name(node_name(node)); + printf("Provider: %s (content:", tmp); + free(tmp); + + tmp = livebox_service_content(node_name(node)); + printf("%s)\n", tmp); + free(tmp); + + tmp = livebox_service_lb_script_path(node_name(node)); + printf("LB Script: %s (", tmp); + free(tmp); + + tmp = livebox_service_lb_script_group(node_name(node)); + printf("%s)\n", tmp); + free(tmp); + + tmp = livebox_service_pd_script_path(node_name(node)); + printf("PD Script: %s (", tmp); + free(tmp); + + tmp = livebox_service_pd_script_group(node_name(node)); + printf("%s)\n", tmp); + free(tmp); + + i = livebox_service_mouse_event(node_name(node)); + printf("Mouse event: %s\n", i ? "enabled" : "disabled"); + + i = livebox_service_touch_effect(node_name(node)); + printf("Touch effect: %s\n", i ? "enabled" : "disabled"); + break; + case PROVIDER: + printf("Not supported yet\n"); + break; + case PKG_INSTANCE: + printf("Not supported yet\n"); + break; + case PROVIDER_INSTANCE: + printf("Not supported yet\n"); + break; + case ROOT: + printf("Not supported yet\n"); + break; + default: + printf("Invalid type\n"); + return -EFAULT; + } + + return 0; +} + static inline int do_set(const char *cmd) { int i; @@ -669,6 +807,164 @@ static inline int do_rm(const char *cmd) return 0; } +#if !defined(WCOREDUMP) +#define WCOREDUMP(a) 0 +#endif + +static inline void do_sh(const char *cmd) +{ + pid_t pid; + + cmd += 3; + + while (*cmd && *cmd == ' ') cmd++; + if (!*cmd) + return; + + pid = fork(); + if (pid == 0) { + char command[256]; + int idx; + idx = 0; + + while (idx < sizeof(command) && *cmd && *cmd != ' ') + command[idx++] = *cmd++; + command[idx] = '\0'; + + if (execl(command, cmd, NULL) < 0) + printf("Failed to execute: %s\n", strerror(errno)); + + exit(0); + } else if (pid < 0) { + printf("Failed to create a new process: %s\n", strerror(errno)); + } else { + int status; + if (waitpid(pid, &status, 0) < 0) { + printf("error: %s\n", strerror(errno)); + } else { + if (WIFEXITED(status)) { + printf("Exit: %d\n", WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + printf("Terminated by %d %s\n", WTERMSIG(status), WCOREDUMP(status) ? " - core generated" : ""); + } else if (WIFSTOPPED(status)) { + printf("Stopped by %d\n", WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + printf("Child is resumed\n"); + } + } + } +} + +static inline void do_x(const char *cmd) +{ + Display *disp; + + cmd += 2; + + while (*cmd && *cmd == ' ') cmd++; + if (!*cmd) + return; + + disp = XOpenDisplay(NULL); + if (!disp) { + printf("Failed to connect to the X\n"); + return; + } + + if (!strncasecmp(cmd, "damage ", 7)) { + unsigned int winId; + XRectangle rect; + XserverRegion region; + int x, y, w, h; + + cmd += 7; + + if (sscanf(cmd, "%u %d %d %d %d", &winId, &x, &y, &w, &h) != 5) { + printf("Invalid argument\nx damage WINID_DEC X Y W H\n"); + return; + } + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + region = XFixesCreateRegion(disp, &rect, 1); + XDamageAdd(disp, winId, region); + XFixesDestroyRegion(disp, region); + XFlush(disp); + + printf("Damage: %u %d %d %d %d\n", winId, x, y, w, h); + } else if (!strncasecmp(cmd, "resize ", 7)) { + unsigned int winId; + int w; + int h; + + cmd += 7; + + if (sscanf(cmd, "%u %d %d", &winId, &w, &h) != 3) { + printf("Invalid argument\nx resize WINID_DEC W H\n"); + return; + } + + XResizeWindow(disp, winId, w, h); + printf("Resize: %u %d %d\n", winId, w, h); + } else if (!strncasecmp(cmd, "move ", 5)) { + unsigned int winId; + int x; + int y; + + cmd += 5; + if (sscanf(cmd, "%u %d %d", &winId, &x, &y) != 3) { + printf("Invalid argument\nx move WINID_DEC X Y\n"); + return; + } + + XMoveWindow(disp, winId, x, y); + printf("Move: %u %d %d\n", winId, x, y); + } else if (!strncasecmp(cmd, "map ", 4)) { + unsigned int winId; + cmd += 4; + if (sscanf(cmd, "%u", &winId) != 1) { + printf("Invalid argument\nx map WINID_DEC\n"); + return; + } + XMapRaised(disp, winId); + printf("Map: %u\n", winId); + } else if (!strncasecmp(cmd, "unmap ", 6)) { + unsigned int winId; + cmd += 6; + if (sscanf(cmd, "%u", &winId) != 1) { + printf("Invalid argument\nx unmap WINID_DEC\n"); + return; + } + XUnmapWindow(disp, winId); + printf("Unmap: %u\n", winId); + } else { + printf("Unknown command\n"); + } + + XCloseDisplay(disp); +} + +static inline void put_command(const char *cmd) +{ + if (s_info.history[s_info.history_top]) { + free(s_info.history[s_info.history_top]); + s_info.history[s_info.history_top] = NULL; + } + + s_info.history[s_info.history_top] = strdup(cmd); + s_info.history_top = (s_info.history_top + !!s_info.history[s_info.history_top]) % (sizeof(s_info.history) / sizeof(s_info.history[0])); +} + +static inline const char *get_command(int idx) +{ + idx = s_info.history_top + idx; + while (idx < 0) + idx += (sizeof(s_info.history) / sizeof(s_info.history[0])); + + return s_info.history[idx]; +} + static inline void do_command(const char *cmd) { /* Skip the first spaces */ @@ -680,6 +976,8 @@ static inline void do_command(const char *cmd) } else if (!strncasecmp(cmd, "set ", 4)) { if (do_set(cmd) == 0) return; + } else if (!strncasecmp(cmd, "stat ", 5)) { + do_stat(cmd); } else if (!strncasecmp(cmd, "get ", 4)) { if (do_get(cmd) == 0) return; @@ -692,6 +990,10 @@ static inline void do_command(const char *cmd) } else if (!strncasecmp(cmd, "rm", 2)) { if (do_rm(cmd) == 0) return; + } else if (!strncasecmp(cmd, "sh ", 3)) { + do_sh(cmd); + } else if (!strncasecmp(cmd, "x ", 2)) { + do_x(cmd); } else { help(); } @@ -708,6 +1010,9 @@ static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler) char ch; int fd; int ret; + const char escape_str[] = { 0x1b, 0x5b, 0x0 }; + const char *escape_ptr = escape_str; + const char *tmp; if (fd_handler) { fd = ecore_main_fd_handler_fd_get(fd_handler); @@ -728,6 +1033,53 @@ static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler) /* Silly.. Silly */ while ((ret = read(fd, &ch, sizeof(ch))) == sizeof(ch)) { + if (*escape_ptr == '\0') { + /* Function key */ + switch (ch) { + case 0x41: /* UP */ + printf("%s2K%s1G", escape_str, escape_str); + tmp = get_command(--s_info.history_idx); + if (!tmp) { + s_info.history_idx = 0; + cmd_buffer[0] = '\0'; + prompt(NULL); + } else { + strcpy(cmd_buffer, tmp); + idx = strlen(cmd_buffer); + prompt(cmd_buffer); + } + break; + case 0x42: /* DOWN */ + if (s_info.history_idx >= 0) + break; + + printf("%s2K%s1G", escape_str, escape_str); + tmp = get_command(++s_info.history_idx); + if (s_info.history_idx == 0) { + s_info.history_idx = 0; + cmd_buffer[0] = '\0'; + prompt(NULL); + } else { + strcpy(cmd_buffer, tmp); + idx = strlen(cmd_buffer); + prompt(cmd_buffer); + } + break; + case 0x43: /* RIGHT */ + break; + case 0x44: /* LEFT */ + break; + default: + break; + } + + escape_ptr = escape_str; + continue; + } else if (ch == *escape_ptr) { + escape_ptr++; + continue; + } + switch (ch) { case 0x08: /* BKSP */ cmd_buffer[idx] = '\0'; @@ -742,6 +1094,23 @@ static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler) putc('\r', stdout); prompt(cmd_buffer); break; + case 0x09: /* TAB */ + if (!s_info.quick_search_node) { + s_info.quick_search_node = node_child(s_info.curdir); + s_info.quick_idx = idx; + } else { + s_info.quick_search_node = node_next_sibling(s_info.quick_search_node); + idx = s_info.quick_idx; + } + + if (!s_info.quick_search_node) + break; + + printf("%s2K%s1G", escape_str, escape_str); + strcpy(cmd_buffer + idx, node_name(s_info.quick_search_node)); + idx += strlen(node_name(s_info.quick_search_node)); + prompt(cmd_buffer); + break; case '\n': case '\r': cmd_buffer[idx] = '\0'; @@ -749,7 +1118,10 @@ static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler) if (s_info.input_fd == STDIN_FILENO || s_info.verbose) putc((int)'\n', stdout); do_command(cmd_buffer); + put_command(cmd_buffer); memset(cmd_buffer, 0, sizeof(cmd_buffer)); + s_info.history_idx = 0; + s_info.quick_search_node = NULL; /* Make a main loop processing for command handling */ return ECORE_CALLBACK_RENEW; |