Library include with tkill - c

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.

Related

Why do some Linux system calls not have a wrapper, but are documented as if they do?

Let's look at the gettid system call as an example:
http://man7.org/linux/man-pages/man2/gettid.2.html
I know gettid is not implemented in libc and I need to make a system call directly in order to use it (syscall(SYS_gettid)). I have verified this myself with this C code:
#include <stdio.h>
#include <sys/types.h>
int main(){
pid_t a = gettid();
return 0;
}
which doesn't link and gives this warning when compiling: warning: implicit declaration of function 'gettid'; did you mean 'getline'.
Now my question is, why has the Linux documentation documented it as if this function actually exists?
SYNOPSIS
#include <sys/types.h>
pid_t gettid(void);
They have no example of how to make a direct system call and instead they have the above code snippet which doesn't exist and can't be used. Is there something I'm missing?
The syscall doesn't have a wrapper in the GNU C library (before 2.30), this is just a prototype of how the function would look if it did.
As noted in the man page:
NOTES
Glibc does not provide a wrapper for this system call; call it using syscall(2).
Here's an example of the gettid wrapper:
#define _GNU_SOURCE
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
pid_t gettid(void)
{
pid_t tid = (pid_t)syscall(SYS_gettid);
return tid;
}
As you can see, this is the same prototype as described in the man-page. The prototype in the man-page is just for reference, so you can create a wrapper around the system call if you (or the libc developers) so choose.
If you're just starting to learn C, I suggest you stop trying to understand system calls and their wrappers in the C library until you have more experience in the language. The difference will then be clear.

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

pthread_cancel don't work under solaris

#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..

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!

How to load Linux kernel modules from C code?

I have an application that has both two external kernel modules and a userspace daemon. I want to load the modules from the daemon code, written in C, at startup, and unload them on clean exit. Can I load them in a cleaner way than doing system("modprobe module"); and unload them using the corresponding rmmod?
init_module / remove_module minimal runnable example
Tested on a QEMU + Buildroot VM and Ubuntu 16.04 host with this simple parameter printer module .
We use the init_module / finit_module and remove_module Linux system calls.
The Linux kernel offers two system calls for module insertion:
init_module
finit_module
and:
man init_module
documents that:
The finit_module() system call is like init_module(), but reads the module to be loaded from the file descriptor fd. It is useful when the authenticity of a kernel module can be determined from its location in the filesystem; in cases where that is possible, the overhead of using cryptographically signed modules to determine the authenticity of a module can be avoided. The param_values argument is as for init_module().
finit is newer and was added only in v3.8. More rationale: https://lwn.net/Articles/519010/
glibc does not seem to provide a C wrapper for them, so we just create our own with syscall.
insmod.c
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#define init_module(module_image, len, param_values) syscall(__NR_init_module, module_image, len, param_values)
#define finit_module(fd, param_values, flags) syscall(__NR_finit_module, fd, param_values, flags)
int main(int argc, char **argv) {
const char *params;
int fd, use_finit;
size_t image_size;
struct stat st;
void *image;
/* CLI handling. */
if (argc < 2) {
puts("Usage ./prog mymodule.ko [args="" [use_finit=0]");
return EXIT_FAILURE;
}
if (argc < 3) {
params = "";
} else {
params = argv[2];
}
if (argc < 4) {
use_finit = 0;
} else {
use_finit = (argv[3][0] != '0');
}
/* Action. */
fd = open(argv[1], O_RDONLY);
if (use_finit) {
puts("finit");
if (finit_module(fd, params, 0) != 0) {
perror("finit_module");
return EXIT_FAILURE;
}
close(fd);
} else {
puts("init");
fstat(fd, &st);
image_size = st.st_size;
image = malloc(image_size);
read(fd, image, image_size);
close(fd);
if (init_module(image, image_size, params) != 0) {
perror("init_module");
return EXIT_FAILURE;
}
free(image);
}
return EXIT_SUCCESS;
}
GitHub upstream.
rmmod.c
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#define delete_module(name, flags) syscall(__NR_delete_module, name, flags)
int main(int argc, char **argv) {
if (argc != 2) {
puts("Usage ./prog mymodule");
return EXIT_FAILURE;
}
if (delete_module(argv[1], O_NONBLOCK) != 0) {
perror("delete_module");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
GitHub upstream.
Busybox source interpretation
Busybox provides insmod, and since it is designed for minimalism, we can try to deduce how it is done from there.
On version 1.24.2, the entry point is at modutils/insmod.c function insmod_main.
The IF_FEATURE_2_4_MODULES is optional support for older Linux kernel 2.4 modules, so we can just ignore it for now.
That just forwards to modutils.c function bb_init_module.
bb_init_module attempts two things:
mmap the file to memory through try_to_mmap_module.
This always sets image_size to the size of the .ko file as a side effect.
if that fails, malloc the file to memory with xmalloc_open_zipped_read_close.
This function optionally unzips the file first if it is a zip, and just mallocs it otherwise.
I don't understand why this zipping business is done, since we can't even rely on it because the try_to_mmap_module does not seem to unzip things.
Finally comes the call:
init_module(image, image_size, options);
where image is the executable that was put into memory, and options are just "" if we call insmod file.elf without further arguments.
init_module is provided above by:
#ifdef __UCLIBC__
extern int init_module(void *module, unsigned long len, const char *options);
extern int delete_module(const char *module, unsigned int flags);
#else
# include <sys/syscall.h>
# define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
# define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
#endif
ulibc is an embedded libc implementation, and it seems to provide init_module.
If it is not present, I think glibc is assumed, but as man init_module says:
The init_module() system call is not supported by glibc. No declaration is provided in glibc headers, but, through a quirk of history, glibc does export an ABI for
this system call. Therefore, in order to employ this system call, it is sufficient to manually declare the interface in your code; alternatively, you can invoke
the system call using syscall(2).
BusyBox wisely follows that advice and uses syscall, which glibc provides, and which offers a C API for system calls.
insmod/rmmod use the functions init_module and delete_module to do this, which also have a man-page available. They both declare the functions as extern instead of including a header, but the man-page says they should be in <linux/module.h>.
I'd recommend against the use of system() in any daemon code that runs with root permissions as it's relatively easy to exploit from a security standpoint. modprobe and rmmod are, indeed, the right tools for the job. However, it'd be a bit cleaner and much more secure to use an explicit fork() + exec() to invoke them.
I'm not sure there's a cleaner way than system.
But for sure, if you want to load/unload the modules from your userspace daemon, then you force yourself to run the daemon as root*, which may not be considered as secure.
*: or you can add the explicit commands in the sudoers file, but this will be a nightmare to manage when deploying your application.
You can perform the same tasks that modprobe and Co. do, but I doubt that could be characterized as cleaner.

Resources