How to remove newline from between strings read from another text file - c

char IP[32] = "";
char PORT[4] = "0000";
int read_conf()
{
int i;
char line[25] = "";
FILE *fp;
char *str_ptr;
fp = fopen("client.conf","r");
for(i=1;(fgets(line,sizeof(line),fp));i++)
{
if(1==i)
{
str_ptr = strstr(line,"IP:");
if(str_ptr)
{
strcpy(IP,(str_ptr+3));
}
else
{
printf("Error in fetching IP \n");
exit(0);
}
}
else if(2==i)
{
str_ptr = strstr(line,"Port:");
if(str_ptr)
{
strcpy(PORT,(str_ptr+5));
}
else
{
printf("Error in fetching PORT \n");
exit(0);
}
}
}
return 1;
}
char *construct_url(int n,char * const argv[])
{
char * final_url;
int i,k=2;
int j = 0;
final_url = malloc(sizeof(char *)*300);
strcpy(final_url,"http://");
strcat(final_url,IP);
strcat(final_url,":");
strcat(final_url,PORT);
strcat(final_url,"/");
//printf("%s",final_url);
for(i=1;i<n,k>0;i++,k--)
{
strcat(final_url,argv[i]);
if(i==1)
{
strcat(final_url,"/");
}
else
{
strcat(final_url,"?");
}
}
return final_url;
}
In my above code it is adding a newline after IP and PORT value which is not correct URL construction. how do I avoid new line before concatenation.
client.conf consist
IP:10.12.130.216
Port:5200
Expected Result:
http://10.12.130.216:5200/
Getting Result:
http://10.12.130.216
:5200
/

read_conf can be written in simple as follows using fscanf.
char PORT[6] = "00000";//0-65535
int read_conf(void){
FILE *fp = fopen("client.conf","r");
if(1 != fscanf(fp, "IP:%31s\n", IP)){
printf("Error in fetching IP \n");
exit(0);
}
if(1 != fscanf(fp, "Port:%5s", PORT)){
printf("Error in fetching PORT \n");
exit(0);
}
fclose(fp);
return 1;
}

If you are sure that it is a new line, use:
strcat(final_url,IP);
strtok(final_url, "\n");
strcat(final_url,":");
strcat(final_url,PORT);
strtok(final_url, "\n");
strcat(final_url,"/");
or use strtock function separately for IP and PORT strings.

Related

Why gdb showed /stdlib/strtol_l.c: No such file or directory? Do I missing something to install?

