Logo Search packages:      
Sourcecode: ksh version File versions

csserve.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1990-2007 AT&T Knowledge Ventures            *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                      by AT&T Knowledge Ventures                      *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                                                                      *
***********************************************************************/
#pragma prototyped
                  
/*
 * Glenn Fowler
 * AT&T Research
 *
 * obsolete generic server state machine
 * <css.h> provides a discipline interface with multiple servers
 */

#include "csslib.h"

struct Server_s
{
      Cssdisc_t   disc;
      Css_t*            css;
      void*       handle;
      int         (*done)(void*, int);
      int         (*con)(void*, int, Csid_t*, int, char**);
      int         (*rd)(void*, int);
      int         (*wr)(void*, int);
      int         (*to)(void*);
};

static int
acceptf(Css_t* css, Cssfd_t* fp, Csid_t* ip, char** av, Cssdisc_t* disc)
{
      register Server_t*      server = (Server_t*)disc;

      return (*server->con)(server->handle, fp->fd, ip, 0, av) ? -1 : fp->fd;
}

static int
actionf(Css_t* css, Cssfd_t* fp, Cssdisc_t* disc)
{
      register Server_t*      server = (Server_t*)disc;

      switch (fp->status)
      {
      case CS_POLL_READ:
            if (server->rd)
                  return (*server->rd)(server->handle, fp->fd) < 0 ? -1 : 1;
            break;
      case CS_POLL_WRITE:
            if (server->wr)
                  return (*server->wr)(server->handle, fp->fd) < 0 ? -1 : 1;
            break;
      }
      return 0;
}

static int
exceptf(Css_t* css, unsigned long op, unsigned long arg, Cssdisc_t* disc)
{
      register Server_t*      server = (Server_t*)disc;

      switch (op)
      {
      case CSS_CLOSE:
            if (server->done)
                  (*server->done)(server->handle, 0);
            return 0;
      case CSS_INTERRUPT:
            if (server->done && !(*server->done)(server->handle, EXIT_TERM(arg)))
                  return 1;
            error(ERROR_SYSTEM|3, "%s: interrupt exit", fmtsignal(arg));
            return -1;
      case CSS_DORMANT:
      case CSS_TIMEOUT:
      case CSS_WAKEUP:
            return !server->to ? 0 : (*server->to)(server->handle) < 0 ? -1 : 1;
      }
      error(ERROR_SYSTEM|3, "poll error [op=%lu arg=%lu]", op, arg);
      return -1;
}

int
csfd(Cs_t* state, int fd, int op)
{
      return !state->server || cssfd(state->server->css, fd, op) ? -1 : 0;
}

/*
 * csserve() wakeup and timeout are mutually exclusive
 */

unsigned long
cstimeout(register Cs_t* state, unsigned long ms)
{
      unsigned long     rv;

      if (!state->server)
            return CS_NEVER;
      state->server->css->disc->wakeup = 0;
      rv = state->server->css->disc->timeout;
      state->server->css->disc->timeout = ms;
      return rv;
}

/*
 * csserve() wakeup and timeout are mutually exclusive
 */

unsigned long
cswakeup(Cs_t* state, unsigned long ms)
{
      unsigned long     rv;

      if (!state->server)
            return CS_NEVER;
      state->server->css->disc->timeout = 0;
      rv = state->server->css->disc->wakeup;
      state->server->css->disc->wakeup = ms;
      return rv;
}

/*
 * server state machine
 */

void
csserve(Cs_t* state, void* handle, const char* path, void* (*init)(void*, int), int (*done)(void*, int), int (*con)(void*, int, Csid_t*, int, char**), int (*rd)(void*, int), int (*wr)(void*, int), int (*to)(void*))
{
      register Server_t*      server;

      if (!con && !rd)
            error(ERROR_PANIC, "a connect or read handler must be supplied");
      if (!(server = newof(0, Server_t, 1, 0)))
            error(ERROR_SYSTEM|3, "out of space");
      state->server = server;
      server->disc.version = CSS_VERSION;
      server->disc.flags = CSS_DAEMON|CSS_LOG|CSS_CLOSE|CSS_ERROR|CSS_INTERRUPT|CSS_TIMEOUT|CSS_WAKEUP;
      server->handle = handle;
      server->con = con;
      if (server->con)
            server->disc.acceptf = acceptf;
      server->rd = rd;
      server->wr = wr;
      if (server->rd || server->wr)
            server->disc.actionf = actionf;
      server->to = to;
      server->disc.errorf = errorf;
      server->disc.exceptf = exceptf;
      server->done = done;
      close(0);
      if (!(server->css = cssopen(path, (Cssdisc_t*)server)))
            exit(1);
      error_info.id = server->css->service;
      state->id = server->css->id;
      state->cs = server->css->path;
      state->control = state->mount + (server->css->control - server->css->mount);
      strcpy(state->mount, server->css->mount);
#ifdef SIGCHLD
      if (!done)
            signal(SIGCHLD, SIG_DFL);
#endif

      /*
       * we   the
       *   are  
       *         ser
       *            ver
       *
       * in background
       * no controlling tty
       * pwd is the service data directory
       * stdin is the connect stream
       * stdout is /dev/null
       * stderr is CS_MNT_LOG in the service data directory
       * umask matches service mode
       */

      if (init)
            server->handle = (*init)(server->handle, server->css->fdmax);
      csspoll(CS_NEVER, 0);
}

int
_cs_fd(int fd, int op)
{
      return csfd(&cs, fd, op);
}

void
_cs_serve(void* handle, const char* path, void* (*init)(void*, int), int (*done)(void*, int), int (*con)(void*, int, Csid_t*, int, char**), int (*rd)(void*, int), int (*wr)(void*, int), int (*to)(void*))
{
      csserve(&cs, handle, path, init, done, con, rd, wr, to);
}

unsigned long
_cs_timeout(unsigned long ms)
{
      return cstimeout(&cs, ms);
}

unsigned long
_cs_wakeup(unsigned long ms)
{
      return cswakeup(&cs, ms);
}

Generated by  Doxygen 1.6.0   Back to index