Illegal Instruction :4 - c

i was writing a c code for executing "history 10" command of terminal,i run program using clang compiler on my mac terminal,it show error "Illegal Instruction :4"
My Code is-
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include <unistd.h>
#include<string.h>
int main()
{ char cmd[10];
strcpy(cmd,"history 10");
system(cmd);
return 0;
}

You overrun your buffer: the cmd array has only 10 characters and you strcpy an 11-character string into it (the string has an implicit 11-th zero byte at the end, which is the string's terminator).
Get rid of the buffer and just do
system("history 10");
Or declare the buffer long enough to accomodate your current, and possibly some future command. Something like this:
char cmd[500];

Related

Does getcwd() ignore the size of the buffer and copy it?

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
char wd[10];
if(getcwd(wd,BUFSIZ) == NULL){ //BUFSIZ = 8192
perror("getcwd");
exit(1);
}
printf("wd = %s\n",wd);
}
This C code works well in Ubuntu Linux 20.
The size of buffer wd is 10 but if I print the wd, it can output a string that is over size 10.
I think that the function uses the pointer of wd regardless of size, so it can work well but it can also print dummy string. Is it right?
//Edit :
printf("wd2 = %s\n",wd2); -> printf("wd = %s\n",wd);
You lie to getcwd about buffer size.
getcwd does not magically know the buffer size. Buffers which know their own size is not a C language feature. That's why getcwd needs the size parameter!
So, getcwd happily writes beyond end of array.
In C, this is Undefined Behavior. Anything can happen, and "anything" includes what you observe here.
Alright, let's get you straightened out:
You can't declare wd as char[10] and then try and read 8192 bytes into it -- won't work,
You can't declare wd and then try and output wd2 -- won't work, and your compiler should be screaming errors at you,
\\n is a literal "\n" (two \\ are a literal '\') not a newline '\n',
#include <limits.h> and #define _GNU_SOURCE to make PATH_MAX available -- which is the maximum length a pathname can be on your system (if any) -- then read that many bytes with getcwd().
Putting it altogether, you can do:
#define _GNU_SOURCE /* needed for PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h> /* needed for PATH_MAX */
int main (void) {
char wd[PATH_MAX]; /* define your buffer with size PATH_MAX */
if (getcwd (wd, PATH_MAX) == NULL) { /* get the same number of bytes */
perror("getcwd");
exit(1);
}
printf ("wd = %s\n", wd); /* output the results using same variable */
}
Compile
With the source in getcwd.c and ALWAYS compiling with FULL WARNINGS ENABLED, you can do:
$ gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -o bin/getcwd getcwd.c
(note: I have a bin directory in my current directory that I put executables in to keep from cluttering my source directory)
Don't accept code until it compiles without warning. Add -Werror to treat warnings as errors so you can't cheat.
Example Use/Output
Running the program yields:
$ ./bin/getcwd
wd = /home/david/dev/src-c/tmp/debug
Let me know if you have further questions.

Why is there a difference in the output if redirected to a text file and how to solve it

If compiled this program
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]){
printf("If I had more time, \n");
write(STDOUT_FILENO, "I would have written you a shorter letter.\n", 43);
exit(EXIT_SUCCESS);}
it prints on the terminal:
"If I had more time,
I would have written you a shorter letter."
In this specific order,
but when directing it to a text file (ie: ./program.a>test.txt)
the order of these 2 sentences switch, I've tried googling it but to no avail.
Any ideas

vswprintf keeps prefixing a Byte Order Mark character

I am still a rookie with C, and even newer to wide chars in C.
The below code should show
4 points to Smurfs
but it shows
4 points to Smurfs
In gdb I see this:
(gdb) p buffer
$1 = L" 4 points to Smurfs",
But when I copy paste from the console, the spaces are magically gone:
(gdb) p buffer
$1 = L"4 points to Smurfs",
Also, buffer[0] contains this according to gdb:
65279 L' '
Apparently the character in question &#65279 is the Unicode Character 'ZERO WIDTH NO-BREAK SPACE' (U+FEFF). I retyped the code making sure I did not enter this. I don't know where this comes from. I also opened the code in notepad per https://stackoverflow.com/a/9691839/7602 and there is no extra chars there.
I wouldn't care if ncurses would stop showing this as a space.
Code (heavily cut down):
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <wchar.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <locale.h>
#define NCURSES_WIDECHAR 1
#include <ncursesw/ncurses.h>
#include "types.h"
#include "defines.h"
#include "externs.h"
WINDOW * term;
/*row column color n arguments */
void rccn(int row, int col, const wchar_t *fmt, ...)
{
wchar_t buffer[80];
int size;
va_list args;
va_start(args, fmt);
size = vswprintf(buffer, 80, fmt, args);
va_end( args );
if(size >= 80){
mvaddwstr(row, col, L"Possible hacker detected!");
}else{
mvaddwstr(row, col, buffer);
}
}
int main(void)
{
int ch;
setlocale(LC_ALL,"");
term = initscr();
rccn(1,1,L"%i points to %ls",4,L"Smurfs");
ch = getch();
return EXIT_SUCCESS;
}
The problem goes 'away' with
rccn(1,1,L"%i points to %ls",4,L"Smurfs"+1);
As if the wide encoding of the constant adds that char in front..
Found it..
I had followed a tutorial where it was advised to add this compiler flag:
-fwide-exec-charset=utf-32
My code was not running on Cygwin at all, and I read that Windows is utf-16 centered, so I removed that compiler flag and it started working on Cygwin.
Then out of curiosity I removed the compiler flag on Raspbian, and it is now working as expected there as well, no more byte order marks.

