This is the mail archive of the
cygwin
mailing list for the Cygwin project.
[patch] invoking user's preferred shell from cygwin.bat
- From: Michael Wardle <michael at endbracket dot net>
- To: cygwin at cygwin dot com
- Date: Thu, 24 Mar 2005 14:46:38 +1100
- Subject: [patch] invoking user's preferred shell from cygwin.bat
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/