/*
- * Copyright 2012 Samsung Electronics Co., Ltd
+ * Copyright 2013 Samsung Electronics Co., Ltd
*
- * Licensed under the Flora License, Version 1.0 (the "License");
+ * Licensed under the Flora License, Version 1.1 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.tizenopensource.org/license
+ * http://floralicense.org/license/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
+#include <sys/shm.h>
+#include <sys/ipc.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/XShm.h>
+#include <X11/Xutil.h>
#include <glib.h>
#include <glib-object.h>
struct slave *info;
info = node_data(node);
- if (!info)
+ if (!info) {
return;
+ }
free(info->pkgname);
free(info->abi);
struct package *info;
info = node_data(node);
- if (!info)
+ if (!info) {
return;
+ }
free(info->pkgid);
free(info->slavename);
struct instance *info;
info = node_data(node);
- if (!info)
+ if (!info) {
return;
+ }
free(info->id);
free(info->cluster);
free(info);
}
-static inline void ls(void)
+static void ls(void)
{
struct node *node;
int cnt = 0;
printf(" %5.2f %6s %10s %10s %4dx%-4d ", info->period, info->state, info->cluster, info->category, info->width, info->height);
snprintf(buf, sizeof(buf), "/opt/usr/share/live_magazine/reader/%s", node_name(node));
- if (lstat(buf, &stat) < 0)
+ if (lstat(buf, &stat) < 0) {
printf("%3d ERR ", errno);
- else
+ } else {
printf("%2.2lf KB ", (double)stat.st_size / 1024.0f);
+ }
}
- if (node_type(node) == NODE_DIR)
+ if (node_type(node) == NODE_DIR) {
printf("%s/", node_name(node));
- else if (node_type(node) == NODE_FILE)
+ } else if (node_type(node) == NODE_FILE) {
printf("%s", node_name(node));
+ }
printf("\n");
node = node_next_sibling(node);
static void send_slave_list(void)
{
struct packet *packet;
+ int ret;
if (s_info.cmd != NOP) {
printf("Previous command is not finished\n");
return;
}
- com_core_packet_send_only(s_info.fd, packet);
+ ret = com_core_packet_send_only(s_info.fd, packet);
packet_destroy(packet);
+ if (ret < 0) {
+ printf("Failed to send a packet: %d\n", ret);
+ return;
+ }
+
s_info.cmd = SLAVE_LIST;
s_info.age++;
}
static void send_command(const char *cmd, const char *var, const char *val)
{
struct packet *packet;
+ int ret;
if (s_info.cmd != NOP) {
printf("Previous command is not finished\n");
}
packet = packet_create_noack("master_ctrl", "sss", cmd, var, val);
- com_core_packet_send_only(s_info.fd, packet);
+ if (!packet) {
+ printf("Failed to create a ctrl packet\n");
+ return;
+ }
+
+ ret = com_core_packet_send_only(s_info.fd, packet);
packet_destroy(packet);
+ if (ret < 0) {
+ printf("Failed to send packet ctrl\n");
+ return;
+ }
+
s_info.cmd = MASTER_CTRL;
s_info.age++;
}
static void send_pkg_list(void)
{
struct packet *packet;
+ int ret;
if (s_info.cmd != NOP) {
printf("Previous command is not finished\n");
return;
}
- com_core_packet_send_only(s_info.fd, packet);
+ ret = com_core_packet_send_only(s_info.fd, packet);
packet_destroy(packet);
+ if (ret < 0) {
+ printf("Failed to create a packet\n");
+ return;
+ }
+
s_info.cmd = PKG_LIST;
s_info.age++;
struct node *parent;
const char *name;
struct instance *inst;
+ int ret;
if (s_info.cmd != NOP) {
printf("Previous command is not finished\n");
name = node_name(parent);
packet = packet_create_noack("pkg_ctrl", "sss", "rminst", name, inst->id);
- com_core_packet_send_only(s_info.fd, packet);
+ if (!packet) {
+ printf("Failed to create a packet\n");
+ return;
+ }
+
+ ret = com_core_packet_send_only(s_info.fd, packet);
packet_destroy(packet);
+ if (ret < 0) {
+ printf("Failed to send a packet: %d\n", ret);
+ return;
+ }
+
+ s_info.cmd = INST_CTRL;
+ s_info.age++;
+}
+
+static void send_inst_fault(void)
+{
+ struct packet *packet;
+ struct node *parent;
+ const char *name;
+ struct instance *inst;
+ int ret;
+
+ if (s_info.cmd != NOP) {
+ printf("Previous command is not finished\n");
+ return;
+ }
+
+ parent = node_parent(s_info.targetdir);
+ if (!parent) {
+ printf("Invalid argument\n");
+ return;
+ }
+
+ if (!node_parent(parent)) {
+ printf("Invalid argument\n");
+ return;
+ }
+
+ name = node_name(node_parent(parent));
+ if (!name || strcmp(name, "package")) {
+ printf("Invalid argument\n");
+ return;
+ }
+
+ inst = node_data(s_info.targetdir);
+ name = node_name(parent);
+
+ packet = packet_create_noack("pkg_ctrl", "sss", "faultinst", name, inst->id);
+ if (!packet) {
+ printf("Failed to create a packet\n");
+ return;
+ }
+
+ ret = com_core_packet_send_only(s_info.fd, packet);
+ packet_destroy(packet);
+ if (ret < 0) {
+ printf("Failed to send a packet: %d\n", ret);
+ return;
+ }
+
s_info.cmd = INST_CTRL;
s_info.age++;
}
static void send_inst_list(const char *pkgname)
{
struct packet *packet;
+ int ret;
if (s_info.cmd != NOP) {
printf("Previous command is not finished\n");
return;
}
- com_core_packet_send_only(s_info.fd, packet);
+ ret = com_core_packet_send_only(s_info.fd, packet);
packet_destroy(packet);
+ if (ret < 0) {
+ printf("Failed to send a packet: %d\n", ret);
+ return;
+ }
+
s_info.cmd = INST_LIST;
s_info.age++;
}
-static inline void help(void)
+static void help(void)
{
printf("liveinfo - Livebox utility\n");
printf("------------------------------ [Option] ------------------------------\n");
printf("-b Batch mode\n");
+ printf("-x execute command\n");
printf("------------------------------ [Command list] ------------------------------\n");
printf("\e[32mcd [PATH] - Change directory\e[0m\n");
printf("\e[32mls [ | PATH] - List up content as a file\e[0m\n");
printf("\e[32mx resize Pix w h - Resize the window\e[0m\n");
printf("\e[32mx map Pix - Show the window\e[0m\n");
printf("\e[32mx unmap Pix - Hide the window\e[0m\n");
+ printf("\e[32mx capture Pix outfile - Capture pixmap and save it to outfile\e[0m\n");
printf("\e[32msh [command] Execute shell command, [command] should be abspath\e[0m\n");
printf("\e[32mexit - \e[0m\n");
printf("\e[32mquit - \e[0m\n");
{
struct node *node;
s_info.rootdir = node_create(NULL, NULL, NODE_DIR);
- if (!s_info.rootdir)
+ if (!s_info.rootdir) {
return;
+ }
node_set_mode(s_info.rootdir, NODE_READ | NODE_EXEC);
node = node_create(s_info.rootdir, "provider", NODE_DIR);
{
}
-static inline struct node *update_target_dir(const char *cmd)
+static struct node *update_target_dir(const char *cmd)
{
struct node *node;
int len = 0;
while (*src && *src == ' ') src++;
- if (!*src)
+ if (!*src) {
return 0;
+ }
while (*src && *src != ' ') {
*out++ = *src++;
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");
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)
+static int do_set(const char *cmd)
{
int i;
char variable[4096] = { '0', };
i = get_token(cmd, variable);
cmd += i;
- while (*cmd && *cmd == ' ') cmd++;
+ while (*cmd && *cmd == ' ') {
+ cmd++;
+ }
if (!i || !*cmd) {
printf("Invalid argument(%s): set [VAR] [VAL]\n", cmd);
cmd += 2;
- while (*cmd && *cmd == ' ')
+ while (*cmd && *cmd == ' ') {
cmd++;
+ }
s_info.targetdir = *cmd ? update_target_dir(cmd) : s_info.curdir;
if (!s_info.targetdir) {
{
cmd += 2;
- while (*cmd && *cmd == ' ')
+ while (*cmd && *cmd == ' ') {
cmd++;
+ }
- if (!*cmd)
+ if (!*cmd) {
return -1;
+ }
if (s_info.cmd != NOP) {
printf("Waiting the server response\n");
{
cmd += 2;
while (*cmd && *cmd == ' ') cmd++;
- if (!*cmd)
+ if (!*cmd) {
return -1;
+ }
if (s_info.cmd != NOP) {
printf("Waiting the server response\n");
return 0;
}
+static inline int do_fault(const char *cmd)
+{
+ cmd += 5;
+ while (*cmd && *cmd == ' ') cmd++;
+ if (!*cmd) {
+ return -1;
+ }
+
+ if (s_info.cmd != NOP) {
+ printf("Waiting the server response\n");
+ return -EBUSY;
+ }
+
+ s_info.targetdir = update_target_dir(cmd);
+ if (!s_info.targetdir) {
+ printf("%s is not exists\n", cmd);
+ return -ENOENT;
+ }
+
+ if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
+ printf("Access denied %s\n", cmd);
+ return -EACCES;
+ }
+
+ send_inst_fault();
+ return 0;
+}
+
#if !defined(WCOREDUMP)
#define WCOREDUMP(a) 0
#endif
-static inline void do_sh(const char *cmd)
+static void do_sh(const char *cmd)
{
pid_t pid;
cmd += 3;
- while (*cmd && *cmd == ' ') cmd++;
- if (!*cmd)
+ while (*cmd && *cmd == ' ') {
+ cmd++;
+ }
+
+ if (!*cmd) {
return;
+ }
pid = fork();
if (pid == 0) {
int idx;
idx = 0;
- while (idx < sizeof(command) && *cmd && *cmd != ' ')
+ while (idx < (sizeof(command) - 1) && *cmd && *cmd != ' ') {
command[idx++] = *cmd++;
+ }
command[idx] = '\0';
- if (execl(command, cmd, NULL) < 0)
+ if (execl(command, cmd, NULL) < 0) {
printf("Failed to execute: %s\n", strerror(errno));
+ }
exit(0);
} else if (pid < 0) {
}
}
-static inline void do_x(const char *cmd)
+static inline int get_pixmap_size(Display *disp, Pixmap id, int *x, int *y, unsigned int *w, unsigned int *h)
+{
+ Window dummy_win;
+ unsigned int dummy_border, dummy_depth;
+ int _x;
+ int _y;
+
+ if (!x) {
+ x = &_x;
+ }
+
+ if (!y) {
+ y = &_y;
+ }
+
+ if (!XGetGeometry(disp, id, &dummy_win, x, y, w, h, &dummy_border, &dummy_depth)) {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static inline int do_capture(Display *disp, Pixmap id, const char *filename)
+{
+ XShmSegmentInfo si;
+ XImage *xim;
+ Visual *visual;
+ unsigned int w;
+ unsigned int h;
+ int bufsz;
+ int fd;
+ Screen *screen;
+
+ screen = DefaultScreenOfDisplay(disp);
+ visual = DefaultVisualOfScreen(screen);
+
+ if (get_pixmap_size(disp, id, NULL, NULL, &w, &h) < 0) {
+ printf("Failed to get size of a pixmap\n");
+ return -EINVAL;
+ }
+
+ printf("Pixmap size: %dx%d\n", w, h);
+ bufsz = w * h * sizeof(int);
+
+ si.shmid = shmget(IPC_PRIVATE, bufsz, IPC_CREAT | 0666);
+ if (si.shmid < 0) {
+ printf("shmget: %s\n", strerror(errno));
+ return -EFAULT;
+ }
+
+ si.readOnly = False;
+ si.shmaddr = shmat(si.shmid, NULL, 0);
+ if (si.shmaddr == (void *)-1) {
+
+ if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
+ printf("shmctl: %s\n", strerror(errno));
+ }
+
+ return -EFAULT;
+ }
+
+ /*!
+ * \NOTE
+ * Use the 24 bits Pixmap for Video player
+ */
+ xim = XShmCreateImage(disp, visual, 24 /* (depth << 3) */, ZPixmap, NULL, &si, w, h);
+ if (xim == NULL) {
+ if (shmdt(si.shmaddr) < 0) {
+ printf("shmdt: %s\n", strerror(errno));
+ }
+
+ if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
+ printf("shmctl: %s\n", strerror(errno));
+ }
+
+ return -EFAULT;
+ }
+
+ xim->data = si.shmaddr;
+ XShmAttach(disp, &si);
+
+ XShmGetImage(disp, id, xim, 0, 0, 0xFFFFFFFF);
+ XSync(disp, False);
+
+ fd = open(filename, O_CREAT | O_RDWR, 0644);
+ if (fd >= 0) {
+ if (write(fd, xim->data, bufsz) != bufsz) {
+ printf("Data is not fully written\n");
+ }
+
+ if (close(fd) < 0) {
+ printf("close: %s\n", strerror(errno));
+ }
+ } else {
+ printf("Error: %sn\n", strerror(errno));
+ }
+
+ XShmDetach(disp, &si);
+ XDestroyImage(xim);
+
+ if (shmdt(si.shmaddr) < 0) {
+ printf("shmdt: %s\n", strerror(errno));
+ }
+
+ if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
+ printf("shmctl: %s\n", strerror(errno));
+ }
+
+ return 0;
+}
+
+static void do_x(const char *cmd)
{
Display *disp;
cmd += 2;
- while (*cmd && *cmd == ' ') cmd++;
- if (!*cmd)
+ while (*cmd && *cmd == ' ') {
+ cmd++;
+ }
+
+ if (!*cmd) {
return;
+ }
disp = XOpenDisplay(NULL);
if (!disp) {
XFlush(disp);
printf("Damage: %u %d %d %d %d\n", winId, x, y, w, h);
+ } else if (!strncasecmp(cmd, "capture ", 8)) {
+ unsigned int winId;
+ char filename[256];
+
+ cmd += 8;
+
+ if (sscanf(cmd, "%u %255[^ ]", &winId, filename) != 2) {
+ printf("Invalid argument\nx capture WINID_DEC FILENAME (%s)\n", cmd);
+ return;
+ }
+ if (do_capture(disp, winId, filename) == 0) {
+ printf("Captured: %s\n", filename);
+ }
} else if (!strncasecmp(cmd, "resize ", 7)) {
unsigned int winId;
int w;
static inline const char *get_command(int idx)
{
idx = s_info.history_top + idx;
- while (idx < 0)
+ 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 */
- while (*cmd && *cmd == ' ') cmd++;
+ while (*cmd && *cmd == ' ') {
+ cmd++;
+ }
if (strlen(cmd) && *cmd != '#') {
if (!strncasecmp(cmd, "exit", 4) || !strncasecmp(cmd, "quit", 4)) {
ecore_main_loop_quit();
} else if (!strncasecmp(cmd, "set ", 4)) {
- if (do_set(cmd) == 0)
+ 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)
+ if (do_get(cmd) == 0) {
return;
+ }
} else if (!strncasecmp(cmd, "ls", 2)) {
- if (do_ls(cmd) == 0)
+ if (do_ls(cmd) == 0) {
return;
+ }
} else if (!strncasecmp(cmd, "cd", 2)) {
- if (do_cd(cmd) == 0)
+ if (do_cd(cmd) == 0) {
return;
+ }
} else if (!strncasecmp(cmd, "rm", 2)) {
- if (do_rm(cmd) == 0)
+ if (do_rm(cmd) == 0) {
+ return;
+ }
+ } else if (!strncasecmp(cmd, "fault", 5)) {
+ if (do_fault(cmd) == 0) {
return;
+ }
} else if (!strncasecmp(cmd, "sh ", 3)) {
do_sh(cmd);
} else if (!strncasecmp(cmd, "x ", 2)) {
}
break;
case 0x42: /* DOWN */
- if (s_info.history_idx >= 0)
+ if (s_info.history_idx >= 0) {
break;
+ }
printf("%s2K%s1G", escape_str, escape_str);
tmp = get_command(++s_info.history_idx);
idx = s_info.quick_idx;
}
- if (!s_info.quick_search_node)
+ 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));
case '\r':
cmd_buffer[idx] = '\0';
idx = 0;
- if (s_info.input_fd == STDIN_FILENO || s_info.verbose)
+ 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));
default:
cmd_buffer[idx++] = ch;
- if (s_info.input_fd == STDIN_FILENO || s_info.verbose)
+ if (s_info.input_fd == STDIN_FILENO || s_info.verbose) {
putc((int)ch, stdout);
+ }
if (idx == sizeof(cmd_buffer) - 1) {
cmd_buffer[idx] = '\0';
}
}
- if (ret < 0 && !fd_handler)
+ if (ret < 0 && !fd_handler) {
ecore_main_loop_quit();
+ }
return ECORE_CALLBACK_RENEW;
}
}
pkginfo->pkgid = strdup("conf.file");
- if (!pkginfo->pkgid)
+ if (!pkginfo->pkgid) {
printf("Error: %s\n", strerror(errno));
+ }
pkginfo->primary = 1;
node_set_age(node, s_info.age);
pkginfo->slavename = strdup(slavename);
- if (!pkginfo->slavename)
+ if (!pkginfo->slavename) {
printf("Error: %s\n", strerror(errno));
+ }
pkginfo->abi = strdup(abi);
- if (!pkginfo->abi)
+ if (!pkginfo->abi) {
printf("Error: %s\n", strerror(errno));
+ }
pkginfo->pid = pid;
pkginfo->refcnt = refcnt;
free(slaveinfo->state);
slaveinfo->pkgname = strdup(pkgname);
- if (!slaveinfo->pkgname)
+ if (!slaveinfo->pkgname) {
printf("Error: %s\n", strerror(errno));
+ }
slaveinfo->abi = strdup(abi);
- if (!slaveinfo->abi)
+ if (!slaveinfo->abi) {
printf("Error: %s\n", strerror(errno));
+ }
slaveinfo->state = strdup(state);
- if (!slaveinfo->state)
+ if (!slaveinfo->state) {
printf("Error: %s\n", strerror(errno));
+ }
slaveinfo->pid = pid;
slaveinfo->secured = secured;
free(instinfo->state);
instinfo->id = strdup(inst_id);
- if (!instinfo->id)
+ if (!instinfo->id) {
printf("Error: %s\n", strerror(errno));
+ }
instinfo->cluster = strdup(cluster);
- if (!instinfo->cluster)
+ if (!instinfo->cluster) {
printf("Error: %s\n", strerror(errno));
+ }
instinfo->category = strdup(category);
- if (!instinfo->category)
+ if (!instinfo->category) {
printf("Error: %s\n", strerror(errno));
+ }
instinfo->state = strdup(state);
- if (!instinfo->state)
+ if (!instinfo->state) {
printf("Error: %s\n", strerror(errno));
+ }
instinfo->period = period;
instinfo->width = width;
s_info.fd_handler = ecore_main_fd_handler_add(s_info.fifo_handle, ECORE_FD_READ, read_cb, NULL, NULL, NULL);
if (!s_info.fd_handler) {
printf("Failed to add a fd handler\n");
- close(s_info.fifo_handle);
+ if (close(s_info.fifo_handle) < 0) {
+ printf("close: %s\n", strerror(errno));
+ }
s_info.fifo_handle = -EINVAL;
ecore_main_loop_quit();
return -EFAULT;
prompt(NULL);
if (s_info.input_fd == STDIN_FILENO) {
- if (fcntl(s_info.input_fd, F_SETFL, O_NONBLOCK) < 0)
+ if (fcntl(s_info.input_fd, F_SETFL, O_NONBLOCK) < 0) {
printf("Error: %s\n", strerror(errno));
+ }
s_info.in_handler = ecore_main_fd_handler_add(s_info.input_fd, ECORE_FD_READ, input_cb, NULL, NULL, NULL);
if (!s_info.in_handler) {
{ "batchmode", required_argument, 0, 'b' },
{ "help", no_argument, 0, 'h' },
{ "verbose", required_argument, 0, 'v' },
+ { "execute", required_argument, 0, 'x' },
{ 0, 0, 0, 0 }
};
int option_index;
int c;
do {
- c = getopt_long(argc, argv, "b:hv:", long_options, &option_index);
+ c = getopt_long(argc, argv, "b:hv:x:", long_options, &option_index);
switch (c) {
case 'b':
if (!optarg || !*optarg) {
if (s_info.input_fd != STDIN_FILENO) {
/* Close the previously, opened file */
- close(s_info.input_fd);
+ if (close(s_info.input_fd) < 0) {
+ printf("close: %s\n", strerror(errno));
+ }
}
s_info.input_fd = open(optarg, O_RDONLY);
s_info.verbose = !strcmp(optarg, "true");
break;
+ case 'x':
+ if (!optarg || !*optarg) {
+ printf("Invalid argument\n");
+ help();
+ return -EINVAL;
+ }
+ break;
default:
break;
}
} while (c != -1);
ecore_init();
+
+#if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
g_type_init();
+#endif
com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
ttystate.c_lflag &= ~(ICANON | ECHO);
ttystate.c_cc[VMIN] = 1;
- if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0)
+ if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0) {
printf("Error: %s\n", strerror(errno));
+ }
}
} else {
printf("Batch mode enabled\n");
}
- if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0)
+ if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0) {
printf("Error: %s\n", strerror(errno));
+ }
init_directory();
if (s_info.input_fd == STDIN_FILENO) {
ttystate.c_lflag |= ICANON | ECHO;
- if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0)
+ if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0) {
printf("Error: %s\n", strerror(errno));
+ }
} else {
- close(s_info.input_fd);
+ if (close(s_info.input_fd) < 0) {
+ printf("close: %s\n", strerror(errno));
+ }
}
if (s_info.fifo_handle > 0) {
- close(s_info.fifo_handle);
+ if (close(s_info.fifo_handle) < 0) {
+ printf("close: %s\n", strerror(errno));
+ }
s_info.fifo_handle = -EINVAL;
}