I tried to compile with -g and then run gdb to find the line that caused the segmentation fault, but the error message confused me.
Program received signal SIGSEGV, Segmentation fault.
__GI_____strtol_l_internal (nptr=0x0, endptr=endptr#entry=0x0, base=base#entry=10, group=group#entry=0, loc=0x7ffff7fb04a0 <_nl_global_locale>)
at ../stdlib/strtol_l.c:292
292 ../stdlib/strtol_l.c: No such file or directory.
I tried reinstalling gdb to get it working again, but I failed. It still shows the same error message. I later found the problem myself and marked it in the code below. I'm just curious why something like this sometimes happens when I try to debug some string functions? Like strdup, strtok, strtol, etc.. Am I missing something to install? I hope I can solve this problem completely.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
char buff[255];
#define NUM_BUCKETS 32
typedef struct Customer {
char* email;
char* name;
int shoesize;
char* food;
struct Customer* next;
} Customer ;
unsigned long hash(char *str) {
unsigned long hash = 0;
int c;
while (*str != '\0') {
c = *str;
hash = ((hash << 5) + hash) + (unsigned char)c;
str++;
}
return hash;
}
Customer *add_friend_to_list(char *email, char *name, int shoesize, char *food, Customer *bucket) {
Customer* customer;
customer = malloc(sizeof(Customer));
customer->name = strdup(name);
customer->food = strdup(food);
customer->shoesize = shoesize;
customer->email = strdup(email);
customer->next = bucket;
return customer;
}
void add_consumer_to_hashtable(char *name, char *food, char *email, int shoesize, Customer **buckets, size_t num_buckets) {
size_t which_bucket = hash(name) % num_buckets;
buckets[which_bucket] = add_friend_to_list(email, name, shoesize, food, buckets[which_bucket]);
}
int main() {
Customer* buckets[NUM_BUCKETS] = {NULL};
int ittime = 0;
FILE *fp = NULL;
fp = fopen("customers.tsv", "r");
while (true) {
fgets(buff, 255, fp);
if (feof(fp)) {
break;
}
ittime++;
}
fclose(fp);
fp = NULL;
char *email = (char *)malloc(5 * sizeof(char));
char *name = (char *)malloc(5 * sizeof(char));
int shoesize;
char *food = (char *)malloc(5 * sizeof(char));
const char s[2] = "\t";
fp = fopen("customers.tsv", "r");
for (int i = 0; i < ittime + 1; i++) { //This line cause the Segmentation Fault
fgets(buff, 255, fp);
char *token;
token = strtok(buff, s);
email = token;
token = strtok(NULL, s);
name = token;
token = strtok(NULL, s);
shoesize = atoi(token);
token = strtok(NULL, s);
food = token;
add_consumer_to_hashtable(name, food, email, shoesize, buckets, NUM_BUCKETS);
}
fclose(fp);
while (true) {
char *cmd = (char *)malloc(5 * sizeof(char));
printf("command: ");
scanf("%s", cmd);
if (strcmp(cmd, "add") == 0) {
char *email1 = (char *)malloc(5 * sizeof(char));
char *name1 = (char *)malloc(5 * sizeof(char));
int shoesize1;
char *food1 = (char *)malloc(5 * sizeof(char));
printf("email address? ");
scanf("%s", email1);
printf("name? ");
scanf(" %[^\n]", name1);
printf("shoe size? ");
scanf("%d", &shoesize1);
printf("favorite food? ");
scanf("%s", food1);
add_consumer_to_hashtable(name1, food1, email1, shoesize1, buckets, NUM_BUCKETS);
free(name1);
free(food1);
free(email1);
} else if (strcmp(cmd, "lookup") == 0) {
char *Email = (char *)malloc(5 * sizeof(char));
printf("email address? ");
scanf("%s", Email);
bool exist = false;
for (int i = 0; i < 32; i++) {
Customer *cus = buckets[i];
if (buckets[i] == NULL) {
continue;
}
while ((cus != NULL)) {
if (cus->shoesize == EOF) {
break;
}
if (strcmp(cus->email, Email) == 0) {
printf("email: %s\n", cus->email);
printf("name: %s\n", cus->name);
printf("shoesize: %d\n", cus->shoesize);
printf("food: %s\n", cus->food);
exist = true;
break;
}
if (cus->next != NULL) {
cus = cus->next;
} else {
break;
}
}
}
if (exist == false) {
printf("user not found!\n");
}
} else if (strcmp(cmd, "delete") == 0) {
char *Email = (char *)malloc(5 * sizeof(char));
printf("email address? ");
scanf("%s", Email);
bool exist = false;
for (int i = 0; i < 32; i++) {
Customer *cus = buckets[i];
if (buckets[i] == NULL) {
continue;
}
while ((cus != NULL)) {
if (cus->shoesize == EOF) {
break;
}
if (strcmp(cus->email, Email) == 0) {
free(cus->email);
free(cus->food);
free(cus->name);
free(cus);
cus->shoesize = EOF;
cus = NULL;
exist = true;
break;
}
if (cus->next != NULL) {
cus = cus->next;
} else {
break;
}
}
}
if (exist == false) {
printf("user not found!\n");
}
} else if (strcmp(cmd, "list") == 0) {
for (int i = 0; i < 32; i++) {
Customer *cus = buckets[i];
if (buckets[i] == NULL) {
continue;
}
while ((cus != NULL) && ((cus->shoesize) != EOF)) {
printf("email: %s\n", cus->email);
printf("name: %s\n", cus->name);
printf("shoesize: %d\n", cus->shoesize);
printf("food: %s\n", cus->food);
if (cus->next != NULL) {
cus = cus->next;
printf("\n");
} else {
break;
}
}
}
} else if (strcmp(cmd, "quit") == 0) {
break;
} else if (strcmp(cmd, "save") == 0) {
fp = fopen("customers.tsv", "w");
for (int i = 0; i < 32; i++) {
Customer *cus = buckets[i];
if (buckets[i] == NULL) {
continue;
}
while ((cus != NULL) && ((cus->shoesize) != EOF)) {
fprintf(fp, "%s\t%s\t%d\t%s", cus->email, cus->name, cus->shoesize, cus->food);
if (cus->next != NULL) {
cus = cus->next;
fprintf(fp, "\n");
} else {
break;
}
}
}
fclose(fp);
} else {
printf("unknown command\n");
}
}
for (int i = 0; i < 32; i++) {
Customer *tmp;
Customer *cus = buckets[i];
if (cus == NULL) {
continue;
}
if (cus->next != NULL) {
tmp = cus;
cus = cus->next;
} else {
break;
}
while ((tmp != NULL)) {
if (tmp->shoesize != EOF) {
free(tmp->email);
free(tmp->food);
free(tmp->name);
free(tmp);
}
cus->shoesize = EOF;
cus = NULL;
}
if (tmp != NULL) {
free(tmp);
}
if (cus != NULL) {
free(cus);
}
}
return 0;
}
I tried to compile with -g and then run gdb to find the line that caused the segmentation fault, but the error message confused me.
The error message means:
crash happened inside GLIBC strtol_l_internal() function
GDB can't show you the source of that function because libc6-src (or similar) package is not installed.
Now, looking at the source for strtol_l_internal() is not going to be helpful -- the root cause of the problem is that you called it with incorrect parameter.
You should read man strtol and verify that you satisfied its preconditions.
It looks like you called strtol(NULL, NULL, ...), which is not a valid thing to do. You could use (gdb) up command to find out where the wrong call came from, and fix the caller.

How to test if a file is open/closed in different functions in C

I need to write separate functions for opening/closing the file and working with it. Was recommended to not use global variables in it.
I have a function where I need to open the file and print what's in it(open_file), a second to work with the data in it(do_stuff_in_file), and a third to only close the file and exit the program(close_file).
When I try to call do_stuff_in_file or close_file the program just crashes.
I know I'm supposed to use pointers, but I just can't get it right and I don't know where's the mistake.
int open_file(FILE **fr) {
if ((fr = fopen("soldcars.txt", "r")) == NULL) {
printf("File was not opened\n");
return 1;
}
else {
char testchar;
while ((testchar = fgetc(fr)) != EOF) {
ungetc(testchar, fr);
//just printing whats in the file
}
}
return 0;
}
int do_stuff_in_file(FILE **fr, int date) {
if (fr==NULL) {
printf("File not open yet\n");
return 1;
}
else{ fseek(fr, 0, SEEK_SET); } //doing stuff
return 0;
}
int close_file(FILE **fr) {
if (fr==NULL) {
printf("It was not even open yet\n");
return 1;
}
else{
if (fclose(fr) == EOF) {
printf("File was not successfully closed");
return 1;
}
else{
printf("Adios");
exit(1);
}
}
}
int main() {
char input;
int date;
FILE* fr;
fr = NULL;
while ((input = getchar()) != 'c') {
if (input == 'o') open_file(&fr);
else if (input == 'd') {
scanf("%d", &date);
do_stuff_in_file(&fr, date);
}
}
if (input == 'c') {
close_file(&fr);
}
return 0;
}
You need to dereference properly. eg
int open_file(FILE **fr) {
if ((*fr = fopen("soldcars.txt", "r")) == NULL) {
perror( "soldcars.txt" );
return 1;
}
Note *fr = open instead of fr = open. And, in that function, always use *fr, as in fgetc(*fr) vice fgetc(fr). Similarly in the other functions. Because fr is not a FILE *, but *fr is.

Custom pidgin plugin crashes (GTK library and GLib on C )

I am developing plugin for Pidgin. I want to share one of my windows that are open on my computer with other user via VNC. When I select the window to be shared and press the button, Pidgin freezes and closes.
Here is working well: opening vnc connection and sends Port name to other users. (but this one for sharing all of screen.)
static void
send_button_cb(GtkButton *button, PidginConversation *gtkconv)
{
gchar *url_vnc;
gchar *url_http;
gchar *joinstr;
int std_out[2];
int autoport = purple_prefs_get_bool(PREF_AUTOPORT);
char x11vnc_port[10] = "0";
if (purple_prefs_get_bool(PREF_X11VNC) && ((x11vnc_pid == 0) || (kill(x11vnc_pid, 0) != 0)))
{
if (purple_prefs_get_bool(PREF_GENPASSWD))
{
readableRandomString(password, 4);
}
else
{
strcpy(password, purple_prefs_get_string(PREF_PASSWD));
}
sprintf(x11vnc_port, "%d", 5900 + purple_prefs_get_int(PREF_PORT));
pipe(std_out);
if ((x11vnc_pid = fork()) == 0)
{
close(1);
close(std_out[0]);
dup2(std_out[1], 1);
close(std_out[1]);
int ret = execlp("x11vnc", "x11vnc", "-shared", "-gui", "tray", "-http", "-viewonly", "-passwd", password, ((autoport) ? "-autoport" : "-rfbport"), x11vnc_port, NULL);
perror("pidgin_vnc:x11vnc");
exit(ret);
}
close(std_out[1]);
port_num = x11vnc_port;
if (fd = fdopen(std_out[0], "r"))
{
while (!feof(fd))
{
if (fscanf(fd, "PORT=%d", &port_num))
break;
}
port_num -= 5900;
//close (fd);
printf("FINI\n");
}
else
{
port_num = x11vnc_port;
}
}
const char *ip;
PurpleStunNatDiscovery *stun_res = purple_stun_discover(NULL);
if (stun_res && stun_res->status == PURPLE_STUN_STATUS_DISCOVERED)
{
printf("STUN mode %d %d\n", stun_res->status, stun_res->type);
ip = purple_network_get_my_ip(-1);
}
else
{
ip = purple_upnp_get_public_ip();
if (ip == NULL)
{
printf("LOCAL mode\n");
ip = purple_network_get_my_ip(-1);
}
else
{
printf("UPNP mode\n");
}
}
url_http = g_strdup_printf("http://%s:%d/", ip, 5800 + port_num);
url_vnc = g_strdup_printf("vnc://invitation:%s#%s:%d", password, ip, port_num);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, url_vnc);
joinstr = g_strdup_printf("%s.\ntry %s\nor %s. Password=%s", purple_prefs_get_string(PREF_TEXT), url_vnc, url_vnc, url_http, url_http, password);
gtk_imhtml_append_text(GTK_IMHTML(gtkconv->entry), joinstr, FALSE);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "imhtml display vnc\n");
g_signal_emit_by_name(gtkconv->entry, "message_send");
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "message sent\n");
g_free(url_vnc);
g_free(url_http);
g_free(joinstr);
}
There is a problem in here. When I click to button which is calling this function program crashes when you click the button.(this function for sharing one of my windows that are open on my computer.)
static void
send_button_cb_win(GtkButton *button, PidginConversation *gtkconv)
{
gchar *url_vnc;
gchar *url_http;
gchar *joinstr;
int std_out[2];
int comboBoxSelectedRow = gtk_combo_box_get_active(combo_box);
char *selectedId[1] = {0};
selectedId[0] = ekranIds[0][comboBoxSelectedRow];
int autoport = purple_prefs_get_bool(PREF_AUTOPORT);
char x11vnc_port[10] = "0";
if (purple_prefs_get_bool(PREF_X11VNC) && ((x11vnc_pid == 0) || (kill(x11vnc_pid, 0) != 0)))
{
if (purple_prefs_get_bool(PREF_GENPASSWD))
{
readableRandomString(password, 4);
}
else
{
strcpy(password, purple_prefs_get_string(PREF_PASSWD));
}
sprintf(x11vnc_port, "%d", 5900 + purple_prefs_get_int(PREF_PORT));
pipe(std_out);
if((x11vnc_pid = fork()) == 0)
{
close(1);
close(std_out[0]);
dup2(std_out[1], 1);
close(std_out[1]);
int ret = execlp("x11vnc", "x11vnc", "-id", selectedId[0], "-gui", "-shared", "tray", "-http", "-viewonly", "-passwd", password, ((autoport) ? "-autoport" : "-rfbport"), x11vnc_port, NULL);
perror("pidgin_vnc:x11vnc");
exit(ret);
}
close(std_out[1]);
port_num = x11vnc_port;
if (fd = fdopen(std_out[0], "r"))
{
while (!feof(fd))
{
if (fscanf(fd, "PORT=%d", &port_num))
break;
}
port_num -= 5900;
//close (fd);
printf("FINI\n");
}
else
{
port_num = x11vnc_port;
}
}
const char *ip;
PurpleStunNatDiscovery *stun_res = purple_stun_discover(NULL);
if (stun_res && stun_res->status == PURPLE_STUN_STATUS_DISCOVERED)
{
printf("STUN mode %d %d\n", stun_res->status, stun_res->type);
ip = purple_network_get_my_ip(-1);
}
else
{
ip = purple_upnp_get_public_ip();
if (ip == NULL)
{
printf("LOCAL mode\n");
ip = purple_network_get_my_ip(-1);
}
else
{
printf("UPNP mode\n");
}
}
url_http = g_strdup_printf("http://%s:%d/", ip, 5800 + port_num);
url_vnc = g_strdup_printf("vnc://invitation:%s#%s:%d", password, ip, port_num);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, url_vnc);
joinstr = g_strdup_printf("%s.\ntry %s\nor %s. Password=%s", purple_prefs_get_string(PREF_TEXT), url_vnc, url_vnc, url_http, url_http, password);
gtk_imhtml_append_text(GTK_IMHTML(gtkconv->entry), joinstr, FALSE);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "imhtml display vnc\n");
g_signal_emit_by_name(gtkconv->entry, "message_send");
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "message sent\n");
g_free(url_vnc);
g_free(url_http);
g_free(joinstr);
gtk_widget_show_all(button);
}
This function to fill combobox with opened windows names
static void
refresh_combo_box(GtkWidget *widget, PidginConversation *gtkconv)
{
FILE *fp1;
FILE *fp2;
char path[1035];
char path2[1035];
char sum[1035];
/* Open the command for reading. */
fp1 = popen("xprop -root | grep '_NET_CLIENT_LIST_STACKING(WINDOW)'", "r");
if (fp1 == NULL)
{
printf("Failed to run command\n" );
exit(1);
}
/* Read the output a line at a time - output it. */
while (fgets(path, sizeof(path) - 1, fp1) != NULL)
{
// printf("%s", path);
strcat(sum, path);
}
char *splitter = strtok(sum, "#");
splitter = strtok(NULL, "#");
char *virgulSplitter = strtok(splitter, ", ");
ekranIds[0][0] = strdup(virgulSplitter);
int a = 1;
while (virgulSplitter != NULL)
{
virgulSplitter = strtok(NULL, ",");
if (virgulSplitter != NULL)
{
ekranIds[0][a] = strdup(virgulSplitter);
a++;
}
}
for (int x = 0; x < a; x++)
{
ekranIds[0][a - 1][strcspn(ekranIds[0][a - 1], "\n")] = 0;
char tmp[500] = {0};
//here is get window names by id
sprintf(tmp, "xprop -id %s | grep '^WM_NAME'", ekranIds[0][x]);
fp2 = popen(tmp, "r");
if (fp1 == NULL)
{
printf("Failed to run command\n" );
exit(1);
}
// Read the output a line at a time - output it.
while (fgets(path2, sizeof(path2) - 1, fp2) != NULL)
{
char *windowSplitter = strtok(path2, "=");
windowSplitter = strtok(NULL, "=");
ekranIds[1][x] = strdup(windowSplitter);
}
}
pclose(fp2);
pclose(fp1);
char *combobox_source[30];
for (int yf = 0; yf < 30; yf++)
{
if (ekranIds[1][yf] != NULL)
{
combobox_source[yf] = strdup(ekranIds[1][yf]);
}
}
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(combo_box)));
for (int i = 0; i < G_N_ELEMENTS(combobox_source); i++)
{
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), combobox_source[i]);
}
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
gtk_widget_show_all(combo_box);
}
First function is working well: opening vnc connection and sends Port name to other users. (but this one for sharing all of screen.)
Second function has problem. When I click to button which is calling this function program crashes when you click the button.(this function for sharing one of my windows that are open on my computer.)
Third function to fill combobox with opened windows' names.

