---
name: "notify"
section: "3"
platform: "macos"
package: "Libnotify"
version: "348.120.4"
release: "macOS 26.5"
platforms: ["macos"]
url: "https://new.carta.tech/notify/3"
---

# notify(3)

event distribution functions

## NAME

**notify\_post**, **notify\_register\_check**, **notify\_register\_dispatch**, **notify\_register\_signal**, **notify\_register\_mach\_port**, **notify\_register\_file\_descriptor**, **notify\_check**, **notify\_get\_state**, **notify\_set\_state**, **notify\_suspend**, **notify\_resume**, **notify\_cancel**, **notify\_is\_valid\_token** – event distribution functions

## SYNOPSIS

**#include \<notify.h\>**

*uint32\_t*\

**notify\_post**(*const char \*name*);

*uint32\_t*\

**notify\_register\_check**(*const char \*name, int \*out\_token*);

*typedef* *void*\

**(^notify\_handler\_t)**(*int token*);

*uint32\_t*\

**notify\_register\_dispatch**(*const char \*name, int \*out\_token*, *dispatch\_queue\_t queue*, *notify\_handler\_t handler*);

*uint32\_t*\

**notify\_register\_signal**(*const char \*name, int sig, int \*out\_token*);

*uint32\_t*\

**notify\_register\_mach\_port**(*const char \*name, mach\_port\_t \*notify\_port, int flags, int \*out\_token*);

*uint32\_t*\

**notify\_register\_file\_descriptor**(*const char \*name, int \*notify\_fd, int flags, int \*out\_token*);

*uint32\_t*\

**notify\_check**(*int token, int \*check*);

*uint32\_t*\

**notify\_set\_state**(*int token, uint64\_t state*);

*uint32\_t*\

**notify\_get\_state**(*int token, uint64\_t \*state*);

*uint32\_t*\

**notify\_suspend**(*int token*);

*uint32\_t*\

**notify\_resume**(*int token*);

*uint32\_t*\

**notify\_cancel**(*int token*);

*bool*\

**notify\_is\_valid\_token**(*int val*);

## DESCRIPTION

These routines allow processes to exchange stateless notification events. Processes post notifications to a single system-wide notification server, which then distributes notifications to client processes that have registered to receive those notifications, including processes run by other users.

Notifications are associated with names in a namespace shared by all  clients of the system. Clients may post notifications for names, and may monitor names for posted notifications. Clients may request notification delivery by a number of different methods.

Clients desiring to monitor names in the notification system must register with the system, providing a name and other information required for the desired notification delivery method. Clients are given an integer token representing the registration. Token values are zero or positive integers.

The kernel provides limited queues for mach message and file descriptor messages. It is important to make sure that clients read mach ports and file descriptors frequently to prevent messages from being lost due to resource limitations. Clients that use signal-based notification should be aware that signals are not delivered to a process while it is running in a signal handler. This may affect the delivery of signals in close succession.

Notifications may be coalesced in some cases. Multiple events posted for a name in rapid succession may result in a single notification sent to clients registered for notification for that name. Clients checking for changes using the notify\_check() routine cannot determine if more than one event has been posted since a previous call to  notify\_check() for that name.

"False positives" may occur in notify\_check() when used with a token generated by notify\_register\_check() due to implementation constraints. This behavior may vary in future releases.

### notify\_post

This routine causes the system to send a notification for the given  name to all clients that have registered for notifications of this name. This is the only API required for an application that only produces notifications.

### notify\_register\_check

Registers for passive notification for the given name. The routine generates a token that may be used with the **notify\_check**() routine to check if any notifications have been posted for the name. The check is implemented using a shared memory scheme, making the check  very fast and efficient. The implementation has a limited amount of shared memory, so developers are encouraged to use this mechanism sparingly. It is also important to release the resources consumed by a registration with  **notify\_cancel**() when they are no longer required by the application.

### notify\_register\_dispatch

registers a callback handler in the form of a block which will be dispatched to the queue when a notification for the given name is received.  This is a convenient way to register callbacks without any management of file descriptors, mach ports, or signals on the part of the application.  The given queue is retained by the system for the lifetime of the notification.  Use **notify\_cancel**() to release the notification and its reference to the queue.

### notify\_register\_signal

registers a client for notification delivery via a signal. This fits well with the design of many UNIX daemons that use a signal such as SIGHUP to reinitialize of reset internal state information.

### notify\_register\_mach\_port

registers a client for notification delivery via mach messaging. Notifications are delivered by an empty message sent to a mach port. By default, a new port is created by a call to this routine. A mach port previously created by a call to this routine may be used for notifications if a pointer to that port is passed in to the routine and NOTIFY\_REUSE is set in the flags parameter. The notification service must be able to extract send rights to the port.

Values for the flags parameter may only be 0 (zero) or NOTIFY\_REUSE.

