how to create a chaine of symbolic links in c - c

when i try to execute this code i "segmentation fault"appears on the screen. Can someone please tell me what the error is? thanks in advance
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char * argv[]){
int fd , i;
int count= atoi(argv[2]);
char name[50];
char nname[50];
strcpy(nname, "./lfille");
strcpy(name, argv[1]);
struct stat statbuf;
/* if((fd=open(argv[1], O_RDWR)==-1)){
fprintf(stderr, "Datei existiert nicht\n");
}else*/ if((lstat(argv[1], &statbuf)==-1)){
fprintf(stderr, "Error bei lstat\n");
}else if(!(S_ISREG(statbuf.st_mode))){
printf("%s ist nicht REG\n ", argv[1]);
exit(1);
}else{
for(i=0; i<count; i++){
printf("%s", nname);
symlink(name, nname);
sprintf(name,"%s", nname);
sprintf(nname, "./lfille%d", i);
}
}
return 0;
}

I compiled the source code with gnu gcc 4.8.2.
The program worked fine for me. I think you are only passing one argument to the program instead of two. This is why. I suggest what Weather Vane said in his answer.

The parameter *argv[] is an array of string pointers, with argc informing the length of this array.
The first element argv[0] points to a string holding the program name. If there were any runtime arguments supplied when the program is run, a string pointer is supplied for each one, with the appropriate value in argc to tell you how many elements of the string pointer array have been supplied. If there were no program arguments supplied, *argv[] array will have a length of 1.
If you try to access the arguments that should have been given, you will be indexing beyond the length of the array *argv[] which leads to undefined behaviour. You will be dereferencing a pointer which has an essentially random value. This might be benign, or it might lead to the segmentation fault due to trying to access memory you are not allowed.
I suggest any program which takes (say 2) user arguments at run time have checking code similar to this:
if (argc < 3) {
printf ("Syntax should be: %s filename links\n", argv[0]);
exit (1);
}

Related

Segmentation Fault but I can't find it

This is a program that takes the arguments passed by the user, checks if it's a letter, and concatenates them in an array:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char **argv)
{
char frase[80] = "";
for(int i = 1; i < argc; i++) {
printf("%s", argv[i]);
if(isalpha(argv[i]))
strcat(frase, argv[i]);
}
printf("%s\n", frase);
}
I have used gdb (also with the core option) and there are no errors, yet I get Segmentation Fault (core dumped). The code works if I remove if(isalpha(argv[i])). Any help would be appreciated, thank you.
The argument to isalpha is one character, not a pointer to a string of characters. Passing it a pointer might cause it to reference undefined memory by indexing out of the table of characters it uses.

Using command line arguments in C

I have the following code where I try to access the command line arguments but I am having trouble doing so.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv) {
int fd = open("drawing.ppm", O_RDWR | O_CREAT | O_APPEND, 0700);
char colour[] = "0 0 0 ";
if(argv[1] == "red") {
char colour[] = "255 0 0 ";
}
printf("%s\n", &argv[1]);
int date = write(fd, colour, sizeof(colour));
close(fd);
}
When I run the code, the terminal displays 1▒ which is some weird unexpected symbol. Can someone please tell me why this isn't working?
A few things.
First your signature for main() is wrong it should be
int main(int argc, char *argv[])
Notice how argv is an array (pointer) of strings not chars.
Second you don't check to see if there were any args passed.
Something like
if (argc > 2)
Third your printout is the address of argv[1] instead of argv[1]
Try (inside/after the argc check)
printf("%s\n", argv[1]);
you declare 2 times colour variable take care of that the second one is local to the if-scope.
The type of argv[1] is char* and you try to use with the operator == which is useful for string type variables. Here you are comparing two pointers, in fact, two memory addresses.
You may try to use strcmp to compare the contents of objects pointed by the pointers.

Bad address error with execvp

I'm trying to make a shell "bosh>" which takes in Unix commands and keep getting a bad address error. I know my code reads in the commands and parses them but for some reason, I cannot get them to execute, instead, I get a "bad address" error.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <sys/wait.h>
#define MAX_LINE 128
#define MAX_ARGS 10
int main(){
pid_t pid;
char command[MAX_LINE]; /*command line buffer*/
char *commandArgs[MAX_ARGS]; /*command line arg*/
int i;
char *sPtr=strtok(command," ");
int n=0;
printf("bosh>");
fgets(command, MAX_LINE-1,stdin);
command[strlen(command)-1]='\0';
while(strcmp(command,"quit")!=0)
{
n=0;
sPtr=strtok(command," ");
while(sPtr&&n<MAX_ARGS)
{
sPtr=strtok(NULL," ");
n++;
}
commandArgs[0]=malloc(strlen(command)+1);
strcpy(commandArgs[0],command);
if(fork()==0)
{
execvp(commandArgs[0],commandArgs);
perror("execvp failed");
exit(2);
}
pid=wait(NULL);
printf("%s",">" );
fgets(command, MAX_LINE-1,stdin);
command[strlen(command)-1]='\0';
}
printf("Command (%d) done\n", pid);
return 0;
}
These two lines are the culprit:
commandArgs[0]=malloc(strlen(command)+1);
strcpy(commandArgs[0],command);
First of all, malloc(strlen(...)) followed by strcpy is what the POSIX function strdup already does. But then, you don't need to even copy the string - it is enough to just store the pointer to the original string into commandArgs[0]:
commandArgs[0] = command;
But then, how does execvp how many arguments the command is going to take? If you read the manuals carefully, they'd say something like:
The execv(), execvp(), and execvpe() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers MUST be terminated by a NULL pointer.
Your argument array is not NULL-terminated. To fix it, use
commandArgs[0] = command;
commandArgs[1] = NULL; // !!!!
(Then you'd notice that you'd actually want to assign the arguments within the strtok parsing loop, so that you can actually assign all of the arguments into the commandArgs array; and compile with all warnings enabled and address those, and so forth).
You initialize sPtr in its declaration, which you do not need to do because you never use the initial value. But the initialization produces undefined behavior because it depends on the contents of the command array, which at that point are indeterminate.
The array passed as the second argument to execvp() is expected to contain a NULL pointer after the last argument. You do not ensure that yours does.
You furthermore appear to drop all arguments to the input command by failing to assign tokens to commandArgs[]. After tokenizing you do copy the first token (only) and assign the copy to the first element of commandArgs, but any other tokens are ignored.

