chdir(getenv("HOME") returns Bad address - c

char *home = getenv("HOME");
if (!strcmp(t->argv[0], "cd")) {
if (!t->argv[1]) {
chdir(home);
}
if (chdir(t->argv[1])) {
perror(t->argv[1]);
}
}
what this is supposed to do is run the cd command with the provided argument, and if there is no argument provided then return to the home directory. if i call cd without an argument, chdir prints "Bad address". i dont know why, considering i printed the value that getenv("HOME") returns and entered that path manually in my shell and it worked fine. why does it work when i provide the value but not when getenv provides it?
I also cant manually code a path for home either because it has to run on other machines. i need it to work with getenv("HOME").

i was being an idiot, as #dimich pointed out. the first chdir worked fine, but the second if statement should be an else if.
new code:
char *home = getenv("HOME");
if (!strcmp(t->argv[0], "cd")) {
if (!t->argv[1]) {
chdir(home);
} else if (chdir(t->argv[1])) {
perror(t->argv[1]);
}
}

Related

gtk filechooser with msys2 return not correct values

in my project i compiled a gtk-gui with msys2. I think everything works fine except for one thing.
If i start my application and try to choose a file with the filechooser i recognized that in the first attempt the return value of the
gtk_file_chooser_get_current_folder() is NULL. In the second try the return value seems to be correct but the last folder is missing.
Compiling and running it under linux leads to no problem. I use glade in combination with gtk.
I'm not sure what kind of code snipped i should post here, but if you want to see a specific thing i will upload it of course.
I would be very pleased about some suggestions.
At first i initialize the FileChooserWidget:
WCO_GUI_Ref()->MyFileChosserButton1 = GTK_WIDGET(gtk_builder_get_object(WCO_GUI_Ref()->MyBuilder, "MyFileChosserButton1"));
If you choose a folder with the FileChooser a function is called which stores the return value and print it out:
WCO_PDF_SetFoldername(WCO_ENTRY(WCO_GUI_Get(folder_name)));
The WCO_GUI_Get() function returns a void pointer which is casted by the WCO_ENTRY() macro. In this function the i call gtk_file_chooser_get_current_folder() like this:
void *WCO_GUI_Get(int id)
{
void *ret;
switch(id)
{
case 0: ret = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(WCO_GUI_Ref()->MyFileChosserButton1)); break;
default: break;
}
return ret;
}
If i place this debug code:
printf("%s", WCO_ENTRY(WCO_GUI_Get(folder_name)) );
The Output of it in the first try is (null) and after the first one i got a output like this C:\usr\documents\ but the actual selected folder is C:\usr\documents\test\

`execvp()` seems to not be completing the path search

