/*
* Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
* the packaging of this file.
*
* Alternatively, it may be distributed under the terms of the GNU General
* Public License, either version 2 or 3, which can be found in the file
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
* file.
*/
#include <signal.h>
#import "OFObject.h"
#import "OFNotification.h"
OF_ASSUME_NONNULL_BEGIN
/** @file */
@class OFArray OF_GENERIC(ObjectType);
@class OFDictionary OF_GENERIC(KeyType, ObjectType);
@class OFMutableArray OF_GENERIC(ObjectType);
@class OFMutableDictionary OF_GENERIC(KeyType, ObjectType);
@class OFSandbox;
@class OFString;
/**
* @brief A notification that will be sent when the application did finish
* launching.
*/
extern const OFNotificationName OFApplicationDidFinishLaunchingNotification;
/**
* @brief A notification that will be sent when the application will terminate.
*/
extern const OFNotificationName OFApplicationWillTerminateNotification;
/**
* @brief Specify the class to be used as the application delegate.
*
* An instance of this class will be created and act as the application
* delegate.
*
* For example, it can be used like this:
*
* @code
* // In MyAppDelegate.h:
* @interface MyAppDelegate: OFObject <OFApplicationDelegate>
* @end
*
* // In MyAppDelegate.m:
* OF_APPLICATION_DELEGATE(MyAppDelegate)
*
* @implementation MyAppDelegate
* - (void)applicationDidFinishLaunching: (OFNotification *)notification
* {
* [OFApplication terminate];
* }
* @end
* @endcode
*/
#define OF_APPLICATION_DELEGATE(class_) \
int \
main(int argc, char *argv[]) \
{ \
return OFApplicationMain(&argc, &argv, \
(class_ *)[[class_ alloc] init]); \
}
#ifdef OF_HAVE_PLEDGE
# define OF_HAVE_SANDBOX
#endif
/**
* @protocol OFApplicationDelegate OFApplication.h ObjFW/OFApplication.h
*
* @brief A protocol for delegates of OFApplication.
*
* @note Signals are not available on AmigaOS!
*/
@protocol OFApplicationDelegate <OFObject>
/**
* @brief A method which is called when the application was initialized and is
* running now.
*
* @param notification A notification with name
* OFApplicationDidFinishLaunchingNotification
*/
- (void)applicationDidFinishLaunching: (OFNotification *)notification;
@optional
/**
* @brief A method which is called when the application will terminate.
*
* @param notification A notification with name
* OFApplicationWillTerminateNotification
*/
- (void)applicationWillTerminate: (OFNotification *)notification;
/**
* @brief A method which is called when the application received a SIGINT.
*
* @warning You are not allowed to send any messages inside this method, as
* message dispatching is not signal-safe! You are only allowed to do
* signal-safe operations like setting a variable or calling a
* signal-safe function!
*/
- (void)applicationDidReceiveSIGINT;
#ifdef SIGHUP
/**
* @brief A method which is called when the application received a SIGHUP.
*
* This signal is not available on Windows.
*
* @warning You are not allowed to send any messages inside this method, as
* message dispatching is not signal-safe! You are only allowed to do
* signal-safe operations like setting a variable or calling a
* signal-safe function!
*/
- (void)applicationDidReceiveSIGHUP;
#endif
#ifdef SIGUSR1
/**
* @brief A method which is called when the application received a SIGUSR1.
*
* This signal is not available on Windows.
*
* @warning You are not allowed to send any messages inside this method, as
* message dispatching is not signal-safe! You are only allowed to do
* signal-safe operations like setting a variable or calling a
* signal-safe function!
*/
- (void)applicationDidReceiveSIGUSR1;
#endif
#ifdef SIGUSR2
/**
* @brief A method which is called when the application received a SIGUSR2.
*
* This signal is not available on Windows.
*
* @warning You are not allowed to send any messages inside this method, as
* message dispatching is not signal-safe! You are only allowed to do
* signal-safe operations like setting a variable or calling a
* signal-safe function!
*/
- (void)applicationDidReceiveSIGUSR2;
#endif
@end
/**
* @class OFApplication OFApplication.h ObjFW/OFApplication.h
*
* @brief A class which represents the application as an object.
*
* In order to create a new OFApplication, you should create a class conforming
* to the optional @ref OFApplicationDelegate protocol and put
* `OF_APPLICATION_DELEGATE(NameOfYourClass)` in the .m file of that class.
*
* When the application is about to be terminated,
* @ref OFApplicationDelegate#applicationWillTerminate: will be called on the
* delegate and an @ref OFApplicationWillTerminateNotification will be sent.
*/
OF_SUBCLASSING_RESTRICTED
@interface OFApplication: OFObject
{
OFString *_programName;
OFArray OF_GENERIC(OFString *) *_arguments;
OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_environment;
int *_argc;
char ***_argv;
id <OFApplicationDelegate> _Nullable _delegate;
void (*_Nullable _SIGINTHandler)(id, SEL);
#ifndef OF_WINDOWS
void (*_Nullable _SIGHUPHandler)(id, SEL);
void (*_Nullable _SIGUSR1Handler)(id, SEL);
void (*_Nullable _SIGUSR2Handler)(id, SEL);
#endif
#ifdef OF_HAVE_SANDBOX
OFSandbox *_Nullable _activeSandbox;
OFSandbox *_Nullable _activeSandboxForChildProcesses;
#endif
}
#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nullable, nonatomic)
OFApplication *sharedApplication;
@property (class, readonly, nullable, nonatomic) OFString *programName;
@property (class, readonly, nullable, nonatomic)
OFArray OF_GENERIC(OFString *) *arguments;
@property (class, readonly, nullable, nonatomic)
OFDictionary OF_GENERIC(OFString *, OFString *) *environment;
#endif
/**
* @brief The name of the program (argv[0]).
*/
@property (readonly, nonatomic) OFString *programName;
/**
* @brief The arguments passed to the application.
*/
@property (readonly, nonatomic) OFArray OF_GENERIC(OFString *) *arguments;
/**
* @brief The environment of the application.
*/
@property (readonly, nonatomic)
OFDictionary OF_GENERIC(OFString *, OFString *) *environment;
/**
* @brief The delegate of the application.
*/
@property OF_NULLABLE_PROPERTY (assign, nonatomic)
id <OFApplicationDelegate> delegate;
#ifdef OF_HAVE_SANDBOX
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFSandbox *activeSandbox;
@property OF_NULLABLE_PROPERTY (readonly, nonatomic)
OFSandbox *activeSandboxForChildProcesses;
#endif
/**
* @brief Returns the only OFApplication instance in the application.
*
* @return The only OFApplication instance in the application
*/
+ (nullable OFApplication *)sharedApplication;
/**
* @brief Returns the name of the program (argv[0]).
*
* @return The name of the program (argv[0])
*/
+ (nullable OFString *)programName;
/**
* @brief Returns the arguments passed to the application.
*
* @return The arguments passed to the application
*/
+ (nullable OFArray OF_GENERIC(OFString *) *)arguments;
/**
* @brief Returns the environment of the application.
*
* @return The environment of the application
*/
+ (nullable OFDictionary OF_GENERIC(OFString *, OFString *) *)environment;
/**
* @brief Terminates the application with the EXIT_SUCCESS status.
*/
+ (void)terminate OF_NO_RETURN;
/**
* @brief Terminates the application with the specified status.
*
* @param status The status with which the application will terminate
*/
+ (void)terminateWithStatus: (int)status OF_NO_RETURN;
#ifdef OF_HAVE_SANDBOX
+ (void)of_activateSandbox: (OFSandbox *)sandbox;
+ (void)of_activateSandboxForChildProcesses: (OFSandbox *)sandbox;
#endif
- (instancetype)init OF_UNAVAILABLE;
/**
* @brief Gets argc and argv.
*
* @param argc A pointer where a pointer to argc should be stored
* @param argv A pointer where a pointer to argv should be stored
*/
- (void)getArgumentCount: (int *_Nonnull *_Nonnull)argc
andArgumentValues: (char *_Nullable *_Nonnull *_Nonnull[_Nonnull])argv;
/**
* @brief Terminates the application.
*/
- (void)terminate OF_NO_RETURN;
/**
* @brief Terminates the application with the specified status.
*
* @param status The status with which the application will terminate
*/
- (void)terminateWithStatus: (int)status OF_NO_RETURN;
#ifdef OF_HAVE_SANDBOX
- (void)of_activateSandbox: (OFSandbox *)sandbox;
- (void)of_activateSandboxForChildProcesses: (OFSandbox *)sandbox;
#endif
@end
#ifdef __cplusplus
extern "C" {
#endif
extern int OFApplicationMain(int *_Nonnull, char *_Nullable *_Nonnull[_Nonnull],
id <OFApplicationDelegate>);
#ifdef __cplusplus
}
#endif
OF_ASSUME_NONNULL_END