pthread_cancel don't work under solaris - c

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
char a[]="Hello";
void * thread_body(void * param) {
while(1)
printf("%s\n", param);
}
int main(int argc, char *argv[]) {
pthread_t threadHello;
int code;
pthread_create(&threadHello, NULL, thread_body, a);
pthread_cancel(threadHello);
pthread_exit(0);
}
When I compile and run this under Solaris 10 (SunOS 5.10), it doesn't stop. But under Linux it works as intended.

Per POSIX, printf (and all of stdio) may be a cancellation point. It is not required to be. I suspect Solaris just doesn't choose to make it one. Have you tried another function like sleep here?
If you really need printf to be cancellable, you'll probably need to implement your own printf-like function as a wrapper for dprintf, but that won't work so well if you're depending on the builtin locking functionality of stdio..

Related

How to pass parameters to asmlinkage function?

I want to add a system call docs and I have one asmlinkage function. The function must take 2 parameters. These parameters are coming from the c docs which I calls system call. At below I showed the c docs :
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main(int argc,char*argv[])
{
long int amma = syscall(335,argc,argv);
printf("System call functions returned %ld\n", amma);
return 0;
}
As you see I want to pass argc and argv char array for making some file operations.
Firstly I wrote my asmlinkage function like that :
asmlinkage long function(int argc,char *argv[]){
if(argc==2)
printk(KERN_INFO "Hello world"); // but it can not take argc
}
In addition I added to line to syscalls.h:
asmlinkage function(int,char*[]);
Then I compiled correctly but when I started to run my code in userspace my syscall killed.
I found a link in this website but I couldn't compile it. Topic owner used "SYSCALL_DEFINE" but I faced many code mistake which I could not understand.

Library include with tkill

I tried use tkill ,to kill some thread with c code .
What are the library I need to include to use this function?
Running on linux ubuntu
int main(int argc , char* argv[])
{
tkill(123,9);
}
You neeed syscall(SYS_tkill, ThePid, TheSignal).
Example:
#include <unistd.h>
#include <sys/syscall.h>
#include <signal.h>
int main()
{
//kills self:
pid_t tid = syscall(SYS_gettid);
syscall(SYS_tkill,tid,SIGTERM);
return 0;
}
Glibc has had a policy of not including wrappers for non-POSIX syscalls.
They may be changing it in current/future versions but using the generic syscall syscall-making function should always work on Linux.

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

Is it possible to redefine main function in c

I saw redefine function here using macro in c. So I am interesting is it possible to redefine main function?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
printf("Original main function\n");
return 0;
}
int _main(int argc, char **argv)
{
printf("New Original main function\n");
return main(argc, argv);
}
#ifdef DEBUG
#define main(argc, argv) _main(argc, argv)
#endif
Code compiled with out any problem but I am getting:
Original main function
So I am wondering why it does not work? When I use same techniques for malloc and free functions it works perfect. So what is wrong?
Why I want to do something like this? I want to do some code before main function will be executed. Is it possible in this way? if not is there are some other way?
P.S.: Sorry I did not mention in question. I am using gcc in Ubuntu OS. If you are down voting please give a reason in comments. You comments is very useful to my further development.
If you want to change entry point of your program, you don't need play with defines. You can use linker's -e option for that:
gcc -Wl,-e,__main ...
Please note extra underscore. Depending on some options, the symbol name can be different.
If your question is really: "can i execute code before main?" Then the answer is an emphatic YES.
Since you are using GCC, you can use function attributes (http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html) to mark a function as a constructor.
void pre_main_function (void) __attribute__ ((constructor));
A useful example can be found at http://www.geeksforgeeks.org/functions-that-are-executed-before-and-after-main-in-c/
EDIT
The following syntax can also be used:
__attribute__ (( constructor(n) ))
where n specifies the priority, allowing you to mark multiple functions to be executed before main whilst giving you control over the execution order ( the lower the value of n, the earlier the function is executed.
Your #define does not change the main function at all - it is a macro preprocessor.
The only effect of your #define will be to change the call to main in _main into a recursive call to _main(). But since _main is not called, this is dead code. This is what your code looks like after the preprocessor has run...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
printf("Original main function\n");
return 0;
}
int _main(int argc, char **argv)
{
printf("New Original main function\n");
return _main(argc, argv); /* recursive call due to macro replace */
}
This then leads to the next question - which is why redefine main at all? If you want some entirely different code to run on debug simply declare main as
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
#ifdef DEBUG
return debugApp( argc, argv);
#else
return productionApp( argc, argv);
#endif
}
N.B Just because you can do something doesn't mean you should do it. :-)

Why does my compiler not accept fork(), despite my inclusion of <unistd.h>?

Here's my code (created just to test fork()):
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int pid;
pid=fork();
if (pid==0) {
printf("I am the child\n");
printf("my pid=%d\n", getpid());
}
return 0;
}
I get following warnings:
warning: implicit declaration of function 'fork'
undefined reference to 'fork'
What is wrong with it?
unistd.h and fork are part of the POSIX standard. They aren't available on windows (text.exe in your gcc command hints that's you're not on *nix).
It looks like you're using gcc as part of MinGW, which does provide the unistd.h header but does not implement functions like fork. Cygwin does provide implementations of functions like fork.
However, since this is homework you should already have instructions on how to obtain a working environment.
You have got #include <unistd.h> which is where fork() is declared.
So, you probably need to tell the system to show the POSIX definitions before you include the system headers:
#define _XOPEN_SOURCE 600
You can use 700 if you think your system is mostly POSIX 2008 compliant, or even 500 for an older system. Because fork() has been around forever, it will show up with any of those.
If you are compiling with -std=c99 --pedantic, then all the declarations for POSIX will be hidden unless you explicitly request them as shown.
You can also play with _POSIX_C_SOURCE, but using _XOPEN_SOURCE implies the correct corresponding _POSIX_C_SOURCE (and _POSIX_SOURCE, and so on).
As you've already noted, fork() should be defined in unistd.h - at least according to the man pages that come with Ubuntu 11.10. The minimal:
#include <unistd.h>
int main( int argc, char* argv[])
{
pid_t procID;
procID = fork();
return procID;
}
...builds with no warnings on 11.10.
Speaking of which, what UNIX/Linux distribution are you using? For instance, I've found several non-remarkable functions that should be defined in Ubuntu 11.10's headers aren't. Such as:
// string.h
char* strtok_r( char* str, const char* delim, char** saveptr);
char* strdup( const char* const qString);
// stdio.h
int fileno( FILE* stream);
// time.h
int nanosleep( const struct timespec* req, struct timespec* rem);
// unistd.h
int getopt( int argc, char* const argv[], const char* optstring);
extern int opterr;
int usleep( unsigned int usec);
As long as they're defined in your C library it won't be a huge problem. Just define your own prototypes in a compatibility header and report the standard header problems to whoever maintains your OS distribution.
I think that you have to do the following instead:
pid_t pid = fork();
To learn more about Linux API, go to this online manual page, or even go into your terminal right now and type,
man fork
Good luck!

Resources