TL;DR -- what sorts of things might cause an execvp call to not fully function/ search the path properly?
I'm on the tail end of building a rudimentary shell with some quality of life features that I've added over time e.g. history, alias's, and completions. I built those features on top of a functional shell that had a working $PATH search for execution e.g. typing in "ls -la" produced the desired behavior. As you might imagine, I accomplished this just using execvp. (This is written in C if it's not already clear)
I have not changed any of my tokenizing logic and have ensured that the file name is correct; in particular, execvp was producing the desired behavior before I had added these features to my REPL. echo "hello" still produces a tokenized char **xyz and the first token is indeed echo, null-terminated, and so on. That is, my call still looks like, with variables filled-in, ... execvp("echo", argv); after which I call perror, which should only trigger when something has gone awry. Each time I just run the above command, though, since I've added in these features, it returns a failure with the no such file or directory --- before I added these features in though, the behavior was as desired. I'll note, though, that running /bin/echo "hello" runs as expected. Examples are WLOG.
I'm not sure where I should even start looking for errors, and my Google-fu has been mostly fruitless: any suggestions?
I'm initially going to omit code because it totals to several hundred lines and a MWE would not be particularly minimal in addition to my desires to keep this general rather than very particular to my code, though I'm not sure what's causing this. My repository is public and up-to-date, and I'm happy to post any code here.
EDIT:
I knew I wasn't explicitly editing the PATH variable, etc., but this block of code was the problem:
// Grab $PATH from env
char *pathvar = getenv("PATH");
if (pathvar) {
char *path;
int i;
// tokenize on colon to get paths
// then use that immediately to
// scandir, and add everything in
// there to the completions system
path = strtok(pathvar, ":");
while (path) {
struct dirent **fListTemp;
int num_files = scandir(path, &fListTemp, NULL, alphasort);
// only adding the names that are completely composed of
// lower case letters; completions are done using a naive
// Trie Node structure that only supports lowercase letters
// for now... e.g. g++ does not work, and the '+' leads to
// a seg-fault. Same holds for . and ..
for (i = 0; i < num_files; i++) {
char *curr = fListTemp[i]->d_name;
if (strcmp(curr, ".")==0 || strcmp(curr, "..")==0){
continue;
} else if (notalpha(curr)) {
continue;
} else {
str_tolower(curr);
tn_insert(completions, curr);
}
}
for (i = 0; i < num_files; i++) {
free(fListTemp[i]);
}
free (fListTemp);
path = strtok(NULL, ":");
}
} else {
fprintf(stderr, "{wsh # init} -- $PATH variable could not be found?");
}
Note that
The getenv() function returns a pointer to the value in the
environment, or NULL if there is no match.
so my original code was indeed tampering with the PATH variable. The solution I came up with quickly was just to create a copy of that string and use that to parse through the PATH instead:
// Grab $PATH from env
char *pathvar = getenv("PATH");
char *pathvar_cpy = strcpy(pathvar_cpy, pathvar);
if (pathvar_cpy) {
char *path;
int i;
path = strtok(pathvar_cpy, ":");
while (path) {
// Scan directory
struct dirent **fListTemp;
int num_files = scandir(path, &fListTemp, NULL, alphasort);
for (i = 0; i < num_files; i++) {
char *curr = fListTemp[i]->d_name;
if (strcmp(curr, ".")==0 || strcmp(curr, "..")==0){
continue;
} else if (notalpha(curr)) {
continue;
} else {
str_tolower(curr);
tn_insert(completions, curr);
}
}
for (i = 0; i < num_files; i++) {
free(fListTemp[i]);
}
free (fListTemp);
path = strtok(NULL, ":");
}
} else {
fprintf(stderr, "{wsh # init} -- $PATH variable could not be found?");
}

Having trouble making a simple settings file

Some backstory
I'm an engineering student (first year) and we had to create a program that could manage a list of students. Basically putting information of students in an array of structs (student name, birth date, grades). It had to be possible to add students, delete students, sort students, change information, add grades, save progress, load progress and generate a mark list(html/css).
My problem
I wanted to add settings to my project. I put some information in a file I called settings.txt. The first and second line are integers and can be 1 or 0. The third line is a string. Creating this file and reading from the file works fine, but of course I wanted the user to be able to change his settings too. However, when I run the code below, my .exe crashes. It's probably because of something stupid I'm doing but I've been looking at this for a couple of hours now and my 'fixes' make things worse. I hope someone can help me, thanks in advance! :)
I tried adding some comments in english, originally the outputs in printf were dutch. If anything is unclear, please ask!
Code
char getBool (char option[], char booly[]) {
if (option[0]!='0') {
strcpy(booly,"true");
} else {
strcpy(booly,"false");
}
}
char editSettings (char settings[], char startLoad[]) {
//This function will allow the user to edit some settings
//Declare variables: file: filename, lijn: storage for xth line of file,booly: true/false output. Settings:reset: 1/0,load: 1/0,startfile: filename
char file[15]="settings.txt",lijn[25],booly[10],reset,load,startfile[25];
int inp,i;
do {
i=1;
//Read file and output current settings to user
FILE * bestand;
bestand=fopen(file,"rt");
fgets(lijn,999,bestand);
while (!feof(bestand)) {
//i determines what line we're on -> There are always 3 lines
//1st line can be 0 or 1 -> Reset screen after cmd?
//2nd line can be 0 or 1 -> Load file
//3th line is a string (filename) -> .txt is automatically added when loading file
getBool(lijn,booly);
if (i==1) {
printf("%d - Reset screen after every command: %s\n",i,booly);
reset=lijn;
} else if (i==2) {
printf("%d - Load file on startup: %s\n",i,booly);
load=lijn;
} else if (i==3) {
strcpy(startfile,lijn);
}
fgets(lijn,999,bestand);
i++;
}
fclose(bestand);
printf("Pick a setting to change or enter 0 to cancel.\nChoose: ");
//Let user choose a value: 0, 1 or 2. Anything else won't
inp=inlezen("012");
printf("\n");
//Process users choice
if (inp=='1') {
//Toggle reset option, remain other options
bestand=fopen(file,"wt");
if (reset=='0') {
reset='1';
} else if(reset=='1') {
reset='0';
}
fprintf(bestand,"%s\n",reset);
fprintf(bestand,"%s\n",load);
fprintf(bestand,"%s\n",startfile);
fclose(bestand);
} else if (inp=='2') {
//Toggle load on startup option + read filename to start, remain reset option
bestand=fopen(file,"wt");
if (load=='0') {
load='1';
} else if(load=='1') {
load='0';
}
fprintf(bestand,"%c\n",reset);
fprintf(bestand,"%c\n",load);
if (load=='1') {
printf("\nWhich file must be loaded on startup?\nGive name: ");
scanf("%s",&startfile);
}
fprintf(bestand,"%s\n",startfile);
fclose(bestand);
}
} while (inp!='0');
printf("\n");
}
However, when I run the code below, my .exe crashes.
You define char …reset,load, and then you pass those characters to fprintf() with the wrong conversion specifier s:
fprintf(bestand,"%s\n",reset);
fprintf(bestand,"%s\n",load);
If your compiler didn't warn about inconsistent usage of those variables, you should use a better compiler; if it did, you should pay attention to the warnings.

