The Linux Programming Interface

(nextflipdebug5) #1

982 Chapter 47


Listing 47-8: Performing System V semaphore operations with semop()
––––––––––––––––––––––––––––––––––––––––––––––––––––––––– svsem/svsem_op.c
#include <sys/types.h>
#include <sys/sem.h>
#include <ctype.h>
#include "curr_time.h" /* Declaration of currTime() */
#include "tlpi_hdr.h"

#define MAX_SEMOPS 1000 /* Maximum operations that we permit for
a single semop() */

static void
usageError(const char *progName)
{
fprintf(stderr, "Usage: %s semid op[,op...] ...\n\n", progName);
fprintf(stderr, "'op' is either: <sem#>{+|-}<value>[n][u]\n");
fprintf(stderr, " or: <sem#>=0[n]\n");
fprintf(stderr, " \"n\" means include IPC_NOWAIT in 'op'\n");
fprintf(stderr, " \"u\" means include SEM_UNDO in 'op'\n\n");
fprintf(stderr, "The operations in each argument are "
"performed in a single semop() call\n\n");
fprintf(stderr, "e.g.: %s 12345 0+1,1-2un\n", progName);
fprintf(stderr, " %s 12345 0=0n 1+1,2-1u 1=0\n", progName);
exit(EXIT_FAILURE);
}

/* Parse comma-delimited operations in 'arg', returning them in the
array 'sops'. Return number of operations as function result. */

static int
parseOps(char *arg, struct sembuf sops[])
{
char *comma, *sign, *remaining, *flags;
int numOps; /* Number of operations in 'arg' */

for (numOps = 0, remaining = arg; ; numOps++) {
if (numOps >= MAX_SEMOPS)
cmdLineErr("Too many operations (maximum=%d): \"%s\"\n",
MAX_SEMOPS, arg);

if (*remaining == '\0')
fatal("Trailing comma or empty argument: \"%s\"", arg);
if (!isdigit((unsigned char) *remaining))
cmdLineErr("Expected initial digit: \"%s\"\n", arg);

sops[numOps].sem_num = strtol(remaining, &sign, 10);

if (*sign == '\0' || strchr("+-=", *sign) == NULL)
cmdLineErr("Expected '+', '-', or '=' in \"%s\"\n", arg);
if (!isdigit((unsigned char) *(sign + 1)))
cmdLineErr("Expected digit after '%c' in \"%s\"\n", *sign, arg);

sops[numOps].sem_op = strtol(sign + 1, &flags, 10);
Free download pdf