implemented sculls successfully at the application level……it took some time but was worth it
implemented sculls successfully at the application level……it took some time but was worth it
i have checked in general that if we take
void* data; and then do data=(char*)malloc(sizeof(char)); then it gives no warning
but if we take void** data; and then i do
data=(char**)malloc(sizeof(char*));
then it gives a warning of incompatible pointer assignment…..help required here plzz post if anybody knows why
I am trying to make a Makefile which can accept an a c file name as an argument to be used as a variable in my script so that i can use it with any of my c files for compilation .
the content of Makefile as follows..
#!/bin/bash
x=$1
exec: ${x}.o
gcc -o exec ${x}.o
${x}.o: ${x}.c
gcc -c ${x}.o ${x}.c
it is not executing properly as the final executable file is not exec but the with the same name as that of the c file name..i think its using the default makefile to create the executable file .
am i doing it right ?????what is the right make command (to be given) to execute this script…
whenever i execute server every time i need to change the port no.
if i don’t change its sayin “bind: address in use”..?????
I could scuccesfully implement read & write for a single item
Implememted multiple quantums writing and reading successfully.
driver is registered when i tried it in single file…
but when i split the file in start.o and stop.o then it gives error ” -1 file exist “
my progranm of simple device driver is correct… but when i give make command it generate following errors…
make -C /lib/modules/3.2.2-1.fc16.i686/build M=/home/nishu/Documents/device_driver modules
make: *** /lib/modules/3.2.2-1.fc16.i686/build: No such file or directory. Stop.
make: *** [default] Error 2
.
.
Implemented driver again…
implemented sockets using iNET and able to chat between two systems..
implemented sockets ,thread and simple implementation of device-drivers
implemented 1st lkm….
and chatting on 2 pc using inet….multiple client server using UNIX ….. and threads….
LINUX implements through the fork() and exec() system calls an elegant two-step mechanism for process creation and execution.
This separation allows to perform some interesting housekeeping actions in between, as we’ll see in the following lectures.
A call to fork() of the form:
#include <unistd.h> pid_t fork(void);
Return Value:
On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.
Errors:
It will creates (if it succeeds) a new process, which a child of the caller’s, and is an exact copy of the (parent) caller itself. By exact copy we mean that it’s image is a physical bitwise copy of the parent’s (in principle, they do not share the image in memory: though there can be exceptions to this rule, we can always thing of the two images as being stored in two separate and protected address spaces in memory, hence a manipulation of the parent’s variables won’t affect the child’s copies, and vice versa). The only visible differences are in the PCB, and the most relevant (for now) of them are the following:
The two processes obviously have two different process id.s. (pid). In a C program process id.s are conveniently represented by variables of pid_t type, the type being defined in the sys/types.h header.
The fork() call returns in both the parent and the child, and both resume their execution from the statement immediately following the call. One usually wants that parent and child behave differently, and the way to distinguish between them in the program’s source code is to test the value returned by fork(). This value is 0 in the child, and the child’s pid in the parent. Since fork() returns -1 in case the child spawning fails, a catch-all C code fragment to separate behaviours may look like the following:
#include <sys/types.h> #include <stdlib.h> #include <errno.h> #include <stdio.h> int main() { pid_t childpid; childpid=fork(); switch(childpid) { case -1: fprintf(stderr,"ERROR: %s\n", sys_errlist[errno]); exit(1); break; case 0: /* Child's code goes here */ printf(“ Child: My id is: %d and my parents id is: %d\n”,getpid(),getppid()); break; default: printf(“ Parent: My id is: %d and my child id is: %d\n”,getpid(),childpid); break; }
Note that a child (i.e. a process whatsoever, since they are all children of some other process, with the exception of processes 0, swapper and 1, init) cannot use the value returned by fork() to know its pid, since this is always 0 in the child. A system call named getpid() is provided for this purpose, and another one, named getppid() is used to ask the system about the parent’s id. Both functions take no arguments and return the requested value in pid_t type, or -1 in case of failure.
In the above program , a system call to exit() is made in case of failure, which causes the program to abort . We’ll see later that the exit() call returns the lower 8 bits of its argument (1, in the above example) to a waiting parent process, which can use them to determine the child’s exit status and behave accordingly. The usual convention is to exit with 0 on correct termination, and with a meaningful (for the parent) error code on abort.
It is often the case that a parent process must coordinate its actions with those of its children, maybe exchanging with them various kind of messages. UNIX defines several sophisticated inter-process communication (IPC) mechanisms, the simplest of which is a parent’s ability to test the termination status of its children. A synchronization mechanism is provided via the wait() system call, that allows a parent to sleep until one of its children exits, and then get its exit status. This call actually comes in three flavors,
General Syntax of wait() system call is:
#include<sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
The wait function suspends execution of the current process until a child has exited, or until a signal is delivered whose action is to terminate the current process or to call a signal handling function. If a child has already exited by the time of the call (a so-called “zombie” process), the function returns immediately. Any system resources used by the child are freed.
Return Value:
The process ID of the child which exited, or zero if WNOHANG was used and no child was available, or -1 on error (in which case errno is set to an appropriate value).
Errors:
Here’s an example call to wait(): a program spawns two children, then waits for their completion and behaves differently according to which one is finished. Try to compile and execute it (no need to type: you can cut and paste from your web browser…).
#include <sys/types.h> #include <sys/wait.h> #include <stdio.h> int main(int argc, char *argv[]) { pid_t whichone, first, second; int howmany; int status; if ((first=fork())==0) /* Parent spawns 1st child */ { printf("Hi, I am the first child, and my id is %d\n",getpid()); sleep(10); /* Sleep 10 sec, then exit */ exit(0); } else if (first == -1) { perror("1st fork: something went bananas\n"); exit(1); } else if ((second=fork())==0) /* Parent spawns 2nd child */ { printf("Hiya, I am the second child, and my id is %d\n",getpid()); sleep(15); /* Sleep 15 sec, then exit */ exit(0); } else if (second == -1) { perror("2nd fork: something went bananas\n"); exit(1); } printf("This is the parent\n"); howmany=0; while (howmany < 2) /* Wait twice */ { whichone=wait(&status); howmany++; if (whichone==first) printf("First child exited "); else printf("Second child exited "); if ((status & 0xffff)==0) printf("correctly\n"); else printf("uncorrectly\n"); } return 0; }
The parent enters into the loop; waiting for the children’s completion. The wait() system call blocks the caller process until one of its immediate children (not children’s children, or other siblings) terminates, and then returns the pid of the terminated process. The argument to wait() is the address on an integer variable or the NULL pointer. If it’s not NULL, the system writes 16 bits of status information about the terminated child in the low-order 16 bits of that variable. Among these 16 bits, the higher 8 bits contain the lower 8 bits of the argument the child passed to exit() while the lower 8 bits are all zero if the process exited correctly, and contain error information if not (see the wait(2) man page for details). Hence, if a child exits with 0 all those 16 bits are zero. To reveal if this is actually the case we test the bitwise AND expression (status & 0xffff), which evaluates as an integer whose lower 16 bits are those of status, and the others are zero. If it evaluates to zero, everything went fine, otherwise some trouble occurred. Try changing the argument passed to exit() in one of the children.
The Posix and BSD extensions to wait() are useful when a parent must not block waiting for children, but still wants to know about the children’s termination status values via the wait mechanism. We’ll treat only the Posix waitpid() call, and you are referred to the man page for the BSD call.
The waitpid() call is declared as follows in the sys/wait.h header:
pid_t waitpid(pid_t pid, int *statptr, int options);
Here the meaning of the the return value and of the pointer to the status statptr is exactly the same in wait(). However this call allows to specify which children should be waited for and how. Specifically, the first argument pid specifies the process(es) that must be waited for. The relevant (for now) cases are:
The relevant (for now) value for the third argument is a constant called WNOHANG, that causes the function not to suspend the caller’s execution if status is not immediately available for one of the child processes. This allows to implement a loop in which the parent can do something useful and periodically poll the children’s status as well.
Sources