Publishers

Updated: April 19, 2023

Here are some examples of a simple publisher that loops forever, changing the value of an attribute. Each publisher also updates its own counter attribute, so we can be sure that the programs are actually working. They assume that the system is using the default PPS directory, /pps.

Note: Although these examples check for the existence of /pps (to make sure that PPS is running), you need to create the /pps/example directory before running them.

One publisher

This publisher opens (perhaps creating) the button object, and then loops, toggling the button's state.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{
   int fd;
   int state = 0;
   char buf[256];
   struct stat stat_buf;
   int count = 0;
   ssize_t len, bytes_written;

   /* Is PPS running? */
   if (stat( "/pps", &stat_buf) != 0)
   {
      if (errno == ENOENT)
         printf ("The PPS server isn't running.\n");
      else
         perror ("stat (/pps)");
      return EXIT_FAILURE;
   }

   /* Create the "button" object (if it doesn't already exist). */
   fd = open( "/pps/example/button", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );
   if ( fd < 0 )
   {
      perror ("Couldn't open /pps/example/button");
      return EXIT_FAILURE;
   }

   /* Loop forever, toggling the state of the button. */
   while ( 1 )
   {
      usleep (500);
      count++;
      len = snprintf(buf, 256, "state::%s\npub1::%d", state ? "on" : "off", count);
      bytes_written = write( fd, buf, len );
      if (bytes_written == -1)
      {
         perror ("write()");
      }
      else if (bytes_written != len)
      {
         printf ("Bytes written: %d String length: %d\n", bytes_written, len);
      }

      if ( state == 0 )
         state = 1;
      else
         state = 0;
   }

   return EXIT_SUCCESS;
}

Note the following:

An additional publisher

This publisher updates the same object as the first publisher, but it toggles the button's color attribute.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{
   int fd;
   int color = 0;
   int count = 0;
   char buf[256];
   struct stat stat_buf;
   ssize_t len, bytes_written;

   /* Is PPS running? */
   if (stat( "/pps", &stat_buf) != 0)
   {
      if (errno == ENOENT)
         printf ("The PPS server isn't running.\n");
      else
         perror ("stat (/pps)");
      return EXIT_FAILURE;
   }

   /* Create the "button" object (if it doesn't already exist). */
   fd = open( "/pps/example/button", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );
   if ( fd < 0 )
   {
      perror ("Couldn't open /pps/example/button");
      return EXIT_FAILURE;
   }

   /* Loop forever, changing the color. */
   while ( 1 )
   {
      usleep (300);
      count++;
      len = snprintf(buf, 256, "color::%s\npub2::%d", color ? "red" : "green", count);
      bytes_written = write( fd, buf, len );
      if (bytes_written == -1)
      {
          perror ("write()");
      }
      else if (bytes_written != len)
      {
          printf ("Bytes written: %d String length: %d\n", bytes_written, len);
      }

      if ( color == 0 )
          color = 1;
      else
         color = 0;
   }

   return EXIT_SUCCESS;
}

This program is very similar to the first publisher. You can have as many publishers as you wish updating the same object; PPS makes sure that each update is an atomic operation—the publishers don't even have to know that each other exists.