Systems Programming

Introduction

Most programming languages attempt to work in a platform independant way. For example

These libraries all provide facilities to create processes in a simple way, to open, read and write files. These must all be at the lowest common denominator of all the platforms.

On the other hand, to get the best performance or to use all of the features supplied by an Operating System, you need to use the specific facilities provided by that O/S. These will almost certainly be O/S specific, so that to use them means that your programs will be less portable than using the general libraries.

Using system specific facilities means that you are using systems programming services. This may be for

Unix API

Contents

Standards
Documentation
System Specific Values
System Specific Structures
Examples

Standards

The POSIX (Portable Operating System Interface...) defines the standard API for all versions of Unix. It attempts to make the API common across many platforms. There are many levels of POSIX, each addressing different areas of the O/S services. POSIX 1003.1 addresses Other versions of POSIX address issues such as networking, threads, real-time processing, etc.

Documentation

The Unix documentation is all online, in directory /usr/man. It is accessible using the command
man [-s section] command
The command
apropos keyword
can be used to search for commands.

Section 2 of the manual is the O/S basic API. For example,

man 2 open
gives the entry for opening a file.

Section 3 of the manual is additional C level calls, some at the O/S level, some from others. For example

man 3 getlogin

Errors

In C, everything is a function, sometimes returning no value (void functions). Systems calls usually use this value to signal errors

System Specific Values

API specification files are stored in /usr/include and used in C programs by the
#include <...>
mechanism.

Values about sizes of primitive data types is stored in /usr/include/values.h

System Specific Structures

Common data stuctures are specified in /usr/include/types.h (or includes that they point to). (Warning: reading these can cause brain-strain!). Read the online doco instead.

Examples

The following are simple examples of services offered in Unix that do not require much background.

getlogin()

The function getlogin() is defined by
char *getlogin(void)
It returns a string holding the login name, or NULL on failure. You should not modify the returned string.
#include <stdio.h>
int main(int argc, char **argv)
{
    char *login;

    if ((login = getlogin()) != NULL) {
        printf("Login name %s\n", login);
    } else {
        fprintf(stderr, "Can't find login name\n");
        exit(1);
    }
    exit(0);
}


getenv

The environment holds the values of shell variables that may be accessible to the program. The function
#include <stdlib.h>

char *getenv(char *name)
takes a string as argument, and returns a string as value. The argument is the variable whose value you want. The return is the value or NULL of the variable is not set. You should not modify the return value.
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    char *path;

    if ((path = getenv("PATH")) != NULL) {
        printf("Path is: %s\n", path);
    } else {
        fprintf(stderr, "Can't find the value of PATH\n");
        exit(1);
    }
    exit(0);
}


passwd

Information about users is stored in the file /etc/passwd. The function getpwnam() returns such information given a user's name as a string.
#include <pwd.h>

struct passwd *getpwnam(char *name)
The returned structure is
struct passwd
{
  char *pw_name;                /* Username.  */
  char *pw_passwd;              /* Password.  */
  uid_t pw_uid;                 /* User ID.  */
  gid_t pw_gid;                 /* Group ID.  */
  char *pw_dir;                 /* Home directory.  */
  char *pw_shell;               /* Shell program.  */
};
This may be used as
#include <stdio.h>
#include <pwd.h>

int main(int argc, char *argv[])
{
    struct passwd *pass;
    char *name = "jan";

    if ((pass = getpwnam(name)) != NULL) {
        printf("Home dir of %s is %s \n", name,
             pass->pw_dir);
    } else {
        fprintf(stderr, "Can't find password info for %s\n",
             name);
        exit(1);
    }
    exit(0);
}


uname

System information is given by the call
#include <sys/utsname.h>

int uname(struct *utsname name)
Given the address of an existing structure, the fields are filled in. A value of -1 is returned on error. The structure is
#define _SYS_NMLN 257

struct utsname {
    char sysname[_SYS_NMLN];
    char nodename[_SYS_NMLN];
    char release[_SYS_NMLN];
    char version[_SYS_NMLN];
    char machine[_SYS_NMLN-65];
}
This may be used as
#include <stdio.h>
#include <sys/utsname.h>

int main(int argc, char *argv[])
{
    struct utsname name;

    if (uname(&name) != -1) {
        printf("System name: %s\n",
             name.sysname);
    } else {
        fprintf(stderr, "Can't find system name\n");
        exit(1);
    }
    exit(0);
}


Home Systems Software Home
Jan Newmarch (http://jan.newmarch.name) <jan@newmarch.name>

Copyright © Jan Newmarch
Last modified: Wed Nov 19 18:58:44 EST 1997