title: Is it correct to call semget() followed by semop() without calling semctl()?
body: <p>I was going through the example program for semaphores in <a href="http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html#semsamp" rel="nofollow noreferrer">Beej's Guide to Unix IPC</a>.</p>
  
  <p>The example program contains the following semaphore initialization code. I am only posting a snippet from it that is relevant to the question. To see the complete code, visit the link I have provided above.</p>
  
  <pre><code>/*
  ** initsem() -- more-than-inspired by W. Richard Stevens' UNIX Network
  ** Programming 2nd edition, volume 2, lockvsem.c, page 295.
  */
  int initsem(key_t key, int nsems)  /* key from ftok() */
  {
      int i;
      union semun arg;
      struct semid_ds buf;
      struct sembuf sb;
      int semid;
  
      semid = semget(key, nsems, IPC_CREAT | IPC_EXCL | 0666);
  
      if (semid &gt;= 0) { /* we got it first */
          sb.sem_op = 1; sb.sem_flg = 0;
          arg.val = 1;
  
          printf("press return\n"); getchar();
  
          for(sb.sem_num = 0; sb.sem_num &lt; nsems; sb.sem_num++) { 
              /* do a semop() to "free" the semaphores. */
              /* this sets the sem_otime field, as needed below. */
              if (semop(semid, &amp;sb, 1) == -1) {
                  int e = errno;
                  semctl(semid, 0, IPC_RMID); /* clean up */
                  errno = e;
                  return -1; /* error, check errno */
              }
          }
  </code></pre>
  
  <p>Here is what I am unable to understand. Once <code>semget()</code> creates semaphores and returns successfully with a valid semaphore ID, the semaphores themselves are uninitialized and in an indeterminate state. This is confirmed by the man page of <code>semget</code>.</p>
  
  <blockquote>
    <p><strong>Semaphore initialization</strong></p>
    
    <p>The values of the semaphores in a newly created set are indeterminate.  (POSIX.1-2001 and POSIX.1-2008 are explicit on this point, although POSIX.1-2008 notes that a future version of the standard may
    require an implementation to initialize the semaphores to 0.)  Although Linux, like many other implementations, initializes the semaphore values to 0, a portable application cannot rely  on  this:  it
    should explicitly initialize the semaphores to the desired values.</p>
    
    <p>Initialization can be done using semctl(2) SETVAL or SETALL operation.  Where multiple peers do not know who will be the first to initialize the set, checking for a nonzero sem_otime in the associated
    data structure retrieved by a semctl(2) IPC_STAT operation can be used to avoid races.</p>
  </blockquote>
  
  <p>But in the above code <code>semctl()</code> was not called to initialize the semaphores. Instead, <code>semop()</code> was called with <code>sem_op</code> = <code>1</code>, which according to the man page of <code>semop</code> does the following.</p>
  
  <blockquote>
    <p>If sem_op is a positive integer, the operation adds this value to the semaphore value (semval).  Furthermore, if SEM_UNDO is specified for this operation, the system subtracts the  value  sem_op  from
    the semaphore adjustment (semadj) value for this semaphore.  This operation can always proceed—it never forces a thread to wait.  The calling process must have alter permission on the semaphore set.</p>
  </blockquote>
  
  <p>But without initialization, <code>semval</code> was indeterminate. So adding <code>1</code> to it still leaves it indeterminate.</p>
  
  <p>Is this code incorrect or is my understanding incorrect? If my understanding is incorrect, could you please explain me why this code is correct?</p>