# semget

## NAME



           semget - get a System V semaphore set identifier
    


## LIBRARY



           Standard C library (_libc_ , _-lc_)
    


## SYNOPSIS



           **#include <sys/sem.h>**
    
           **int semget(key_t** _key_**, int** _nsems_**, int** _semflg_**);**
    


## DESCRIPTION



           The **semget**() system call returns the System V semaphore set
           identifier associated with the argument _key_.  It may be used
           either to obtain the identifier of a previously created semaphore
           set (when _semflg_ is zero and _key_ does not have the value
           **IPC_PRIVATE**), or to create a new set.
    
           A new set of _nsems_ semaphores is created if _key_ has the value
           **IPC_PRIVATE** or if no existing semaphore set is associated with _key_
           and **IPC_CREAT** is specified in _semflg_.
    
           If _semflg_ specifies both **IPC_CREAT** and **IPC_EXCL** and a semaphore
           set already exists for _key_ , then **semget**() fails with _errno_ set to
           **EEXIST**.  (This is analogous to the effect of the combination
           **O_CREAT | O_EXCL** for open(2).)
    
           Upon creation, the least significant 9 bits of the argument _semflg_
           define the permissions (for owner, group, and others) for the
           semaphore set.  These bits have the same format, and the same
           meaning, as the _mode_ argument of open(2) (though the execute
           permissions are not meaningful for semaphores, and write
           permissions mean permission to alter semaphore values).
    
           When creating a new semaphore set, **semget**() initializes the set's
           associated data structure, _semid_ds_ (see semctl(2)), as follows:
    
           •  _sem_perm.cuid_ and _sem_perm.uid_ are set to the effective user ID
              of the calling process.
    
           •  _sem_perm.cgid_ and _sem_perm.gid_ are set to the effective group
              ID of the calling process.
    
           •  The least significant 9 bits of _sem_perm.mode_ are set to the
              least significant 9 bits of _semflg_.
    
           •  _sem_nsems_ is set to the value of _nsems_.
    
           •  _sem_otime_ is set to 0.
    
           •  _sem_ctime_ is set to the current time.
    
           The argument _nsems_ can be 0 (a don't care) when a semaphore set is
           not being created.  Otherwise, _nsems_ must be greater than 0 and
           less than or equal to the maximum number of semaphores per
           semaphore set (**SEMMSL**).
    
           If the semaphore set already exists, the permissions are verified.
    


## RETURN VALUE



           On success, **semget**() returns the semaphore set identifier (a
           nonnegative integer).  On failure, -1 is returned, and _errno_ is
           set to indicate the error.
    


## ERRORS



           **EACCES** A semaphore set exists for _key_ , but the calling process
                  does not have permission to access the set, and does not
                  have the **CAP_IPC_OWNER** capability in the user namespace
                  that governs its IPC namespace.
    
           **EEXIST IPC_CREAT** and **IPC_EXCL** were specified in _semflg_ , but a
                  semaphore set already exists for _key_.
    
           **EINVAL** _nsems_ is less than 0 or greater than the limit on the
                  number of semaphores per semaphore set (**SEMMSL**).
    
           **EINVAL** A semaphore set corresponding to _key_ already exists, but
                  _nsems_ is larger than the number of semaphores in that set.
    
           **ENOENT** No semaphore set exists for _key_ and _semflg_ did not specify
                  **IPC_CREAT**.
    
           **ENOMEM** A semaphore set has to be created but the system does not
                  have enough memory for the new data structure.
    
           **ENOSPC** A semaphore set has to be created but the system limit for
                  the maximum number of semaphore sets (**SEMMNI**), or the
                  system wide maximum number of semaphores (**SEMMNS**), would be
                  exceeded.
    


## STANDARDS



           POSIX.1-2008.
    


## NOTES



           **IPC_PRIVATE** isn't a flag field but a _key_t_ type.  If this special
           value is used for _key_ , the system call ignores all but the least
           significant 9 bits of _semflg_ and creates a new semaphore set (on
           success).
    
       **Semaphore initialization**
           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.
    
           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.
    
       **Semaphore limits**
           The following limits on semaphore set resources affect the
           **semget**() call:
    
           **SEMMNI** System-wide limit on the number of semaphore sets.  Before
                  Linux 3.19, the default value for this limit was 128.
                  Since Linux 3.19, the default value is 32,000.  On Linux,
                  this limit can be read and modified via the fourth field of
                  _/proc/sys/kernel/sem_.
    
           **SEMMSL** Maximum number of semaphores per semaphore ID.  Before
                  Linux 3.19, the default value for this limit was 250.
                  Since Linux 3.19, the default value is 32,000.  On Linux,
                  this limit can be read and modified via the first field of
                  _/proc/sys/kernel/sem_.
    
           **SEMMNS** System-wide limit on the number of semaphores: policy
                  dependent (on Linux, this limit can be read and modified
                  via the second field of _/proc/sys/kernel/sem_).  Note that
                  the number of semaphores system-wide is also limited by the
                  product of **SEMMSL** and **SEMMNI**.
    


## BUGS



           The name choice **IPC_PRIVATE** was perhaps unfortunate, **IPC_NEW** would
           more clearly show its function.
    


## EXAMPLES



           The program shown below uses **semget**() to create a new semaphore
           set or retrieve the ID of an existing set.  It generates the _key_
           for **semget**() using ftok(3).  The first two command-line arguments
           are used as the _pathname_ and _proj_id_ arguments for ftok(3).  The
           third command-line argument is an integer that specifies the _nsems_
           argument for **semget**().  Command-line options can be used to
           specify the **IPC_CREAT**(_-c_) and **IPC_EXCL**(_-x_) flags for the call to
           **semget**().  The usage of this program is demonstrated below.
    
           We first create two files that will be used to generate keys using
           ftok(3), create two semaphore sets using those files, and then
           list the sets using ipcs(1):
    
               $ **touch mykey mykey2** ;
               $ **./t_semget -c mykey p 1** ;
               ID = 9
               $ **./t_semget -c mykey2 p 2** ;
               ID = 10
               $ **ipcs -s** ;
    
               ------ Semaphore Arrays --------
               key        semid      owner      perms      nsems
               0x7004136d 9          mtk        600        1
               0x70041368 10         mtk        600        2
    
           Next, we demonstrate that when semctl(2) is given the same _key_ (as
           generated by the same arguments to ftok(3)), it returns the ID of
           the already existing semaphore set:
    
               $ **./t_semget -c mykey p 1** ;
               ID = 9
    
           Finally, we demonstrate the kind of collision that can occur when
           ftok(3) is given different _pathname_ arguments that have the same
           inode number:
    
               $ **ln mykey link** ;
               $ **ls -i1 link mykey** ;
               2233197 link
               2233197 mykey
               $ **./t_semget link p 1** ;       # Generates same key as 'mykey'
               ID = 9
    
       **Program source**
    
           /* t_semget.c
    
              Licensed under GNU General Public License v2 or later.
           */
           #include <stdio.h>
           #include <stdlib.h>
           #include <sys/ipc.h>
           #include <sys/sem.h>
           #include <unistd.h>
    
           static void
           usage(const char *pname)
           {
               fprintf(stderr, "Usage: %s [-cx] pathname proj-id num-sems\n",
                       pname);
               fprintf(stderr, "    -c           Use IPC_CREAT flag\n");
               fprintf(stderr, "    -x           Use IPC_EXCL flag\n");
               exit(EXIT_FAILURE);
           }
    
           int
           main(int argc, char *argv[])
           {
               int    semid, nsems, flags, opt;
               key_t  key;
    
               flags = 0;
               while ((opt = getopt(argc, argv, "cx")) != -1) {
                   switch (opt) {
                   case 'c': flags |= IPC_CREAT;   break;
                   case 'x': flags |= IPC_EXCL;    break;
                   default:  usage(argv[0]);
                   }
               }
    
               if (argc != optind + 3)
                   usage(argv[0]);
    
               key = ftok(argv[optind], argv[optind + 1][0]);
               if (key == -1) {
                   perror("ftok");
                   exit(EXIT_FAILURE);
               }
    
               nsems = atoi(argv[optind + 2]);
    
               semid = semget(key, nsems, flags | 0600);
               if (semid == -1) {
                   perror("semget");
                   exit(EXIT_FAILURE);
               }
    
               printf("ID = %d\n", semid);
    
               exit(EXIT_SUCCESS);
           }
    


* * *