| .\" Copyright 1993 Giorgio Ciucci (giorgio@crcc.it) |
| .\" and Copyright (C) 2020 Michael Kerrisk <mtk.manpages@gmail.com> |
| .\" |
| .\" %%%LICENSE_START(VERBATIM) |
| .\" Permission is granted to make and distribute verbatim copies of this |
| .\" manual provided the copyright notice and this permission notice are |
| .\" preserved on all copies. |
| .\" |
| .\" Permission is granted to copy and distribute modified versions of this |
| .\" manual under the conditions for verbatim copying, provided that the |
| .\" entire resulting derived work is distributed under the terms of a |
| .\" permission notice identical to this one. |
| .\" |
| .\" Since the Linux kernel and libraries are constantly changing, this |
| .\" manual page may be incorrect or out-of-date. The author(s) assume no |
| .\" responsibility for errors or omissions, or for damages resulting from |
| .\" the use of the information contained herein. The author(s) may not |
| .\" have taken the same level of care in the production of this manual, |
| .\" which is licensed free of charge, as they might when working |
| .\" professionally. |
| .\" |
| .\" Formatted or processed versions of this manual, if unaccompanied by |
| .\" the source, must acknowledge the copyright and authors of this work. |
| .\" %%%LICENSE_END |
| .\" |
| .\" Modified Tue Oct 22 17:54:56 1996 by Eric S. Raymond <esr@thyrsus.com> |
| .\" Modified 1 Jan 2002, Martin Schulze <joey@infodrom.org> |
| .\" Modified 4 Jan 2002, Michael Kerrisk <mtk.manpages@gmail.com> |
| .\" Modified, 27 May 2004, Michael Kerrisk <mtk.manpages@gmail.com> |
| .\" Added notes on capability requirements |
| .\" Modified, 11 Nov 2004, Michael Kerrisk <mtk.manpages@gmail.com> |
| .\" Language and formatting clean-ups |
| .\" Added notes on /proc files |
| .\" Rewrote BUGS note about semget()'s failure to initialize |
| .\" semaphore values |
| .\" |
| .TH SEMGET 2 2020-04-11 "Linux" "Linux Programmer's Manual" |
| .SH NAME |
| semget \- get a System V semaphore set identifier |
| .SH SYNOPSIS |
| .nf |
| .B #include <sys/types.h> |
| .B #include <sys/ipc.h> |
| .B #include <sys/sem.h> |
| .fi |
| .PP |
| .BI "int semget(key_t " key , |
| .BI "int " nsems , |
| .BI "int " semflg ); |
| .SH DESCRIPTION |
| The |
| .BR semget () |
| system call returns the System\ V semaphore set identifier |
| associated with the argument |
| .IR key . |
| It may be used either to obtain the identifier of a previously created |
| semaphore set (when |
| .I semflg |
| is zero and |
| .I key |
| does not have the value |
| .BR IPC_PRIVATE ), |
| or to create a new set. |
| .PP |
| A new set of |
| .I nsems |
| semaphores is created if |
| .I key |
| has the value |
| .B IPC_PRIVATE |
| or if no existing semaphore set is associated with |
| .I key |
| and |
| .B IPC_CREAT |
| is specified in |
| .IR semflg . |
| .PP |
| If |
| .I semflg |
| specifies both |
| .B IPC_CREAT |
| and |
| .B IPC_EXCL |
| and a semaphore set already exists for |
| .IR key , |
| then |
| .BR semget () |
| fails with |
| .I errno |
| set to |
| .BR EEXIST . |
| (This is analogous to the effect of the combination |
| .B O_CREAT | O_EXCL |
| for |
| .BR open (2).) |
| .PP |
| Upon creation, the least significant 9 bits of the argument |
| .I 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 |
| .I mode |
| argument of |
| .BR open (2) |
| (though the execute permissions are |
| not meaningful for semaphores, and write permissions mean permission |
| to alter semaphore values). |
| .PP |
| When creating a new semaphore set, |
| .BR semget () |
| initializes the set's associated data structure, |
| .I semid_ds |
| (see |
| .BR semctl (2)), |
| as follows: |
| .IP \(bu 2 |
| .I sem_perm.cuid |
| and |
| .I sem_perm.uid |
| are set to the effective user ID of the calling process. |
| .IP \(bu |
| .I sem_perm.cgid |
| and |
| .I sem_perm.gid |
| are set to the effective group ID of the calling process. |
| .IP \(bu |
| The least significant 9 bits of |
| .I sem_perm.mode |
| are set to the least significant 9 bits of |
| .IR semflg . |
| .IP \(bu |
| .I sem_nsems |
| is set to the value of |
| .IR nsems . |
| .IP \(bu |
| .I sem_otime |
| is set to 0. |
| .IP \(bu |
| .I sem_ctime |
| is set to the current time. |
| .PP |
| The argument |
| .I nsems |
| can be 0 |
| (a don't care) |
| when a semaphore set is not being created. |
| Otherwise, |
| .I nsems |
| must be greater than 0 |
| and less than or equal to the maximum number of semaphores per semaphore set |
| .RB ( SEMMSL ). |
| .PP |
| If the semaphore set already exists, the permissions are |
| verified. |
| .\" and a check is made to see if it is marked for destruction. |
| .SH RETURN VALUE |
| If successful, the return value will be the semaphore set identifier |
| (a nonnegative integer), otherwise, \-1 |
| is returned, with |
| .I errno |
| indicating the error. |
| .SH ERRORS |
| On failure, |
| .I errno |
| will be set to one of the following: |
| .TP |
| .B EACCES |
| A semaphore set exists for |
| .IR key , |
| but the calling process does not have permission to access the set, |
| and does not have the |
| .B CAP_IPC_OWNER |
| capability in the user namespace that governs its IPC namespace. |
| .TP |
| .B EEXIST |
| .B IPC_CREAT |
| and |
| .BR IPC_EXCL |
| were specified in |
| .IR semflg , |
| but a semaphore set already exists for |
| .IR key . |
| .\" .TP |
| .\" .B EIDRM |
| .\" The semaphore set is marked to be deleted. |
| .TP |
| .B EINVAL |
| .I nsems |
| is less than 0 or greater than the limit on the number |
| of semaphores per semaphore set |
| .RB ( SEMMSL ). |
| .TP |
| .B EINVAL |
| A semaphore set corresponding to |
| .I key |
| already exists, but |
| .I nsems |
| is larger than the number of semaphores in that set. |
| .TP |
| .B ENOENT |
| No semaphore set exists for |
| .I key |
| and |
| .I semflg |
| did not specify |
| .BR IPC_CREAT . |
| .TP |
| .B ENOMEM |
| A semaphore set has to be created but the system does not have |
| enough memory for the new data structure. |
| .TP |
| .B ENOSPC |
| A semaphore set has to be created but the system limit for the maximum |
| number of semaphore sets |
| .RB ( SEMMNI ), |
| or the system wide maximum number of semaphores |
| .RB ( SEMMNS ), |
| would be exceeded. |
| .SH CONFORMING TO |
| SVr4, POSIX.1-2001. |
| .\" SVr4 documents additional error conditions EFBIG, E2BIG, EAGAIN, |
| .\" ERANGE, EFAULT. |
| .SH NOTES |
| The inclusion of |
| .I <sys/types.h> |
| and |
| .I <sys/ipc.h> |
| isn't required on Linux or by any version of POSIX. |
| However, |
| some old implementations required the inclusion of these header files, |
| and the SVID also documented their inclusion. |
| Applications intended to be portable to such old systems may need |
| to include these header files. |
| .\" Like Linux, the FreeBSD man pages still document |
| .\" the inclusion of these header files. |
| .PP |
| .B IPC_PRIVATE |
| isn't a flag field but a |
| .I key_t |
| type. |
| If this special value is used for |
| .IR key , |
| the system call ignores all but the least significant 9 bits of |
| .I semflg |
| and creates a new semaphore set (on success). |
| .\" |
| .SS 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. |
| .\" In truth, every one of the many implementations that I've tested sets |
| .\" the values to zero, but I suppose there is/was some obscure |
| .\" implementation out there that does not. |
| .PP |
| Initialization can be done using |
| .BR semctl (2) |
| .B SETVAL |
| or |
| .B SETALL |
| operation. |
| Where multiple peers do not know who will be the first to |
| initialize the set, checking for a nonzero |
| .I sem_otime |
| in the associated data structure retrieved by a |
| .BR semctl (2) |
| .B IPC_STAT |
| operation can be used to avoid races. |
| .\" |
| .SS Semaphore limits |
| The following limits on semaphore set resources affect the |
| .BR semget () |
| call: |
| .TP |
| .B SEMMNI |
| System-wide limit on the number of semaphore sets. |
| On Linux systems before version 3.19, |
| the default value for this limit was 128. |
| Since Linux 3.19, |
| .\" commit e843e7d2c88b7db107a86bd2c7145dc715c058f4 |
| the default value is 32,000. |
| On Linux, this limit can be read and modified via the fourth field of |
| .IR /proc/sys/kernel/sem . |
| .\" This /proc file is not available in Linux 2.2 and earlier -- MTK |
| .TP |
| .B SEMMSL |
| Maximum number of semaphores per semaphore ID. |
| On Linux systems before version 3.19, |
| the default value for this limit was 250. |
| Since Linux 3.19, |
| .\" commit e843e7d2c88b7db107a86bd2c7145dc715c058f4 |
| the default value is 32,000. |
| On Linux, this limit can be read and modified via the first field of |
| .IR /proc/sys/kernel/sem . |
| .TP |
| .B 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 |
| .IR /proc/sys/kernel/sem ). |
| Note that the number of semaphores system-wide |
| is also limited by the product of |
| .B SEMMSL |
| and |
| .BR SEMMNI . |
| .SH BUGS |
| The name choice |
| .B IPC_PRIVATE |
| was perhaps unfortunate, |
| .B IPC_NEW |
| would more clearly show its function. |
| .SH EXAMPLE |
| The program shown below uses |
| .BR semget () |
| to create a new semaphore set or retrieve the ID of an existing set. |
| It generates the |
| .I key |
| for |
| .BR semget () |
| using |
| .BR ftok (3). |
| The first two command-line arguments are used as the |
| .I pathname |
| and |
| .I proj_id |
| arguments for |
| .BR ftok (3). |
| The third command-line argument is an integer that specifies the |
| .I nsems |
| argument for |
| .BR semget (). |
| Command-line options can be used to specify the |
| .BR IPC_CREAT |
| .RI ( \-c ) |
| and |
| .BR IPC_EXCL |
| .RI ( \-x ) |
| flags for the call to |
| .BR semget (). |
| The usage of this program is demonstrated below. |
| .PP |
| We first create two files that will be used to generate keys using |
| .BR ftok (3), |
| create two semaphore sets using those files, and then list the sets using |
| .BR ipcs (1): |
| .PP |
| .in +4n |
| .EX |
| $ \fBtouch mykey mykey2\fP |
| $ \fB./t_semget \-c mykey p 1\fP |
| ID = 9 |
| $ \fB./t_semget \-c mykey2 p 2\fP |
| ID = 10 |
| $ \fBipcs \-s\fP |
| |
| \-\-\-\-\-\- Semaphore Arrays \-\-\-\-\-\-\-\- |
| key semid owner perms nsems |
| 0x7004136d 9 mtk 600 1 |
| 0x70041368 10 mtk 600 2 |
| .EE |
| .in |
| .PP |
| Next, we demonstrate that when |
| .BR semctl () |
| is given the same |
| .I key |
| (as generated by the same arguments to |
| .BR ftok (3)), |
| it returns the ID of the already existing semaphore set: |
| .PP |
| .in +4n |
| .EX |
| $ \fB./t_semget \-c mykey p 1\fP |
| ID = 9 |
| .EE |
| .in |
| .PP |
| Finally, we demonstrate the kind of collision that can occur when |
| .BR ftok (3) |
| is given different |
| .I pathname |
| arguments that have the same inode number: |
| .PP |
| .in +4n |
| .EX |
| $ \fBln mykey link\fP |
| $ \fBls \-i1 link mykey\fP |
| 2233197 link |
| 2233197 mykey |
| $ \fB./t_semget link p 1\fP # Generates same key as \(aqmykey\(aq |
| ID = 9 |
| .EE |
| .in |
| .PP |
| .SS Program source |
| \& |
| .nf |
| #include <sys/types.h> |
| #include <sys/ipc.h> |
| #include <sys/sem.h> |
| #include <sys/stat.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| |
| static void |
| usage(const char *pname) |
| { |
| fprintf(stderr, "Usage: %s [\-cx] pathname proj\-id num\-sems\en", |
| pname); |
| fprintf(stderr, " \-c Use IPC_CREAT flag\en"); |
| fprintf(stderr, " \-x Use IPC_EXCL flag\en"); |
| 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 \(aqc\(aq: flags |= IPC_CREAT; break; |
| case \(aqx\(aq: 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\en", semid); |
| |
| exit(EXIT_SUCCESS); |
| } |
| .fi |
| .SH SEE ALSO |
| .BR semctl (2), |
| .BR semop (2), |
| .BR ftok (3), |
| .BR capabilities (7), |
| .BR sem_overview (7), |
| .BR sysvipc (7) |