Logo Search packages:      
Sourcecode: ledcontrol version File versions  Download package

pipe.c

/*
 * Pipe handling - creation, removal and reading.
 */

#include "ledd.h"

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>


/*
 * Deletes possibly existing pipe file, creates a new one and opens it.
 */
void pipe_open(File *pipe) {
      struct stat buf;

      /* Test it. */
      if (pipe->name==NULL || pipe->name[0]==0)
            return;

      /* Check for file existance. */
      if (stat(pipe->name,&buf)==0) {
            if (!S_ISFIFO(buf.st_mode))
                  G_ERROR("%s exists and is not a pipe",pipe->name);
      }

      /* Try to delete the pipefile */
      if (unlink(pipe->name)) {
            if (errno!=ENOENT)
                  G_ERROR("unable to unlink %s (%s)",
                        pipe->name,STRERROR);
      }

      /* Make it */
      umask(0);
      if (mknod(pipe->name,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IFIFO,0)) {
            G_ERROR("mknod of %s failed (%s)",pipe->name,STRERROR);
      }

      /* Open it, non-blocking mode */
      pipe->fd=open(pipe->name,O_RDONLY|O_NONBLOCK);
      if (pipe->fd==-1) {
            G_ERROR("unable to open %s (%s)",pipe->name,STRERROR);
      }

      /* Mark it as such. */
      pipe->type=TYPE_PIPE;

      return;
}


/*
 * Opens all pipes listed in opts->pipes.
 */
void pipe_open_all(options *opts) {
      GSList *list;

      for(list=opts->pipes; list; list=g_slist_next(list)) {
            if (list->data==NULL)
                  continue;
            pipe_open((File *)list->data);
      }
      return;
}

/*
 * Creates a pipe the way pipe() does, but sets it in non-blocking mode
 * and sets the close-on-exec flag to 0 (will keep open through exec()).
 * Hits G_ERROR on failure.
 */
void pipe_create(int fd[2]) {

      if (pipe(fd))
            G_ERROR("pipe creation failed (%s)",STRERROR);

      if (fcntl(fd[0],F_SETFD,0))
            G_ERROR("fcntl(fd[0],F_SETFD,0) failed (%s)",STRERROR);

      if (fcntl(fd[0],F_SETFL,O_NONBLOCK))
            G_ERROR("fcntl(fd[0],F_SETFL,O_NONBLOCK failed (%s)",STRERROR);

      if (fcntl(fd[1],F_SETFD,0))
            G_ERROR("fcntl(fd[1],F_SETFD,0) failed (%s)",STRERROR);

      if (fcntl(fd[1],F_SETFL,O_NONBLOCK))
            G_ERROR("fcntl(fd[1],F_SETFL,O_NONBLOCK) failed (%s)",
                  STRERROR);

      return;
}


/*
 * Closes the pipe file and deletes it.
 */
void pipe_close(File *pipe) {
      if (pipe->fd < 0)
            return;
      close(pipe->fd);
      pipe->fd=-1;
      if (pipe->type==TYPE_PIPE)
            if (unlink(pipe->name))
                  if (errno!=ENOENT)
                        g_warning("unable to unlink %s (%s)",
                                pipe->name,STRERROR);

      return;
}


/*
 * Closes all pipes in opts->pipes.
 */
void pipe_close_all(options *opts) {
      GSList *list;

      for (list=opts->pipes; list; list=g_slist_next(list)) {
            if (list->data==NULL)
                  continue;
            pipe_close((File *)list->data);
      }
      return;
}

      
/*
 * Checks for commands coming from the pipe, parses them and sets them
 */
void pipe_check_new(options *opts,File *pipe) {
      gchar *buf;

      buf=pipe_gets(pipe->fd);
      if (buf[0]!=0) {
            parse_pipe_command(opts,buf,pipe);
      }
      g_free(buf);

      return;
}


/*
 * Checks for commands in all pipes, parses them etc.
 * Always returns TRUE (continue looping).
 */
gboolean pipe_check_all(options *opts) {
      GSList *list;

      for (list=opts->pipes; list; list=g_slist_next(list)) {
            if (list->data==NULL)
                  continue;
            pipe_check_new(opts,list->data);
      }
      return TRUE;
}


/*
 * Gets a string from fd and returns a pointer to a newly-allocated
 * version of it. Unlimited line length.
 */
gchar *pipe_gets(int fd) {
      gchar *str;
      gint i,buflen;

      str=g_new0(gchar,128);
      buflen=128;
      for (i=0; ; i++) {
            if (i>=buflen) {
                  buflen+=128;
                  str=g_renew(gchar,str,buflen);
            }
            if (read(fd,&str[i],1)<1)
                  break;
            if (str[i]=='\n' || str[i]=='\r')
                  break;
      }
      if (str[i]=='\n' || str[i]=='\r')
            str[i]=0;
      return str;
}

Generated by  Doxygen 1.6.0   Back to index