minishell malloc error with EXC_BAD_ACCESS

Hi I've recently started learning unix system programming.
I'm trying to create a minishell in c but when I run my code,
I always get:
EXC_BAD_ACCESS (code=EXC_I386_GPFLT
Don't really know what's wrong here. Searched online they say it's something wrong with malloc, but I don't see what's wrong.
Can someone help me with this problem?
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include "minishell.h"
char promptString[] = "mysh>";
struct command_t command;
int enviromentlength;
int commandlength;
char *pathv[MAX_PATHS];
//to display the prompt in the front of every line
void printPrompt()
{
printf("%s", promptString);
}
//get the user's command
void readCommand(char *buffer)
{
gets(buffer);
}
//get the environment variable and store in a pathEnvVar
int parsePath( char* dirs[] )
{
char* pathEnvVar;
char* thePath;
int i;
for(i = 0; i < MAX_ARGS; i++)
{
dirs[i] = NULL;
}
i = 0;
//use system call to get the environment variable
pathEnvVar = (char*) getenv("PATH");
//printf("%s\n", pathEnvVar);
thePath = (char*) malloc(strlen(pathEnvVar) + 1);
strcpy(thePath, pathEnvVar);
//splict the variable and store in the pathv
char *temp = strtok(thePath, ":");
dirs[i] = temp;
while(temp != NULL)
{
i++;
temp = strtok(NULL, ":");
if(temp == NULL)
{
break;
}
else
{
dirs[i] = temp;
}
}
dirs[i+1] = NULL;
return i;
}
//get the user's command and parameters
int parseCommand(char * commandline)
{
int i = 0;
char* temp;
temp = strtok(commandline, " ");
while(temp != NULL)
{
command.argv[i] = temp;
i++;
temp = strtok(NULL, " ");
}
command.argv[i] = NULL;
return i;
}
//input the user's command to
//fix the absolute path of the command
char* lookupPath(char* dir[], char* command[])
{
char* result = NULL;
int i;
//printf("%c\n", *command.argv[0]);
//if the command is already an absolute path
if(*command[0] == '/')
{
result = command[0];
//printf("test\n");
if( access(result, X_OK) == 0)
{
return result;
}
else
{
fprintf(stderr, "%s: command not found\n", result);
return NULL;
}
}
//if the command is not an absolute path
else
{
for(i = 0; i < enviromentlength; i++)
{
char *temp = (char *) malloc (30);
strcpy(temp, dir[i]);
strcat(temp, "/");
strcat(temp, command[0]);
result = temp;
if( access(result, X_OK) == 0)
{
return result;
}
}
fprintf(stderr, "%s: command not found\n", result);
return NULL;
}
}
//to change the directory and
//display the absolute path of the current directory
void do_cd(char* dir[])
{
char currentdirectory[MAX_PATHS];
if(dir[1] == NULL || (strcmp(dir[1], ".") == 0))
{
printf("director does not change\n");
//printf("The current directory is:%s", currentdirectory);
}
else
{
if(chdir(dir[1]) < 0)
{
printf("change director error\n");
}
else
{
printf("change director success\n");
}
}
getcwd(currentdirectory, MAX_PATHS);
printf("The current directory is:%s\n", currentdirectory);
}
//redirection the result to file
void redirection(char* command, char* commandcontent[], int position, pid_t thisChPID)
{
char* content[commandlength - 1];
char* filename = (char *) malloc(MAX_PATH_LEN);
FILE* fid;
int i = 0;
int stat;
strcpy(filename, commandcontent[position + 1]);
//printf("%s\n", commandcontent[position + 1]);
for(i = 0; i < position; i++)
{
content[i] = commandcontent[i];
//printf("content: %s\n", content[i]);
}
content[i + 1] = NULL;
for(i = 0; i< position + 1; i++)
{
printf("%s\n", content[i]);
}
printf("%s\n", command);
if((thisChPID=fork()) < 0)
{
fprintf(stderr, "fork failed\n");
}
else if(thisChPID == 0)
{
fid = open(filename, O_WRONLY || O_CREAT);
close(1);
dup(fid);
close(fid);
execve(command, content, pathv);
}
else
{
wait(&stat);
}
}
//use pipe to run the program
void piperun(char* command, char* commandcontent[], int position, pid_t thisChPID)
{
printf("%s\n%d\n", command, position);
char* firstcommand[position+1];
char* secondcommand[commandlength-position];
char* result = (char *) malloc(MAX_PATH_LEN);
pid_t child;
//the pipe name
int pipeID[2];
int j;
for(j = 0; j< position; j++)
{
firstcommand[j] = commandcontent[j];
printf("%s\n", firstcommand[j]);
}
firstcommand[j] = NULL;
printf("length: %d\n", commandlength-position);
for(j = 0; j < (commandlength-position); j++)
{
secondcommand[j] = commandcontent[position + 1 + j];
printf("second:%s\n",secondcommand[j]);
}
//secondcommand[j+1] = NULL;
result = lookupPath(pathv, secondcommand);
//printf("%s\n", secondcommand[0]);
printf("%s\n", result);
//create pipe "pipeID"
if(pipe(pipeID)==-1)
{
printf("Fail to creat pipe.\n");
}
if((thisChPID=fork())==-1)
{
printf("Fail to creat child process.\n");
}
if(thisChPID==0)
{
printf("in the child\n");
close(1);
dup(pipeID[1]);
close(pipeID[0]);
close(pipeID[1]);
if(execve(command, firstcommand, pathv)==-1)
{
printf("Child process can't exec command %s.\n",firstcommand[0]);
}
}
else
{
child = fork();
if((child=fork())==-1)
{
printf("Fail to creat child process.\n");
}
if(child==0)
{
close(0);
dup(pipeID[0]);
close(pipeID[1]);
close(pipeID[0]);
if(execve(result, secondcommand, pathv)==-1)
{
printf("Child process can't exec command %s.\n",secondcommand[0]);
}
}
else
{
wait(NULL);
}
}
}
int main()
{
char commandLine[LINE_LEN];
int child_pid; //child process id
int stat; //used by parent wait
pid_t thisChPID;
char *arg[MAX_ARGS];
//the flag of redirection, piping and background running
int redirectionsituation = 0;
int pipesituation = 0;
int background = 0;
char * tempchar;
//Command initialization
int i;
for(i = 0; i < MAX_ARGS; i++ )
{
command.argv[i] = (char *) malloc(MAX_ARG_LEN);
}
//get all directories from PATH env var
enviromentlength = parsePath(pathv);
//Main loop
while(TRUE)
{
redirectionsituation = 0;
pipesituation = 0;
background = 0;
//Read the command line
printPrompt();
readCommand(commandLine);
//input nothing
if(commandLine[0] == '\0')
{
continue;
}
//quit the shell?
if((strcmp(commandLine, "exit") == 0) || (strcmp(commandLine, "quit") == 0))
{
break;
}
//if it is background running
if(commandLine[strlen(commandLine) - 1] == '&')
{
printf("backgrond\n");
tempchar = strtok (commandLine, "&");
//strcpy(commandLine, tempchar);
printf("%s\n", tempchar);
background = 1;
}
//Parse the command line
commandlength = parseCommand(commandLine);
//if the command is "cd"
if(strcmp(command.argv[0], "cd") == 0)
{
do_cd(command.argv);
continue;
}
//Get the full path name
command.name = lookupPath(pathv, command.argv);
printf("command name %s\n", command.name);
//report error
if( command.name == NULL)
{
continue; //non-fatal
}
//if redirection is required
for(i = 0; i < commandlength; i++)
{
if(strcmp(command.argv[i], ">") == 0)
{
redirectionsituation = 1;
break;
}
}
if(redirectionsituation == 1)
{
redirection(command.name, command.argv, i, thisChPID);
continue;
}
//if pipe is required
for(i = 0; i < commandlength; i++)
{
if(strcmp(command.argv[i], "|") == 0)
{
pipesituation = 1;
break;
}
}
if(pipesituation == 1)
{ //run pipe
piperun(command.name, command.argv, i, thisChPID);
continue;
}
//normal running
if((thisChPID=fork()) < 0)
{
fprintf(stderr, "fork failed\n");
}
else if(thisChPID == 0)
{
//printf("run again\n");
execve(command.name, command.argv, pathv);
}
else
{
//do not put the process in the background, wait until the child process terminates
if(background == 0)
{
wait(&stat);
}
}
}
return 0;
}
Run it in a debugger and see where you are dereferencing a null.

Cannot understand why program crashes after a couple iterations of while loop?

I am writing the following program to parse the text file (attached) but it keeps crashing after couple of iterations of while loop or it seems that the buffer storing file contents is corrupted somehow?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
char * pick_question(char *, char, int);
char * print_answer(char *, char, int);
int no_of_questions(char*, char);
void clear();
int debug = 0;
int main(int argc, char* argv[])
{
system("cmd /c chcp 1252");
// system("cmd /c chcp 65001");
if (argc < 2)
{
perror("Please enter a filename!\n");
exit(0);
}
if (argc > 2)
{
debug = atoi(argv[2]);
}
char const* const fileName = argv[1];
FILE* file = fopen(fileName, "r");
if (!file)
{
perror("Unable to read file!\n");
exit(0);
}
else
{
if (debug == 1)
{
printf("File opened successfully\n");
}
}
static char *buffer;
int fileSz;
fseek(file, 0, SEEK_END);
fileSz = ftell(file);
fseek(file, 0, SEEK_SET);
buffer = (char*) malloc((fileSz + 1) * sizeof(char));
if (!buffer)
{
perror("Unable to allocate buffer!");
exit(0);
}
fread(buffer, sizeof(char), fileSz, file);
while (1)
{
time_t t;
srand((unsigned) time(&t));
int sub = rand() % 5 + 1;
char del;
switch (sub)
{
case 1:
del = 'A';
break;
case 2:
del = 'B';
break;
case 3:
del = 'C';
break;
case 4:
del = 'D';
break;
case 5:
del = 'E';
}
int nrOfQues = no_of_questions(buffer, del);
if (nrOfQues == 0)
{
perror("main(): no_of_questions() returned 0. Unsupported text structure in file or incorrect file encoding!");
fclose(file);
exit(0);
}
int qNo = rand() % nrOfQues + 1;
char *ques = pick_question(buffer, del, qNo);
if (ques)
{
printf("\n\n");
puts(ques);
printf("\n\n");
}
else
{
perror("main(): pick_question() returned NULL. Unsupported text structure in file!");
fclose(file);
exit(0);
}
printf("\n\n");
printf("Do you want to see the answer(y/n)?");
char ans, repeat;
scanf("%c", &ans);
if ( ans == 'Y' || ans == 'y')
{
char *ans = print_answer(buffer, del, qNo);
if (ans)
{
printf("\n\n");
puts(ans);
printf("\n\n");
}
else
{
printf("\n\n");
perror("main(): print_answer() returned NULL. Unsupported text structure in file!");
fclose(file);
exit(0);
}
}
printf("Do you want to try more questions (y/n)?");
clear();
scanf("%c", &repeat);
if (repeat == 'N' || repeat == 'n')
{
break;
}
clear();
}
printf("\n\n");
printf("******** Thank you for using TULE Master! ********");
printf("\n\n");
fclose(file);
return 0;
}
char * pick_question(char * buffer, char sub, int qNo)
{
char tmpBuff[20];
char tmpBuff2[20];
const char * searchStr = "FRÅGA";
const char * searchStr2 = "A 1 SVAR:";
const char * searchStr3 = "*****************************************";
char *pStr, *currPos, *nStr, *tmpStr, *tmpStr2;
currPos = buffer;
int count = snprintf(tmpBuff, 20, "FRÅGA %c %d", sub, qNo);
if (count >= 0 || count < 20)
{
if (debug)
{
printf("tmpBuff is %s\n", tmpBuff);
}
currPos = strstr(currPos, tmpBuff);
if (currPos)
{
pStr = currPos;
nStr = currPos + 1;
nStr = strstr(nStr, searchStr);
if (!nStr)
{
nStr = currPos;
nStr = strstr(nStr, searchStr2);
if (!nStr)
{
printf("pick_qestion(): nStr is NULL. Unsupported "
"text structure");
return NULL;
}
}
// Check if it is a scenario based question
count = snprintf(tmpBuff2, 20, "FRÅGA %c %d", sub, qNo-1);
if (count >= 0 || count < 20)
{
tmpStr = strstr(buffer, tmpBuff2);
tmpStr2 = strstr(tmpStr, searchStr3);
if (tmpStr < tmpStr2 && tmpStr2 < pStr)
{
pStr = tmpStr2;
}
}
int qLen = nStr - pStr;
char *ques = malloc(sizeof(char) * (qLen+1));
snprintf(ques,qLen,"%s", pStr);
return ques;
}
else
{
printf("pick_qestion(): string \"FRÅGA\" not found in file!");
return NULL;
}
}
printf("pick_qestion(): snprintf was not successful!");
return NULL;
}
char * print_answer(char * buffer, char sub, int qNo)
{
char tmpBuff[20];
char *pStr, *currPos, *nStr;
int count = snprintf(tmpBuff, 20, "%c %d SVAR:", sub, qNo);
if (count >= 0 || count < 20)
{
currPos = strstr(buffer, tmpBuff);
if (!currPos)
{
printf("print_answer(): string \"SVAR\" not found in file!");
}
pStr = currPos;
nStr = currPos + 1;
char tmpBuff2[20];
int count = snprintf(tmpBuff2, 20, "%c %d SVAR:", sub, qNo+1);
if (count < 0 || count >= 20)
{
printf("print_answer(): snprint was not successful!");
return NULL;
}
nStr = strstr(nStr, tmpBuff2);
if (!nStr)
{
nStr = buffer + strlen(buffer);
}
int ansLen = nStr - pStr;
char *ans = malloc(sizeof(char) * (ansLen+1));
snprintf(ans, ansLen, "%s", pStr);
return ans;
}
printf("print_answer(): snprint was not successful!");
return NULL;
}
int no_of_questions(char *buffer, char sub)
{
char tmpBuff[20];
char *currPos, *pStr;
int count = snprintf(tmpBuff, 20, "FRÅGA %c", sub);
if (count >= 0 || count < 20)
{
if (debug)
{
printf("tmpBuff is %s\n", tmpBuff);
}
currPos = strstr(buffer, tmpBuff);
while (currPos != NULL)
{
pStr = currPos;
currPos = currPos + 1;
currPos = strstr(currPos, tmpBuff);
}
if (pStr != buffer)
{
pStr += 9;
char tmpBuff2[20];
memcpy(tmpBuff2, pStr, 2);
if (debug)
{
printf("No. of questions for %c DEL is are %d\n", sub,
atoi(tmpBuff2));
}
return atoi(tmpBuff2);
}
return 0;
}
return 0;
}
void clear()
{
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
}
This is the file that is given as input to the program:
Link

Resources