Account Links: Cart | Register | Log In

Skip to content


 
An Introduction to C Development on Linux

Final Thoughts

You should now know how to do all of the basic elements of development under Linux. There are a large number of options out there, but the tools discussed here are by far the most common. Knowing them will serve you well. As has been mentioned many times throughout this paper, there are lots of resources with information about these tools. With the basic information you have now you should be able to read and understand any of them to expand your knowledge. Read 'man' pages and 'HOWTO' files, and look things up on Linux-related Web pages.

If you have any questions/comments/criticisms feel free to contact the author:

Nathan Thomas
nthomas@redhat.com
Technical Developer
Red Hat, Inc.

Resources

Below are printouts of the various source files discussed throughout the text:

hw.c:

#include "hw.h"


int mainhello(char *message)
{
   int retval = 0;

   retval = massivehello(message);
   error_handle(retval);

   return(retval);

}

hw.h

#include <string.h>        /*For the strcmp call*/
#include <unistd.h>        /*symbolic constants- O_WRONLY and O_NDELAY here*/
#include <stdio.h>         /*Standard input and output for our writing out*/
#include <utmp.h>          /*UTMP functionality- try 'man utmp' for more info*/
#include <fcntl.h>         /*file control for handling file descriptors*/
#include <pwd.h>           /*for access to password/user information*/

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <setjmp.h>

/*This is our primary function- it takes in the string to output*/
int massivehello(char *message)
{
   int uid;                /*current user's id number*/
   static int fd;          /*file descriptor id*/
   FILE *fp;               /*file pointer*/
   char *ttydata, *user;   /*buffers for terminal info, and username*/
   struct passwd *pwd;     /*password data structure*/
   struct utmp *utmp;      /*process information structure*/

   ttydata = (char*)malloc(50*sizeof(char));

   uid = getuid();         /*get the user's id number*/
   pwd = getpwuid(uid);    /*get the current process id (this program!)*/

   setutent();             /*go to the beginning of the process list*/

   user = pwd ? pwd->pw_name : "root";  /*figure out who is running this*/


   /*go through the process list and for each entry our 'user' owns, output*/
   /*our message*/

   while ((utmp = getutent()) != NULL)
   {
      if(utmp->ut_type != USER_PROCESS || /*make sure it's a user process*/
         utmp->ut_user[0] == 0 ||         /*and their is a valid user*/
         (strcmp(utmp->ut_user, user)))   /*and that user is our 'user'*/
      {
         continue;          /*skip this entry if any of that stuff failed*/
      }
      sprintf(ttydata, "/dev/%s", utmp->ut_line);

      /*ttydata is the name of the terminal to write to*/

      fd = open(ttydata, O_WRONLY | O_NDELAY);
         if ((fp = fdopen(fd, "w")) != NULL)
         {
            fputs(message, fp);
            fputs("\n", fp);
            fclose(fp);
         } else
         {
            close(fd);
         }
   }


   endutent();                       /*close the utmp file*/

   free(ttydata);

   return(0);                        /*exit with no errors*/
}

ui.c:

#include <stdlib.h>
#include <stdio.h>
#include "ui.h"

int main(int argc, char **argv)
{
   int retval = 0;
   int string_length = 0;
   char *message;

   string_length = input_length(argc, argv);

   message = ((char*)(malloc(string_length*(sizeof(char)))));

   retval = parser(argc, argv, message);
   error_handle(retval);

   retval = mainhello(message);
   error_handle(retval);

   free(message);

   return(retval);
}

ui.h:

#include <stdlib.h>
#include <stdio.h>

void error_handle(int retval)
{
   if (retval)
   {
      fprintf(stderr, "Error: exiting\n");
      exit(1);
   }
   return;
}

int spew_usage(char* argv_0)
{
   fprintf(stderr, "Usage: %s [MESSAGE]\n", argv_0);
   fprintf(stderr, "Outputs MESSAGE to all terminals owned by caller\n");
   fprintf(stderr, "With no MESSAGE \"Hello World!\" is output\n");
}

int input_length(int argc, char **argv)
{
   int counter = 1;
   int string_length = 0;

   if (argc == 1)
   {
     return(strlen("Hello World!\n"));
   }

   while (counter < argc)
   {
      string_length += (strlen(argv[counter]));
      counter++;
   }

   string_length += argc;  /*to account for spaces*/

   return(string_length);
}


int parser(int argc, char **argv, char *message)
{
   int retval = 0;
   int counter = 2;

   if (argc == 1)
   {
      strcpy(message, "Hello World!\n");
      return(retval);

   }

   if (!(strcmp(argv[1], "--help")))
   {
      spew_usage(argv[0]);
      return(retval);
   }

   strcpy(message, argv[1]);
   strcat(message, " ");

   while (counter < argc)
   {
      strcat(message, argv[counter]);
      strcat(message, " ");
      counter++;

   }

   return(retval);
}

makefile:

miniwall : ui.o hw.o
        gcc -o miniwall ui.o hw.o

ui.o : ui.c
        gcc -c -w ui.c

hw.o : hw.c
        gcc -c -w hw.c

.PHONY : clean

clean :
        rm -f *.o miniwall

back home  
Using the Concurrent Versions System for Source Management    

 

[an error occurred while processing this directive]