diff --git a/ChangeLog b/ChangeLog index ec2c01073..7e83f69f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-08-22 Adam Fedor + + * Tools/gsnd/gsnd.m (main): Close any open file descriptors so + we can be a proper daemon. + 2003-08-22 Gregory John Casamento * Source/GSNibTemplates.[hm]: Added new template classes to a new file diff --git a/Tools/gsnd/gsnd.m b/Tools/gsnd/gsnd.m index bae934225..919cf68ab 100644 --- a/Tools/gsnd/gsnd.m +++ b/Tools/gsnd/gsnd.m @@ -24,11 +24,16 @@ #include "portaudio/pa_common/portaudio.h" #include #include +#include #ifdef __MINGW__ #include "process.h" #endif +#ifdef HAVE_SYSLOG_H +#include +#endif + #define GSNDNAME @"GNUstepGSSoundServer" #define FRAME_SIZE 4 #define BUFFER_SIZE_IN_FRAMES (1024 * FRAME_SIZE) @@ -60,6 +65,8 @@ #define CLAMP(x, low, high) \ (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) +static int is_daemon = 0; /* Currently running as daemon. */ + short **_X; short **_Y; unsigned int _Time; @@ -77,6 +84,66 @@ int resamplerReadData(int inCount, short inArray[], short *outPtr[], int dataArraySize, int Xoff, BOOL init_count); int resampleError(char *s); +static char ebuf[2048]; + + +#ifdef HAVE_SYSLOG + +static int log_priority; + +static void +gsnd_log (int prio) +{ + if (is_daemon) + { + syslog (log_priority | prio, ebuf); + } + else if (prio == LOG_INFO) + { + write (1, ebuf, strlen (ebuf)); + write (1, "\n", 1); + } + else + { + write (2, ebuf, strlen (ebuf)); + write (2, "\n", 1); + } + + if (prio == LOG_CRIT) + { + if (is_daemon) + { + syslog (LOG_CRIT, "exiting."); + } + else + { + fprintf (stderr, "exiting.\n"); + fflush (stderr); + } + exit(EXIT_FAILURE); + } +} +#else + +#define LOG_CRIT 2 +#define LOG_DEBUG 0 +#define LOG_ERR 1 +#define LOG_INFO 0 +#define LOG_WARNING 0 +void +gsnd_log (int prio) +{ + write (2, ebuf, strlen (ebuf)); + write (2, "\n", 1); + if (prio == LOG_CRIT) + { + fprintf (stderr, "exiting.\n"); + fflush (stderr); + exit(EXIT_FAILURE); + } +} +#endif + @protocol GSSndObj - (void)setIdentifier:(NSString *)identifier; @@ -969,6 +1036,7 @@ static int paCallback(void *inputBuffer, int main(int argc, char** argv, char **env) { + int c; CREATE_AUTORELEASE_POOL(pool); #ifdef GS_PASS_ARGUMENTS @@ -1007,6 +1075,34 @@ int main(int argc, char** argv, char **env) } #endif + /* + * Ensure we don't have any open file descriptors which may refer + * to sockets bound to ports we may try to use. + * + * Use '/dev/null' for stdin and stdout. Assume stderr is ok. + */ + for (c = 0; c < FD_SETSIZE; c++) + { + if (is_daemon || (c != 2)) + { + (void)close(c); + } + } + if (open("/dev/null", O_RDONLY) != 0) + { + sprintf(ebuf, "failed to open stdin from /dev/null (%s)\n", + strerror(errno)); + gsnd_log(LOG_CRIT); + exit(EXIT_FAILURE); + } + if (open("/dev/null", O_WRONLY) != 1) + { + sprintf(ebuf, "failed to open stdout from /dev/null (%s)\n", + strerror(errno)); + gsnd_log(LOG_CRIT); + exit(EXIT_FAILURE); + } + gsnd = [[SoundServer alloc] init]; if (gsnd == nil) {