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.