My cd function does not go to the home directory

I am building a custom shell in c, and one of the requirements is that the folder from while you run the program must be the "home" folder.
That is, if you type in just cd or cd ~ you should get to that directory. I have implemented it, but it is not working.
char *basedir;
void init_prompt()
{
getcwd(cwd,100);
basedir = cwd;
}
void cd_me(char **argv)
{
chdir(argv[1]);
if(getcwd(cwd,100)!=0)
{
;
}
if(strcmp("~\0",argv[1])==0||strcmp("\0",argv[1])==0)
chdir(basedir);
}
Any suggestions on how to fix this?
Also when I print basedir I am getting the correct output.
char *basedir;
basedir = cwd;
You make basedir a synonym to cwd. Whenever cwd changes, basedir follows. It's a pointer, it cannot remember its own string, it can only point to someone else's string.
You must make a copy instead.
char basedir[100];
strcpy(basedir,cwd);
Add bounds checks and error handling as needed.

calling a script from Binary in chroot mode,not working

Part of a program named =program.c
int memoryPercent()
{
int memoryPercent=0;
FILE *pipe1 = NULL;
pipe1=popen("/home/jatin/scripts/memoryPercent.sh","r");
if(!pipe1)
{
snmp_log(LOG_ERR,"popen failed in temp(),errno:%d\n",errno);
return -1;
}
if( fscanf(pipe1,"%d",&memoryPercent) != 1)
{
snmp_log(LOG_ERR,"fscanf failed in temp fun(),errno:\n");
return -2;
}
pclose(pipe1);
return memoryPercent;
}
above is my calling code /home/jatin/scripts/memoryPercent.sh
on this location a scripts is given and it is returning a INTEGER value.
in UBUNTU 12.04 when I compile and execute this code it is running perfectly.
but in my VM-WARE
I have copied all the necessary dependencies at the location /var/snmp3 and executing this binary with CHROOT the syntax is
/usr/sbin/chroot /var/snmp3/ /usr/local/bin/program
it is showing value "-1" only !!
Can anyone tell me what I am missing ?
the script is at the same location in /var/snmp3/home/jatin/scripts/memoryPercent.sh
as well as /home/jatin/scripts/memoryPercent.sh in 775 mode....
Try running the script manually from a chrooted shell.
I think you are missing the shell used by memoryPercent.sh. Have you copied the shell to the chrooted environment?

Resources