14.4 When Only C Will Do


There are some system administrative tasks that cannot be done from a shell script or even from Perl. In such cases, it will be necessary to write a program in a programming language such as C (or whatever you like). However, many of the programming principles we've considered so far still apply.

As a first example, consider this small program, which is a version of the yes command created for a system that lacks it:

/* yes.c */  #include <stdio.h> main(argc,argv)  int argc;  char *argv[];  {  while(1)                   /* repeat forever */     if(argc>=2)             /* if there was an argument */        puts(argv[1]);       /* repeat it */     else        puts(argv[0]);       /* otherwise use command's name */  }

This command works a little differently than the standard yes command in that if no argument is given to the command, it repeats the name it was invoked under rather than "y" by default (if an argument is given, that argument is repeated indefinitely). This allows multiple hard links to be made to the same executable file: yes and no, for example. In virtually every case, repeating "yes" is equivalent to repeating "y".

This version of yes illustrates that C programming need not be incredibly complex and time-consuming, and the program made users on this system quite happy. This program could have been written in Perl, but C is actually easier and more straightforward.

The next C program, designed for an AIX system, illustrates an operation that is best performed in C. This program, setp, assigns a fixed (unvarying) priority to a process (why you might want to do so is discussed in Section 15.2). Here is a simple version, suitable for a single system administrator's own use:

/* setp.c - assign process a fixed priority */  #include <sys/sched.h>  #include <stdio.h> main(argc,argv)  char *argv[];  int argc;  {      pid_t pid;      int p;     pid=(pid_t)(atoi(*++argv));/* 1st arg is the PID */      p=atoi(*++argv);/* 2nd arg is the priority */      setpri(pid,p);/* set it */      printf("Setting priority of process %d to %d.\n",(int)pid,p);  }

The program converts its two arguments to integers with the atoi function and then invokes the AIX setpri system call to actually set the priority. The final print statement is really superfluous in this minimalist version.

The preceding version of setp is fine as an ad hoc tool created by a system administrator for herself. However, if she wants to share it with other members of the system administration staff, it is a little sloppy. Here is a better version (the most important changes are highlighted):

/* set_fprio - more careful fixed priority setting utility */  #include <sys/sched.h>  #include <stdio.h>  #include <sys/types.h>  #include <unistd.h> main(argc,argv)  char *argv[];  int argc;  {  pid_t pid;  int p, old; /* make sure root is running this */  if (getuid(  ) != (uid_t)0) {     printf("You must be root to run setp.\n");     exit(1);     } /* check for the right number of arguments */  if (argc < 3) {     printf("Usage: setp pid new-priority\n");     exit(1);     } /* convert arguments to integers */  pid=(pid_t)(atoi(*++argv));  p=atoi(*++argv);  old=setpri(pid,p);   /* save and check return value */  if (old==-1) {     printf("Priority reset failed for process %d.\n",(int)pid);     exit(1);     }  else {     printf("Changing priority of process %d from %d to %d.\n", (int)pid,old,p);     exit(0);     }  }

These are the most important changes:

  • The program first verifies that it is being run by root, because the setpri system call only works for root. It displays an error message and then exits if someone else tries to use it.

  • The program makes sure that it has the proper number of arguments (by determining whether argc is less than three or not), again printing an error and exiting if one or both of them is missing.

  • The program saves the return value of the setpri system call into the variable old. The purpose of this is not to use it in the final print statement although it is included there but to determine whether the system call succeeded or not, which is done by the if statement. Depending on setpri's return value, an appropriate message is displayed, and the program terminates with a meaningful exit value.

This is the level of care that needs to be taken when writing programs for general or even limited system use. It is not difficult or tremendously time-consuming to do things this way, but it is a bit boring.



Essential System Administration
Essential System Administration, Third Edition
ISBN: 0596003439
EAN: 2147483647
Year: 2002
Pages: 162

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net