This is my_main.c in view mode; [Download] [Up]
/* $Id: my_main.c,v 1.0 92/07/31 17:39:45 cap Exp $ * This is the routine we jump to. * * The data for this module doesn't go into a zero-filled segment, * so you need to initialize everything. */ #include <stdlib.h> #include <fcntl.h> #include <sys/errno.h> #include <defaults.h> #include <objc/hashtable.h> extern char ***_libsys_environ; char **environ_from_command(); /* * This function gets called at the point where Workspace's main * should have been called. Thus, we do our business, then call * Workspace's main, and then return from here. * Right now I'm not using the arguments, but maybe we could * add some fancy command line processing. */ my_main(argc, argv, envp) int argc; char *argv[]; char *envp[]; { int (*workspace_main)() = (int (*)()) RETURN; const char *environ_preference; extern const char *sound_file; environ_preference = NXGetDefaultValue("Workspace", "CustomEnvironmentCommand"); sound_file = NXGetDefaultValue("Workspace", "CustomEmptyRecyclerSound"); if (environ_preference) { char **environ = environ_from_command(environ_preference); if (environ) *_libsys_environ = environ; /* very necessary! */ } if (sound_file) sound_file = NXUniqueString(sound_file); return (*workspace_main)(argc, argv, *_libsys_environ); } /* * environ_from_command - * Add things to the environment. The argument is a string * specifying a command to be executed by /bin/sh, through * the popen call. The command must print on stdout a list of * environment variables, complete with the = between the * variable name and the value. These commands are taken to be * the new environment of all programs that Workspace launches. * * If the command prints nothing, you will get an empty * environment. An example command that retains the current * environment would be "printenv". A more useful thing would * be to have something like "cat ~/Library/environment", * where the environment file would contain strings like * * PATH=blah * PAGER=less * * and so on. This doesn't allow you any shell substitutions, * which most people want. My final suggestion is to extract * the part of your .login file that establishes your * environment into a separate file, say, ~/.environment. * Your .login file would then source this file. The command * you'd specify for here would then be, for csh users, * * csh -c "source ~/.environment; printenv" * * It's important that whatever command you choose, it prints * only environment information. That's why you wouldn't want * to use "source ~/.login", because many people like to * print things in their .login files. * * The exit status of the command must be 0, or you don't * get the new environment, you retain the old. */ /* maximum length of a single environment variable string */ #define ENVIRON_STRING_SIZE 10240 char **environ_from_command(command) const char *command; { FILE *stream; const char **environ = NULL; int index; /* into environ */ int environ_size; int status; /* of command */ char environ_string[ENVIRON_STRING_SIZE]; /* one line of environment */ int console; /* * I don't actually use this console descriptor, but popen fails unless * we open some other file first. This is probably because * Workspace is started by loginwindow, which probably doesn't * supply open files on descriptors 0-2. I didn't check this though. */ console = open("/dev/console", O_WRONLY); if ((stream = popen(command, "r")) == NULL) fprintf(stderr, "CustomWorkspace[%d]: could not open pipe to environment command: %s\n", getpid(), sys_errlist[errno]); else { environ_size = 16; index = 0; environ = malloc(environ_size * sizeof *environ); while (fgets(environ_string, ENVIRON_STRING_SIZE, stream)) { environ_string[strlen(environ_string) - 1] = '\0'; environ[index++] = NXUniqueString(environ_string); if (index == environ_size) { environ_size *= 2; environ = realloc(environ, environ_size * sizeof *environ); } } environ[index] = NULL; if (status = pclose(stream)) { printf("CustomWorkspace[%d]: environment command exited with status %d\n", getpid(), status); free(environ); environ = NULL; } } close(console); return environ; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.