Note that the kernel limits the size of the message queue for any port. If it is important that notifications should not be lost due to queue overflow, clients should service messages quickly, and be cautious in using the same port for notifications for more than one name.

A notification message has an empty message body. The msgh\_id field in the mach message header will have the value of the notification token. If a port is reused for multiple notification registrations, the msgh\_id value may be used to determine which name generated the notification.

### notify\_register\_file\_descriptor

Register for notification by a write to a file descriptor.

By default, a new file descriptor is created and a pointer to it is returned as the value of the "notify\_fd" parameter. A file descriptor created by a previous call to this routine may be used for notifications if a pointer to that file descriptor is passed in to the routine and NOTIFY\_REUSE is set in the flags parameter.

Values for the flags parameter may only be 0 (zero) or NOTIFY\_REUSE.

Note that the kernel limits the buffer space for queued writes on a file descriptor. If it is important that notifications should not be lost due to queue overflow, clients should service messages quickly, and be cautious in using the same file descriptor for notifications for more than one name.

Notifications are delivered by an integer value written to the file descriptor. The value is sent in network byte order. When converted to host byte order, for example by using **ntohl**(), it will match the notification token for which the notification was generated.

### notify\_check

Checks if any notifications have been posted for a name. The output parameter "check" is set to 0 for false, 1 for true. A true indication is returned the first time notify\_check is called for a token. Subsequent calls give a true indication when notifications have been posted for the name associated with the notification token.

**notify\_check**() may be used with any notification token produced by any of the notification registration routines. A fast check based on a shared memory implementation is used when the token was generated by **notify\_register\_check**(). Other tokens are checked by a call to the notification server.

### notify\_set\_state

Set a 64-bit unsigned integer variable associated with a token.

Each registered notification key has an associated 64-bit integer variable, which may be set using this routine and examined using the **notify\_get\_state**() routine. The state variable is free to be used by clients of the notification API. It may be used to synchronize state information between cooperating processes or threads. (Available in Mac OS X 10.5 or later.)

### notify\_get\_state

Get the 64-bit unsigned integer value associated with a token. The default value of a state variable is zero. (Available in Mac OS X 10.5 or later.)

### notify\_suspend

Suspends delivery of notifications for a notification token. Any notifications corresponding to a token that are posted while it is suspended will be coalesced, and pended until notifications are resumed using **notify\_resume**().

Calls to **notify\_suspend**() may be nested. Notifications will resume only when a matching number of calls are made to **notify\_resume**().

### notify\_resume

Removes one level of suspension for a token previously suspended by a call to **notify\_suspend**(). When resumed, notifications will be delivered normally. A single notification will be generated if any notifications were pended while the token was suspended.

### notify\_cancel

Cancel notification and free resources associated with a notification token. Mach ports and file descriptor associated with a token are released (deallocated or closed) when all registration tokens associated with  the port or file descriptor have been cancelled.

### notify\_is\_valid\_token

Determines if an integer value is valid for a current registration. Negative integers are never valid. A positive or zero value is valid if the current process has a registration associated with the given value.

## RETURN VALUES

Many notify functions return status (uint32\_t) to indicate success or failure. This will always be one of the following:

### NOTIFY\_STATUS\_OK

The function did not encounter any issues.

### NOTIFY\_STATUS\_INVALID\_NAME

Name argument is not valid. Often this will indicate that the name passed to the function is NULL.

### NOTIFY\_STATUS\_INVALID\_TOKEN

The function expected a valid token, given by a notify\_register\_\* function, and was passed an invalid token. Token validity can by checked with **notify\_is\_valid\_token**().

### NOTIFY\_STATUS\_INVALID\_PORT

The function is not able to use the port passed. This may be because the port is NULL, MACH\_PORT\_NULL, MACH\_PORT\_DEAD, or the calling process does not have the correct rights to the port.

### NOTIFY\_STATUS\_INVALID\_FILE

The function was passed NULL, or something that is not a file descriptor generated by notify\_register\_file\_descriptor.

### NOTIFY\_STATUS\_INVALID\_SIGNAL

Legacy, currently unused.

### NOTIFY\_STATUS\_INVALID\_REQUEST

An internal error occurred.

### NOTIFY\_STATUS\_NOT\_AUTHORIZED

The calling process is not authorized to take this action. Usually this indicates that the calling process may not act on the name given.

### NOTIFY\_STATUS\_OPT\_DISABLE

An internal error occurred.

### NOTIFY\_STATUS\_SERVER\_NOT\_FOUND

The server could not be found. This usually indicates that sandboxing is preventing the calling process from accessing notifyd.

### NOTIFY\_STATUS\_NULL\_INPUT

One of the inputs was called with NULL when it must not be NULL. For legacy support, if name, token, port, or file descriptor is NULL, the respective NOTIFY\_STATUS\_INVALID\_\* return code will be used instead.