How to fix Segmentation fault in C

Hello i wrote my c program which will be run on linux.
I am trying to make my own shell for linux.
I have the following code below...
#include <limits.h>
#include <libgen.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */
int main(void){
int i = 0;
int k = 0;
int argsCount = 0;
char inputBuffer[MAX_LINE]; /*buffer to hold command entered */
int background; /* equals 1 if a command is followed by '&' */
char *args[MAX_LINE/2 + 1]; /*command line arguments */
pid_t tpid ;
pid_t child_pid;
int child_status;
char path[PATH_MAX+1];
char *progpath = strdup(args[0]);
char *prog = basename(progpath);
char temp[MAX_LINE];
}
It'is compiling well but when i try to run the code it gives me segmentation fault error
How can i fix it and why i take this error?
Your main has a wrong signature. You want
int main(int argsCount, char**args) {
and of course you should remove the internal declaration of argCount & args inside your main.
Perhaps you want instead your args & argCount to contain the parsed arguments of your own shell (but you still have to give a good signature to your main, conventionally and very often int main(int argc, char**argv).... you probably want your shell to accept the -c argument as most shells do, this would ease debugging with simplistic test cases). Then you should initialize them, and you should read some line (probably with getline) in a loop.
As I commented, you should compile with all warnings & debug info:
gcc -Wall -Wextra -g yoursource.c -o yourprog
Then use gdb ./yourprog to debug your program (see GDB documentation). valgrind should also be helpful. Of course, be sure to develop on a Linux system!
BTW, your program is not a convincing start for a shell. Use strace on some existing shell to understand what a shell needs to do. Study the source code of some existing free software shell (e.g. sash, fish, GNU bash ...). Read Advanced Linux Programming

Reading/Writing errno or stack variable causes segfault. Why?

I have a really weird problem here, and haven't managed to find an answer online.
It appears after debugging with printf statements that a segfault ocurred when trying to read errno. Commenting problemed lines out one by one as they cause segfault resulted in having to comment out every reference to errno, after a readdir() call reaches the end of the directory stream and returns NULL.
Even then, the code then segfaults later when trying to access another automatic variable, file_count.
What is going on? Is this a stack overflow? How do I make it stop?
The code is below, if you feel the need to wade through it. All the problematic references to errno are removed, and the program segfaults after successfully executing the third second last line: printf("printing file_count\n");.
EDIT1: Here's a GDB backtrace:
#0 0xc95bf881 in strcpy () from /usr/lib/libc.so.1
#1 0x08051543 in dir_get_list (user=0x8047b88 "user1") at maildir.c:231
#2 0x08050f3e in main (argc=4, argv=0x80479f4) at maildir.c:43
END EDIT1
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#define MAX_FILENAME_LENGTH 255
#define MAX_USERNAME_LENGTH 40
#define MAX_PASSWORD_LENGTH 20
typedef int bool;
#define true 1
#define false 0
struct files_struct{
/*The number of email messages in a maildir.*/
int count;
/*A pointer to an array of pointers to the strings of the filenames. */
char **FileNames;
/*A pointer to an array of ints that give the corresponding size of the file.*/
int *FileSize;
};
typedef struct files_struct FilesStruct;
void dir_set_path(char* path);
bool check_user(char* username, char* pass);
FilesStruct* dir_get_list(char* user);
void delete_mail(char* user, char* filename);
char* get_file(char* user, char* filename);
FilesStruct* dir_get_list(char* user){
char maildir_name[MAX_FILENAME_LENGTH];
DIR * maildir_fd;
struct dirent *maildir_p;
strcpy(maildir_name,"./");
strncat(maildir_name,user,MAX_USERNAME_LENGTH);
strcat(maildir_name,"/");
if((pthread_mutex_lock(&maildir_root_mutex))<0)
perror("ERROR on locking maildir_root_mutex");
printf("Opening directory ""%s""\n",maildir_name);
if((maildir_fd = opendir(maildir_name))==NULL)
perror("ERROR on opendir");
int file_count = 0;
/* scan over entire directory, counting number of files to that data can be properly malloced */
while(1){
if((maildir_p = readdir(maildir_fd))==NULL){
closedir(maildir_fd);
printf("breaking loop\n");
break;
}
char file[MAX_FILENAME_LENGTH+1];
strcpy(file,maildir_p->d_name);
printf("File %d: '%s'\n",file_count+1,maildir_p->d_name);
/* if the file is a file other than an email */
if(!strcmp(".",file)||!strcmp("..",file)||!strcmp("pass",file)||!strcmp(".svn",file)){
printf("Continuing without incrementing file_count\n");
continue;
}
file_count++;
}
printf("%u\n",maildir_fd);
printf("printing file_count\n");
printf("%d",file_count);
printf("file_count printed successfully");
/* Additional code OMITTED */
I came across this recently. In my instance it was that another module had declared:
int errno = 0;
as a global, instead of #including errno.h. Any code that used the "proper" errno would immediately segfault.

Resources