Hi
As you will know, the default Cygwin shortcuts invoke "cygwin.bat" which in turn runs "bash --login".
On most of my Unix accounts, I have tcsh set as my login shell, and have also started to find zsh quite useful, therefore I would prefer to be able to set my preferred shell in Cygwin as well. Most Unix systems do this with the pw_shell field of the password database, /etc/passwd.
I have attached a simple C source file which tries to use the user's shell if it's specified in the password database. You might compile this and make it available with a name such as /bin/shell and change cygwin.bat to invoke "shell" instead of "bash --login".
Design decisions: - falls back to the default shell rather than exiting if a user doesn't exist since Cygwin doesn't currently require a valid user account - uses the default shell if the shell field in /etc/passwd is blank as many other Unixes do - uses /bin/bash as the default shell since cygwin.bat uses that as the default
Features: - sets argv[0] to the shell's basename prefixed by a hyphen/minus character which makes most common shells switch to "login" mode
I hope you find it useful.
-- Michael Wardle
/* * shell - start user's preferred shell */
#include <sys/types.h> #include <errno.h> #include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define DEFAULT_SHELL "/bin/bash" #define PATH_SEPARATOR '/' int main(int argc, char **argv) { const struct passwd *passwd; const char *shell; char *basename; char *arg0; char **args; /* Get the current user's shell */ errno = 0; passwd = getpwuid(getuid()); if (!passwd) { fprintf(stderr, "Cannot get password entry: %s\n", strerror(errno)); shell = NULL; } else { shell = passwd->pw_shell; } /* Fall back to the default if the shell is unset or empty */ if (!shell||!*shell) { fprintf(stderr, "Using default shell %s\n", DEFAULT_SHELL); shell = DEFAULT_SHELL; } /* Set the SHELL environment variable for make, etc. */ setenv("SHELL", shell, 1); /* Set up the shell's argument vector - argv[0] */ errno = 0; arg0 = (char *)malloc(strlen(shell)*sizeof(char)+1); if (!arg0) { perror("Cannot allocate memory for shell argument 0\n"); exit(1); } basename = strrchr(shell, (int)PATH_SEPARATOR); if (basename) basename++; /* move past '/' */ if (basename) { /* Set arg0 to -basename to denote login shell */ strcpy(arg0, "-"); strcat(arg0, basename); } else { /* Leave arg0 as full path */ strcpy(arg0, shell); } /* Set up the shell's argument vector - argv */ errno = 0; args = (char **)malloc(2*sizeof(arg0)); /* {arg0, NULL} */ if (!args) { perror("Cannot allocate memory for shell arguments\n"); exit(1); } args[0] = arg0; args[1] = (char *)NULL; /* Start the shell */ errno = 0; if (execv(shell, args) == -1) { fprintf(stderr, "Cannot execute shell %s: %s\n", shell, strerror(errno)); exit(1); } exit(0); }
-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/