### NOTIFY\_STATUS\_FAILED

Indicates an internal failure of the library. The caller may try again; another attempt may be successful. Please report any instances where this is returned.

## NAMESPACE CONVENTIONS

Names in the namespace must be NULL-terminated. Names should be encoded as UTF-8 strings.

The namespace supported by the system is unstructured, but users of this API are highly encouraged to follow the reverse-ICANN domain name convention used for Java package names and for System Preferences on Mac OS X. For example, "com.mydomain.example.event".

Apple reserves the portion of the namespace prefixed by "com.apple.". This policy is not enforced in the current implementation, but may be in the future. It is enforced that the portion of the namespace prefixed by "com.apple.system." is reserved for root system process.

Names in the space "user.uid.UID", where UID is a numeric user ID number are reserved for processes with that UID. Names in this protected space may only be accessed or modified by processes with the effective UID specified as the UID in the name. The name "user.uid.UID" is protected for the given UID, as are any names of the form "user.uid.UID.\<sub-path\>".  In the latter case, the name must have a dot character following the UID.

Third party developers are encouraged to choose a prefix for names that will avoid conflicts in the shared namespace.

The portion of the namespace prefixed by the string "self." is set aside for private use by applications. That is, each client may use that part of the namespace for intra-process notifications. These notifications  are private to each individual process and are not propagated between processes.

## USAGE EXAMPLES

A notification producer.

    \#include \<notify.h\>\
     ...

    notify\_post("com.eg.random.event");

A client using notify\_check() to determine when to invalidate a cache.

    \#include \<stdio.h\>\
     \#include \<stdlib.h\>\
     \#include \<notify.h\>

    int\
     main(int argc, char \*argv\[\])\
     {\
         uint32\_t status;\
         int token, check;

        status = notify\_register\_check("com.eg.update", &token);\
         if (status != NOTIFY\_STATUS\_OK)\
         {\
            fprintf(stderr, "registration failed (%u)\\n", status);\
            exit(status);\
         }

        build\_my\_cache();

        ...

        status = notify\_check(token, &check);\
         if ((status == NOTIFY\_STATUS\_OK) && (check != 0))\
         {\
            /\* An update has occurred - invalidate the cache \*/\
            reset\_my\_cache();\
         }

        ...

A client using file descriptor notifications.

    \#include \<stdio.h\>\
     \#include \<stdlib.h\>\
     \#include \<string.h\>\
     \#include \<errno.h\>\
     \#include \<sys/types.h\>\
     \#include \<sys/time.h\>\
     \#include \<unistd.h\>\
     \#include \<notify.h\>

    int\
     main(int argc, char \*argv\[\])\
     {\
         uint32\_t status;\
         int nf, rtoken, qtoken, t, ret;\
         fd\_set readfds;

        status = notify\_register\_file\_descriptor("com.eg.random.event",\
            &nf, 0, &rtoken);\
         if (status != NOTIFY\_STATUS\_OK)\
         {\
            fprintf(stderr, "registration failed (%u)\\n", status);\
            exit(status);\
         }

        status = notify\_register\_file\_descriptor("com.eg.random.quit",\
             &nf, NOTIFY\_REUSE, &qtoken);\
         if (status != NOTIFY\_STATUS\_OK)\
         {\
            fprintf(stderr, "registration failed (%u)\\n", status);\
            exit(status);\
         }

        FD\_ZERO(&readfds);\
         FD\_SET(nf, &readfds);

        for (;;)\
         {\
            ret = select(nf+1, &readfds, NULL, NULL, NULL);\
            if (ret \<= 0) continue;\
            if (!FD\_ISSET(nf, &readfds)) continue;

           status = read(nf, &t, sizeof(int));\
            if (status \< 0)\
            {\
                perror("read");\
                break;\
            }

           t = ntohl(t);

           if (t == rtoken) printf("random event\\n");\
            else if (t == qtoken) break;\
         }

        printf("shutting down\\n");\
         notify\_cancel(rtoken);\
         notify\_cancel(qtoken);\
         exit(0);\
     }

A client using dispatch notifications.

    \#include \<stdio.h\>\
     \#include \<stdlib.h\>\
     \#include \<notify.h\>\
     \#include \<dispatch/dispatch.h\>

    int\
     main(void)\
     {\
         uint32\_t status;\
         int token;

        status = notify\_register\_dispatch("com.eg.random.event", &token,\
             dispatch\_get\_main\_queue(), ^(int t) { \
                 printf("com.eg.random.event received!\\n"); });

        dispatch\_main();\
         exit(0);\
     }

## HISTORY

These functions first appeared in Mac OS X 10.3.

## SEE ALSO

[ntohl(3)](/ntohl/3.md), [read(2)](/read/2.md), [select(2)](/select/2.md), [signal(3)](/signal/3.md)