What is the correct changes I should make to my if statement to make it activate?

Currently I have a code that passes arguments to main and I use the strstr tool to see if the arguments or strings passed to it are subsets of each other. If they are not, I get the message (null). However, when I try to take advantage of this with an if statement it doesn't seem to activate?
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i;
for(i=1; i<argc; i++)
{
printf("%s\n", argv[i]);
}
printf("\n");
char *chant;
chant = strstr(argv[1], argv[2]);
printf("The subtring is: %s\n", chant);
if(chant==NULL)
{
printf("good bye");
}
return 0;
}
So if I enter something like hello helloow, it will say "The substring is: (null)" and from there I want my if statement to activate and print "good bye". Isn't chant NULL when strstr can't find a substring? I know there is something wrong with my if statement syntax, but not sure >....
I have tried this as well:
if(*chant!=NULL)
but it gives me this comparison error about pointer and integer.
EDIT:
I don't know WHY, but it seems that if I use GCC instead of CC to comnpile then it will work.. This is very odd..
printf() expects a valid (non-NULL) char* matching the %s. Passing a (char*)NULL is technically undefined behaviour. glibc printf(), for probably bad reasons, decides that "undefined behaviour" to them means printing "(null)".
But the C-compiler sees you dereference a pointer, and then afterwards check whether it was NULL. The compiler is free to conclude that, since you've already dereferenced that pointer, and the world hasn't ended, that pointer wasn't NULL, so it removes the if(!chant){//can't happen}. Welcome to C.
To get defined behaviour, you could go with code like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc < 3)
exit(EXIT_FAILURE); //to avoid passing a NULL-ptr to printf()/strstr()
int i;
for(i=1; i<argc; i++)
{
printf("%s\n", argv[i]);
}
printf("\n");
char *chant;
chant = strstr(argv[1], argv[2]);
printf("The subtring is: %s\n", chant?chant:"(null)");
//prints "(null)" when substring not found, substring otherwise
if(chant==NULL)
{
printf("good bye");
}
return 0;
}

C strcat - warning: passing arg 2 of `strcat' makes pointer from integer without a cast

I'm having a problem with the program below. I'm trying to scan through a string command entered by the user for certain words. My major issue right now is that when I run the following I get a warning saying that "passing arg 2 of `strcat' makes pointer from integer without a cast". My intent is to loop through the first three characters of the string "s", concatenate them onto a string "firstthree", and later check the value of the string "firstthree". Any help is appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <readline/readline.h>
#include <readline/history.h>
/* Simple example of using gnu readline to get lines of input from a user.
Needs to be linked with -lreadline -lcurses
add_history tells the readline library to add the line to it's
internal histiry, so that using up-arrow (or ^p) will allows the user
to see/edit previous lines.
*/
int main(int argc, char **argv) {
char *s;
while (s=readline("Enter Name: ")) {
add_history(s); /* adds the line to the readline history buffer */
printf("Hello %s\n",s);/*output message to the user*/
char *firstthree;
int i;
for(i = 0; i < 3; i++){
strcat(firstthree, s[i]);
printf("Hello %s\n",firstthree);//checking to see the character added to the end of the string
}
printf("Hey %s\n",firstthree);/*prints out the first three characters*/
free(s); /* clean up! */
free(firstthree);
}
return(0);
}
Your program has a lot of problems; you never initialize firstthree, for example.
The reason you're getting the specific error you're seeing is because of this call:
strcat(firstthree, s[i]);
s is a char *, so s[i] is a char, but strcat expects both parameters to be pointers to null-terminated strings. What it seems you want is something like:
char firstthree[4] = { 0 };
for (int i = 0; i < 3; i++)
{
firstthree[i] = s[i];
printf("Hello %s\n", firstthree);
}
You can't use strcat() to do this; it requires two char* s as arguments, not a char* and a char. You could use strncat() if it is available on your platform.

Resources