The galactic imperium plans to send a star destroyer to attack the rebel‘s base. This star destroyer shall host 1024 imperial clone warriors.
At t=0 there is just one soldier availabe: the captain. From his first birthday on, a clone warrior is able to clone once a year. The imperator wants to get the star destroyer ready for action in short time.
The imperial command structure is very simple:
Every warrior sends commands to his clones
there is no communication to the superior
Write a Linux C-Programm with the following requirements:
Every clone warrior has to be represented by a separate process
Commands have to be transmitted via uniquely (!) named message queues
*There is an existing message queue /Imperator from the Imperator to the captain
After the cloning phase, every clone warrior has to wait for commands to receive and to transmit to his inferiors
Hints and requirements:
Consider, how many soldiers are available in which year: t=0 –just the captain, t=1 –captain and his first clone, etc.
Don‘t worry about error handling
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <errno.h>
// Exercise „clone warriors“
#define NUM 10
#define SIZE_MSGBUF 500
#define MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH |S_IWOTH)
mqd_t QueueArray[NUM]; // queues to my clones
void cleanQueueArray(void) { // support function for init: start with no queues
for (int i=0; i<NUM; i++) QueueArray[i] = 0;
}
int main(void) {
char cNameBossQueue[100] = "/Imperator"; // boss queue‘s default name
mqd_t BossQueue; // boss queue to receive commands of the father‘s process
struct mq_attr attr;
attr.mq_maxmsg = 10;
attr.mq_msgsize = SIZE_MSGBUF;
attr.mq_flags = 0;
int nPrio=0;
char cMsgbuf[SIZE_MSGBUF+1] = "";
cleanQueueArray(); // init: no queues to any clones at the beginning
// phase 1 / clone phase takes NUM years:
for (int i=0; i<NUM; i++) {
pid_t npid_child = fork();
if (npid_child > 0) { // Father. Create + store command channel to clone:
char cQueue[100];
sprintf(cQueue, "/Queue%d", npid_child);
QueueArray[i] = mq_open(cQueue, O_CREAT|O_WRONLY, MODE, &attr);
} else { // Child. Remember the name of the boss queue:
sprintf(cNameBossQueue, "/Queue%d", getpid());
cleanQueueArray(); // Child has no queues to clones currently
}
}
// Phase 2 / battle phase. Receive and transmit orders:
BossQueue = mq_open(cNameBossQueue, O_RDONLY, MODE, &attr);
mq_receive(BossQueue, cMsgbuf, SIZE_MSGBUF, &nPrio);
// Send orders to all of my clones:
for (int i=0; i<NUM; i++) {
if (QueueArray[i] > 0) {
mq_send (QueueArray[i], cMsgbuf, strlen(cMsgbuf), 0);
}
}
// Cleanup work...
return 0;
}
I tried running this using
gcc -o Wall clonew clonew.c -lrt"
./clonew
but I get no output
Your commandline (without the trailing ", which I consider a posting accident)
gcc -o Wall clonew clonew.c -lrt
means
compile clonew and clonew.c
into an executable named "Wall"
using the rt lib
I am not sure why the use of "clonew" (first in the compile command, later in the execution attempt) does not trigger any warning.
Clearly you intend to create and execute that file. But it is used as input file and should, even if it exists but is not a C syntax file, cause some complaint.
However, the reason why you do not get the expected output when trying to execute clonew is that your compile command cannot have resulted in the creation of an executable clonew.
Why the attempt to execute something, which either does not exist yet or is a C code file, does not result in any warnings, errors or any other output is a mystery.
If it already exists as an executable but silent program, it should also trigger a complaint.
Related
I have written a C utility that may be launched manually or on a regular basis, by a cron rule. Inside the C program I want to know if it was launched by a cron rule or not.
Reading the user name with getlogin_r renders the same username wether it is launched manually or by cron.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
char *username = malloc(80);
getlogin_r(username, 80);
printf("owner: %s\n", username);
return 0;
}
Any idea?
Following user sj95126 suggestion, I found an indirect (but good enough) way of detecting if a program has been launched by cron or not.
When it comes to run a command-line present at the crontab, cron creates a non-interactive shell for it, i.e., one without standard input, standard output and standard error. This circumstance can be easily tested with the isatty() function from the unistd.h library.
This is a POC of the idea.
/* owner.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* return true if this process has been launched by cron */
/* cron is not directly identified but deduced from no having a tty */
int launched_bycron() {
return (isatty(STDIN_FILENO) + isatty(STDOUT_FILENO) + isatty(STDERR_FILENO)) == 0;
}
int main() {
/* print 1 if stdin, stdout or stderr exist */
printf("stdin: %d\n", isatty(STDIN_FILENO)); /* STDIN_FILENO = 0 */
printf("stdout: %d\n", isatty(STDOUT_FILENO)); /* STDIN_FILENO = 1 */
printf("stderr: %d\n", isatty(STDERR_FILENO)); /* STDIN_FILENO = 2 */
/* get this process username */
char *username = malloc(80);
getlogin_r(username, 80);
/* differentiate launching by cron from lauhcing by user */
if (launched_bycron()) {
printf("this was launched by cron\n");
}
else {
printf("this was launched by %s\n", username);
}
return 0;
}
When launched manually the output is like this
$ ./owner
stdin: 1
stdout: 1
stderr: 1
this was launched by coterobarros
when launched by cron the output can still be captured piping the standard output to a file
crontab -l
* * * * * /usr/local/bin/owner > /tmp/owner.txt
and the content of the file is
$ cat /tmp/*.txt
stdin: 0
stdout: 0
stderr: 0
this was launched by cron
This link was very helpful too
https://unix.stackexchange.com/questions/46789/check-if-script-is-started-by-cron-rather-than-invoked-manually
I need to load a *.ml file into the Ocaml toplevel (the interactive interpreter, when you type 'ocaml' in a shell) and then send an instruction from a Matlab process, get back the result of the instruction, send back another instruction, ...
I've made this C program. The parent process gets the Matlab's instruction from a named pipe, sends it to the child process (with ocaml running) and gets the response back so it can send it to Matlab.
But there is some kind of bug: when I send an instruction, I get back some weird characters, I send another instruction and then I receive the response of the first instruction...
(I didn't copy the perror() test to have less text)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void) {
// Parent -> Child
int pipe_in[2];
// Child -> parent
int pipe_out[2];
/*
pipe[0] = output
pipe[1] = input
*/
pipe(pipe_in);
pipe(pipe_out);
pid_t pid;
if ((pid = fork()) == 0) {
// CHILD SIDE
close(pipe_in[1]);
close(pipe_out[0]);
dup2(pipe_in[0], STDIN_FILENO);
dup2(pipe_out[1], STDOUT_FILENO);
dup2(pipe_out[1], STDERR_FILENO);
close(pipe_in[0]);
close(pipe_out[1]);
char *args[] = {"ocaml", NULL};
execvp("ocaml", args);
printf("FAIL\n");
exit(EXIT_FAILURE);
} else {
// PARENT SIDE
printf("[*] PID : %d\n", (int) pid);
close(pipe_in[0]);
close(pipe_out[1]);
char cmd[1024];
char feedback[1024];
ssize_t cmd_read;
ssize_t feedback_read = sizeof(feedback);
while (1) {
// Get the instruction from Matlab.
printf("[>] ");
int fifo_in = open("/tmp/pipe_in", O_RDONLY);
cmd_read = read(fifo_in, cmd, sizeof(cmd));
close(fifo_in);
printf("%s\n", cmd);
// Send the instruction to the ocaml interpreter.
write(pipe_in[1], cmd, cmd_read);
// Read the response of the ocaml interpreter.
while (feedback_read == sizeof(feedback)) {
feedback_read = read(pipe_out[0], feedback, sizeof(feedback));
printf("[-] %d\n", (int) feedback_read);
}
printf("[<] %s\n", feedback);
// Send to Matlab the response.
int fifo_out = open("/tmp/pipe_out", O_WRONLY);
write(fifo_out, feedback, feedback_read);
close(fifo_out);
cmd_read = 0;
feedback_read = sizeof(feedback);
}
close(pipe_in[1]);
close(pipe_out[0]);
}
}
I compile the code with gcc -Wall -std=c99 -o tphr tphr.c
I run the programm in one shell and in another :
> printf 'let x = 10;;\n' > /tmp/pipe_in
> cat /tmp/pipe_out
OCaml version 4.03.0
# %
> printf 'let y = 5;;\n' > /tmp/pipe_in
> cat /tmp/pipe_out
val x : int = 10
# %
How can I fix the result ?
If, by "weird characters", you mean
OCaml version 4.03.0
that is simply because this is what the OCaml toplevel prints out on startup. So you need to read this line when your own program starts up.
If you mean the # symbol, also known as the prompt, you can turn it off by running ocaml -nopromt.
You don't want to run the interactive ocaml toplevel here for multiple reasons:
the toplevel parses the configfiles of the user and then loads different modules. This can change the available values, change behaviour, and make your matlab process get different results per user.
the output of the toplevel may change between versions making it difficult to parse and return the right reply to matlab
Did you know that you can call the toplevel from ocaml bytecode to interprete strings? I suggest dumping the C code and writing ocaml byte code to read from the pipe, interpret the command and reply with the result.
I'm trying to write my own "keyboard driver" (without actually writing a kernel module),
by grabbing the keyboard at what I assume is the lowest level of abstraction in userland: /dev/input/event*.
The following code does the grabbing, provided you change the first ocurrence of ioctl(fd, EVIOCGRAB, UNGRAB)
to ioctl(fd, EVIOCGRAB, GRAB).
// gcc main.c -o main
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <linux/input.h>
#include <fcntl.h>
#include <errno.h>
#define EXIT_KEY KEY_ESC
#define UNGRAB 0
#define GRAB 1
const char* kbd_device = "/dev/input/event4";
// ------------------------------------------------------------------------------------------------
int main(void){
int fd = open(kbd_device, O_RDONLY);
if(fd == -1){
printf("Cannot open %s. %s.\n", kbd_device, strerror(errno));
return -1;
}
if(ioctl(fd, EVIOCGRAB, UNGRAB))
printf("Couldn't grab %s. %s.\n", kbd_device, strerror(errno));
else
printf("Grabbed %s!\n", kbd_device);
while(1){
struct input_event event;
read(fd, &event, sizeof(event));
if (event.type == EV_KEY && event.value >= 0 && event.value <= 2){
printf("%d %3d\n", event.value, event.code);
if(event.code == EXIT_KEY){
ioctl(fd, EVIOCGRAB, UNGRAB);
close(fd);
return 0;
}
}
}
}
Problem
If I run gcc main.c -o main && sudo ./main, everything works as expected.
If first compile and then I run sudo ./main, however, the terminal scrolls down nonstop, as if the RETURN key was held down.
Why does happen?
Notes
I'm running Ubuntu 14.04
On my platform, /dev/input/event4 happens to be the keyboard
Motivation
I'm trying to write a keyboard "driver" that works both on X and not on X (eg. a TTY).
I understand X11's keyboard library/extension is XKB. I think the TTY's keyboard library is linux/divers/tty/vt/keyboard.c (source),
the initial keyboard map it uses is in linux/drivers/tty/vt/defkeymap.map (source), and it can be modified by using loadkeys (source here). Do correct me if I'm wrong.
When you type
gcc main.c -o main && sudo ./main ↵
GCC takes some time, so the ↵ key has been released by the time ./main runs.
When you type
sudo ./main ↵
the terminal sends the shell a newline as soon as you push down ↵, and starts executing ./main. Then the ↵ released event is seen by your program, but not by your terminal, because your program has grabbed the input device. Thus, to the terminal it looks like ↵ is stuck down, so it continues to produce newlines.
This question has been answered already, but it still lacks an elegant solution to the problem.
I had the same issue with a driver I implemented some time ago that also required capturing the keyboard.
I could not find a way to force the the kernel to recognize a key release in the device before capturing it, so the solution consists in not grabbing the device until you detect that all keys have actually been released. This can be accomplished by monitoring the device with the EVIOCGKEY ioctl AFTER opening it and BEFORE grabbing it.
OBS: Please observe that the apparently dummy read function within the while loop is necessary in order to avoid a busy wait and so that the loop will iterate after each event from the input device. Also note that the file descriptor must be configured for blocking I/O (the default).
void waitReleaseAll(int fd) {
struct input_event evt;
unsigned char key_b[KEY_MAX/8 + 1];
int i, nothing;
while ( 1 ) {
memset(key_b, 0, sizeof(key_b));
ioctl(fd, EVIOCGKEY(sizeof(key_b)), key_b);
for ( nothing = 1 , i = 0 ; i < KEY_MAX/8 + 1 ; i++ ) {
if ( key_b[i] != 0 ) { nothing = 0; break; }
}
if ( nothing ) break;
read(fd, &evt, sizeof(evt));
}
printf("All keys are now released\n");
}
To fix your problem, you should use SIGINT in your code to identify Ctrl-C keystroke from the user.
Implement SIGNAL in your code:
static volatile sig_atomic_t stop = 0;
static void interrupt_handler(int sig)
{
stop = 1;
} // Outside of the main function.
int main(int argc, char *argv[])
{
signal(SIGINT, interrupt_handler);
while (!stop) {
//your code
}
exit(0);
}
I'm hoping that someone can help me out. I have not written much in C code in over a decade and just picked this back up 2 days ago so bear with me please as I am rusty. THANK YOU!
What:
I'm working on creating a very simple thread pool for an application. This code is written in C on CodeBlocks using GNU GCC for the compiler. It is built as a command line application. No additional files are linked or included.
The code should create X threads (in this case I have it set to 10) each of which sits and waits while watching an array entry (identified by the threads thread index or count) for any incoming data it might need to process. Once a given child has processed the data coming in via the array there is no need to pass the data back to the main thread; rather the child should simply reset that array entry to 0 to indicate that it is ready to process another input. The main thread will receive requests and will dole them out to whatever thread is available. If none are available then it will refuse to handle that input.
For simplicity sake the code below is a complete and working but trimmed and gutted version that DOES exhibit the stack overflow I am trying to track down. This compiles fine and initially runs fine but after a few passes the threadIndex value in the child thread process (workerThread) becomes corrupt and jumps to weird values - generally becoming the number of milliseconds I have put in for the 'Sleep' function.
What I have checked:
The threadIndex variable is not a global or shared variable.
All arrays are plenty big enough to handle the max number of threads I am creating.
All loops have the loopvariable reset to 0 before running.
I have not named multiple variables with the same name.
I use atomic_load to make sure I don't write to the same global array variable with two different threads at once please note I am rusty... I may be misunderstanding how this part works
I have placed test cases all over to see where the variable goes nuts and I am stumped.
Best Guess
All of my research confirms what I recall from years back; I likely am going out of bounds somewhere and causing stack corruption. I have looked at numerous other problems like this on google as well as on stack overflow and while all point me to the same conclusion I have been unable to figure out what specifically is wrong in my code.
#include<stdio.h>
//#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<conio.h>
//#include<unistd.h>
#define ESCAPE 27
int maxThreads = 10;
pthread_t tid[21];
int ret[21];
int threadIncoming[21];
int threadRunning[21];
struct arg_struct {
char* arg1;
int arg2;
};
//sick of the stupid upper/lowercase nonsense... boom... fixed
void* sleep(int time){Sleep(time);}
void* workerThread(void *arguments)
{
//get the stuff passed in to us
struct arg_struct *args = (struct arg_struct *)arguments;
char *address = args -> arg1;
int threadIndex = args -> arg2;
//hold how many we have processed - we are unlikely to ever hit the max so no need to round robin this number at this point
unsigned long processedCount = 0;
//this never triggers so it IS coming in correctly
if(threadIndex > 20){
printf("INIT ERROR! ThreadIndex = %d", threadIndex);
sleep(1000);
}
unsigned long x = 0;
pthread_t id = pthread_self();
//as long as we should be running
while(__atomic_load_n (&threadRunning[threadIndex], __ATOMIC_ACQUIRE)){
//if and only if we have something to do...
if(__atomic_load_n (&threadIncoming[threadIndex], __ATOMIC_ACQUIRE)){
//simulate us doing something
//for(x=0; x<(0xFFFFFFF);x++);
sleep(2001);
//the value going into sleep is CLEARLY somehow ending up in index because you can change that to any number you want
//and next thing you know the next line says "First thread processing done on (the value given to sleep)
printf("\n First thread processing done on %d\n", threadIndex);
//all done doing something so clear the incoming so we can reuse it for our next one
//this error should not EVER be able to get thrown but it is.... something is corrupting our stack and going into memory that it shouldn't
if(threadIndex > 20){ printf("ERROR! ThreadIndex = %d", threadIndex); }
else{ __atomic_store_n (&threadIncoming[threadIndex], 0, __ATOMIC_RELEASE); }
//increment the processed count
++processedCount;
}
else{Sleep(10);}
}
//no need to do atomocity I don't think for this as it is only set on the exit and not read till after everything is done
ret[threadIndex] = processedCount;
pthread_exit(&ret[threadIndex]);
return NULL;
}
int main(void)
{
int i = 0;
int err;
int *ptr[21];
int doLoop = 1;
//initialize these all to set the threads to running and the status on incoming to NOT be processing
for(i=0;i < maxThreads;i++){
threadIncoming[i] = 0;
threadRunning[i] = 1;
}
//create our threads
for(i=0;i < maxThreads;i++)
{
struct arg_struct args;
args.arg1 = "here";
args.arg2 = i;
err = pthread_create(&(tid[i]), NULL, &workerThread, (void *)&args);
if (err != 0){ printf("\ncan't create thread :[%s]", strerror(err)); }
}
//loop until we hit escape
while(doLoop){
//see if we were pressed escape
if(kbhit()){ if(getch() == ESCAPE){ doLoop = 0; } }
//just for testing - actual version would load only as needed
for(i=0;i < maxThreads;i++){
//make sure we synchronize so we don't end up pointing into a garbage address or half loading when a thread accesses us or whatever was going on
if(!__atomic_load_n (&threadIncoming[i], __ATOMIC_ACQUIRE)){
__atomic_store_n (&threadIncoming[i], 1, __ATOMIC_RELEASE);
}
}
}
//exiting...
printf("\n'Esc' pressed. Now exiting...\n");
//call to end them all...
for(i=0;i < maxThreads;i++){ __atomic_store_n (&threadRunning[i], 0, __ATOMIC_RELEASE); }
//join them all back up - if we had an actual worthwhile value here we could use it
for(i=0;i < maxThreads;i++){
pthread_join(tid[i], (void**)&(ptr[i]));
printf("\n return value from thread %d is [%d]\n", i, *ptr[i]);
}
return 0;
}
Output
Here is the output I get. Note that how long it takes before it starts going crazy does seem to possibly vary but not much.
Output Screen with Error
I don't trust your handling of args, there seems to be a race condition. What if you create N threads before the first one of them gets to run? Then the first thread created will probably see the args for the N:th thread, rather than for the first, and so on.
I don't believe there's a guarantee that automatic variables used in a loop like that are created in non-overlapping areas; after all they go out of scope with each iteration of the loop.
I am trying to add a new system call that displays some information about currently running processes in the system. I created a new struct named proc_info_struct that contains parts of the process information I want to display. Here is the proc_info_struct code defined in procinfo.h header file
#include <linux/types.h>
struct proc_info_struct
{
pid_t pid;
pid_t parn_pid;
pid_t gid;
unsigned long user_time;
unsigned long sys_time;
long state;
unsigned long long sched_avg_running;
unsigned int time_slice;
unsigned int policy;
unsigned long num_cxs;
int num_children;
char* prog;
};
In the system call method(shown below), I try to check if the process specified exists or not by using the kill() function defined in signal.h using this link as a reference. Here is the code which I use to get the process information:
#include <linux/procinfo.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <asm-generic/current.h>
#include <linux/signal.h>
void fill_proc_info(struct proc_info_struct *proc_info, struct task_struct *task)
{
int num_ch = 0;
struct list_head* list;
proc_info->pid = task->pid;
proc_info->parn_pid = (task->parent)->pid;
proc_info->gid = task->tgid;
proc_info->user_time = task->utime;
proc_info->sys_time = task->stime;
proc_info->state = task->state;
proc_info->sched_avg_running = task->cputime_expires.sum_exec_runtime; //average scheduled running time;
proc_info->policy = task->policy;
proc_info->time_slice = task->rt.time_slice;
proc_info->num_cxs = (task->nvcsw) + (task->nivcsw); //number of context switches(both voluntary and involuntary)
list_for_each(list, &task->children){
num_ch++;
}
proc_info->num_children = num_ch;
proc_info->prog = task->comm;
}
asmlinkage long sys_getprocinfo(pid_t pid, struct proc_info_struct *proc)
{
struct task_struct *task;
struct proc_info_struct *proc_info;
if(pid)
{
//current process
task = get_current();
fill_proc_info(proc_info, task);
}
else{
int exists = 0;//checks whether a process exists or not
for_each_process(task){
if(task->pid = pid){
exists = 1;
}
}
if(exists){
//task = find_task_by_vpid(pid); we don't need this line now since the task has now been set in for_each_process
fill_proc_info(proc_info, task);
}
else{
printk("Process doesn't exist");
return -ESRCH:
}
}
if (copy_to_user(proc, proc_info, sizeof(proc_info)))
return -EFAULT;
return 1;
}
When I try to build the kernel by using make I get the following error
As it can be seen above, I have included the signal.h header in the line:
#include <linux/signal.h>
What am I missing here? How is there an alternative way I can check if a given process exists in the system by using its pid other than kill function?
Edit:
Using the suggestions in the answer, I replaced the kill function call with for_each_process macro. Now it compiles successfully. I wrote a test code to test the system call. When I give a non-existing pid, the system call works correctly by displaying 'Process doesn't exist' in the kernel log. However, when I give an existing code, it raises the displays error in the kernel log:
BUG: unable to handle kernel NULL pointer dereference at (null)
The test code
int main()
{
struct proc_info_struct *proc_info;
pid_t pid = 0; //I tried
/;
syscall(314, pid, &proc_info);
printf("Pid: %ld\nParent: %ld\nGid:%ld\nUtime: %lu\nSysTime:
%d\nState: %lu\n,Time_Slice: %d\nPolicy: %d\nNum_CXS: %lu\nNumChild:
%d\nProg: %s\n",proc_info->pid, proc_info->parn_pid, proc_info->gid,
proc_info->user_time, proc_info->sys_time, proc_info->state, proc_info->time_slice,
proc_info->policy, proc_info->num_cxs, proc_info->num_children, proc_info->prog);
return 0;
}
Tsyvarev right. Linux kernel doesn't contain kill. But it contains sys_kill.
Also, you can look on my test project. There you can find the affl_kill_process() function which kills process.
Kernel code doesn't define user space functions like kill.
For search through processes you can try for_each_process macro, defined in <linux/sched.h>.
UPDATE: BTW, according to comments in your code, you used find_task_by_vpid for some purpose. This function just return task, which has given pid. Why do you not want to use it? Also, you can investigate implementation of the system call kill: how it searches needed task. This system call is defined in kernel/signal.c as SYSCALL_DEFINE2(kill,....
Also note, that searching task(in any form) and reading its fields should be performed within rcu_read_lock/rcu_read_unlock critical section. This protects tasks lists from element destruction during search.
Try adding
#define _POSIX_SOURCE
before all inclusions.