Example #1
0
ShmPipe *
sp_client_open (const char *path)
{
    ShmPipe *self = spalloc_new (ShmPipe);
    struct sockaddr_un sun;

    memset (self, 0, sizeof (ShmPipe));

    self->main_socket = socket (PF_UNIX, SOCK_STREAM, 0);
    if (self->main_socket < 0) {
        sp_close (self);
        return NULL;
    }

    sun.sun_family = AF_UNIX;
    strncpy (sun.sun_path, path, sizeof (sun.sun_path) - 1);

    if (connect (self->main_socket, (struct sockaddr *) &sun,
                 sizeof (struct sockaddr_un)) < 0)
        goto error;

    return self;

error:
    spalloc_free (ShmPipe, self);
    return NULL;
}
Example #2
0
ShmPipe *
sp_client_open (const char *path)
{
  ShmPipe *self = spalloc_new (ShmPipe);
  struct sockaddr_un sock_un;
  int flags;

  memset (self, 0, sizeof (ShmPipe));

  self->main_socket = socket (PF_UNIX, SOCK_STREAM, 0);
  self->use_count = 1;

  if (self->main_socket < 0)
    goto error;

  flags = fcntl (self->main_socket, F_GETFL, 0);
  if (flags < 0)
    goto error;

  if (fcntl (self->main_socket, F_SETFL, flags | FD_CLOEXEC) < 0)
    goto error;

  sock_un.sun_family = AF_UNIX;
  strncpy (sock_un.sun_path, path, sizeof (sock_un.sun_path) - 1);

  if (connect (self->main_socket, (struct sockaddr *) &sock_un,
          sizeof (struct sockaddr_un)) < 0)
    goto error;

  return self;

error:
  sp_client_close (self);
  return NULL;
}
Example #3
0
ShmPipe *
sp_writer_create (const char *path, size_t size, mode_t perms)
{
    ShmPipe *self = spalloc_new (ShmPipe);
    int flags;
    struct sockaddr_un sun;
    int i = 0;

    memset (self, 0, sizeof (ShmPipe));

    self->main_socket = socket (PF_UNIX, SOCK_STREAM, 0);

    if (self->main_socket < 0) {
        RETURN_ERROR ("Could not create socket (%d): %s\n", errno,
                      strerror (errno));
    }

    flags = fcntl (self->main_socket, F_GETFL, 0);
    if (flags < 0) {
        RETURN_ERROR ("fcntl(F_GETFL) failed (%d): %s\n", errno, strerror (errno));
    }

    if (fcntl (self->main_socket, F_SETFL, flags | O_NONBLOCK | FD_CLOEXEC) < 0) {
        RETURN_ERROR ("fcntl(F_SETFL) failed (%d): %s\n", errno, strerror (errno));
    }

    sun.sun_family = AF_UNIX;
    strncpy (sun.sun_path, path, sizeof (sun.sun_path) - 1);

    while (bind (self->main_socket, (struct sockaddr *) &sun,
                 sizeof (struct sockaddr_un)) < 0) {
        if (errno != EADDRINUSE)
            RETURN_ERROR ("bind() failed (%d): %s\n", errno, strerror (errno));

        if (i > 256)
            RETURN_ERROR ("Could not find a free socket name for %s", path);

        snprintf (sun.sun_path, sizeof (sun.sun_path), "%s.%d", path, i);
        i++;
    }

    self->socket_path = strdup (sun.sun_path);

    if (listen (self->main_socket, 10) < 0) {
        RETURN_ERROR ("listen() failed (%d): %s\n", errno, strerror (errno));
    }

    self->shm_area = sp_open_shm (NULL, ++self->next_area_id, 1, perms, size);

    self->perms = perms;

    if (!self->shm_area) {
        sp_close (self);
        return NULL;
    }

    return self;
}
Example #4
0
ShmBlock *
sp_writer_alloc_block (ShmPipe * self, size_t size)
{
    ShmBlock *block;
    ShmAllocBlock *ablock =
        shm_alloc_space_alloc_block (self->shm_area->allocspace, size);

    if (!ablock)
        return NULL;

    block = spalloc_new (ShmBlock);
    sp_shm_area_inc (self->shm_area);
    block->pipe = self;
    block->area = self->shm_area;
    block->ablock = ablock;
    return block;
}
Example #5
0
ShmClient *
sp_writer_accept_client (ShmPipe * self)
{
  ShmClient *client = NULL;
  int fd;
  struct CommandBuffer cb = { 0 };
  int pathlen = strlen (self->shm_area->shm_area_name) + 1;


  fd = accept (self->main_socket, NULL, NULL);

  if (fd < 0) {
    fprintf (stderr, "Could not client connection");
    return NULL;
  }

  cb.payload.new_shm_area.size = self->shm_area->shm_area_len;
  cb.payload.new_shm_area.path_size = pathlen;
  if (!send_command (fd, &cb, COMMAND_NEW_SHM_AREA, self->shm_area->id)) {
    fprintf (stderr, "Sending new shm area failed: %s", strerror (errno));
    goto error;
  }

  if (send (fd, self->shm_area->shm_area_name, pathlen, MSG_NOSIGNAL) !=
      pathlen) {
    fprintf (stderr, "Sending new shm area path failed: %s", strerror (errno));
    goto error;
  }

  client = spalloc_new (ShmClient);
  client->fd = fd;

  /* Prepend ot linked list */
  client->next = self->clients;
  self->clients = client;
  self->num_clients++;

  return client;

error:
  shutdown (fd, SHUT_RDWR);
  close (fd);
  return NULL;
}
Example #6
0
static ShmArea *
sp_open_shm (char *path, int id, int writer, mode_t perms, size_t size)
{
    ShmArea *area = spalloc_new (ShmArea);
    char tmppath[PATH_MAX];
    int flags;
    int prot;
    int i = 0;

    memset (area, 0, sizeof (ShmArea));

    area->use_count = 1;

    area->shm_area_len = size;


    if (writer)
        flags = O_RDWR | O_CREAT | O_TRUNC | O_EXCL;
    else
        flags = O_RDONLY;

    area->shm_fd = -1;

    if (path) {
        area->shm_fd = shm_open (path, flags, perms);
    } else {
        do {
            snprintf (tmppath, PATH_MAX, "/shmpipe.5%d.%5d", getpid (), i++);
            area->shm_fd = shm_open (tmppath, flags, perms);
        } while (area->shm_fd < 0 && errno == EEXIST);
    }

    if (area->shm_fd < 0) {
        RETURN_ERROR ("shm_open failed on %s (%d): %s\n",
                      path ? path : tmppath, errno, strerror (errno));
    }

    if (!path)
        area->shm_area_name = strdup (tmppath);

    if (writer) {
        if (ftruncate (area->shm_fd, size)) {
            RETURN_ERROR ("Could not resize memory area to header size,"
                          " ftruncate failed (%d): %s\n", errno, strerror (errno));
        }
    }

    if (writer)
        prot = PROT_READ | PROT_WRITE;
    else
        prot = PROT_READ;

    area->shm_area = mmap (NULL, size, prot, MAP_SHARED, area->shm_fd, 0);

    if (area->shm_area == MAP_FAILED) {
        RETURN_ERROR ("mmap failed (%d): %s\n", errno, strerror (errno));
    }

    area->id = id;

    if (writer)
        area->allocspace = shm_alloc_space_new (area->shm_area_len);

    return area;
}