Unix Processess
- User space: the space where the user processes will run (in user mode)
- Kernel space: the space where the kernel executes
When residing in memory, a user process is divided into three segments:
- Text segment: contains the executable program code and constant data
- Data segment: contains the initialized data and uninitialized data segments
- Stack segment: used by the process for storage of variables.
Fork Process are created by fork system call. If it fails returns -1.
Example Code:
void main( void ){
int i;
printf("Initp PID %6d PPID %6d GID %6d",
getpid(), getppid(), getpgid(0));
for (i = 0; i < 3; ++i)
if (fork( ) == 0) /* Generate some processes */
printf("Newproc PID %6d PPID %6d GID %6d",
getpid(), getppid(), getpgid(0)); }
Another Example About Fork
main(){
int c = fork();
printf("Hello World\n"); // Expected OUTPUT 2x "Hello World"
return 0; }
There is no system call to learn about the process ids of the children. Hence, a parent should save the child pid returned from the fork call if it is going to use it future.
ARGV
Part of the processing environment of every process are the values passed to the process in the main function. These values can be from the command line or may be passed to a child process from the parent via an exec system call. These values are stored in an array called argv. Number of elements in argv in argc
void main(int argc, char *argv[]){
for ( ; *argv; ++argv ) printf("%s\n", *argv); }
execlp
int main(int argc, char *argv[ ]){
if (argc > 1) {
execlp("/bin/cat", "cat", argv[1], (char *) NULL);
perror("exec failure "); exit(1); }
fprintf(stderr, "Usage: %s text_file\n", *argv); }
execvp
Execvp runs another program but original program exit so after this call, does not matter how many opcode exist program doesn’t run them.
int main(int argc, char *argv[]){ execvp(argv[1], &argv[1]); }
Pipes
Transferring data in between childs and parents. Signals
- SIGUSR1 and SIGUSR2 are freely available to the user processes.
- They are relatively expensive (kernel must interrupt the receiver)
- They have limited bandwidth (there are only 31 or a few more)
- They are good for event notifications but inefficient for complicated interactions.
Unnamed Pipes Example code for pipe communication:
main(int argc, char *argv[ ]) {
int f_des[2];
static char message[BUFSIZ];
pipe(f_des);
switch( fork() ){
case 0: // The child
close(f_des[1]);
read(f_des[0], message, BUFSIZ);
printf("Message received by child: [%s]\n", message);
fflush(stdout);
break;
default: // In the Parent
write(f_des[1], argv[1], strlen(argv[1]))
printf("Message sent by parent : [%s]", argv[1]);
fflush(stdout); }
exit(0); }
When dup2 is called, the file descriptor referenced by filedes will be a duplicate of the file descriptor
Named Pipes
The main difference introduced is that the named pipes have a directory entry. This facilitates the use of pipe by other processes and file access permissions are also assigned.
Header File
#define PUBLIC “/tmp/PUBLIC”
#define B_SIZ (PIPE_BUF / 2)
struct message {
char fifo_name[B_SIZ];
char cmd_line[B_SIZ]; };
Client File
void main( void ){
int n, privatefifo, publicfifo;
static char buffer[PIPE_BUF];
// Make the name for the private FIFO
sprintf(msg.fifo_name, "/tmp/fifo%d", getpid( ));
mknod(msg.fifo_name, S_IFIFO | 0666, 0); // Generate the priv FIFO
publicfifo = open(PUBLIC, O_WRONLY)); //OPEN pub FIFO for writing
while ( 1 ) { // FOREVER
write(fileno(stdout), "\ncmd>", 6); // prompt
memset(msg.cmd_line, 0x0, B_SIZ); // clear first
n = read(fileno(stdin), msg.cmd_line, B_SIZ); // Get command
if (!strncmp("quit", msg.cmd_line, n - 1)) // EXIT ?
break;
write(publicfifo, (char *) &msg, sizeof(msg)); // to PUBLIC
// OPEN private FIFO to read returned command output
privatefifo = open(msg.fifo_name, O_RDONLY)) == -1);
// READ private FIFO and display on standard error
while ((n = read(privatefifo, buffer, PIPE_BUF)) > 0) {
write(fileno(stderr), buffer, n); }
close(privatefifo); }
close(publicfifo);
unlink(msg.fifo_name);
Server File
main(){
int n, done, dummyfifo, publicfifo, privatefifo;
// Generate the public FIFO
mknod(PUBLIC, S_IFIFO | 0666, 0);
// OPEN public FIFO for reading and writing
publicfifo = open(PUBLIC, O_RDONLY));
dummyfifo = open(PUBLIC, O_WRONLY | O_NDELAY));
// message can be read from the PUBLIC pipe
while (read(publicfifo, (char *) &msg, sizeof(msg)) > 0) {
n = done = 0; // clear counters / flags
do { // try OPEN of private FIFO
if ((privatefifo = open(msg.fifo_name, O_WRONLY|O_NDELAY))==-1)
sleep(3); // sleep a while
else { // OPEN successful
fin = popen(msg.cmd_line, "r"); // execute the command
write(privatefifo, "\n", 1); // keep output pretty
while ((n = read(fileno(fin), buffer, PIPE_BUF)) > 0) {
write(privatefifo, buffer, n); // to private FIFO
memset(buffer, 0x0, PIPE_BUF); } // clear between times
pclose(fin); close(privatefifo);
done = 1; } // record success
} while (++n < 5 && !done);
if (!done) // Indicate failure
write(fileno(stderr),
"\nNOTE: SERVER ** NEVER ** accessed private FIFO\n", 48); }
} //End of While ^
Signals
Signals provide a mechanism for notifying processes of system events. They also function as a primitive mechanism for communication and synchronization between user processes.
int main(void) {
int i;
void signal_catcher(int); // Prototype of signal_catcher func
if (signal(SIGINT , signal_catcher) == SIG_ERR) {
perror("SIGINT"); exit(1); }
if (signal(SIGQUIT , signal_catcher) == SIG_ERR) {
perror("SIGQUIT"); exit(2); }
for (i = 0; ; ++i) { /* Forever.*/
printf("%i\n", i); /* display a number */ sleep(1); } }
void signal_catcher(int the_sig){
signal(the_sig, signal_catcher); /* reset */
printf("\nSignal %d received.\n", the_sig);
if (the_sig == SIGQUIT) exit(3); } //end of func
Output:
% a.out
0
^C
Signal 2 received
1
^\
Signal 3 received
3
Message Queues
Example Message Queues
local.h
#define SEED ‘g’ /* seed for ftok */
#define SERVER 1L /* message for the server */
typedef struct {
long msg_to; /* Placed in the queue for */
long msg_fm; /* Placed in the queue by */
}MESSAGE;
Client.c
main(void)
{
key_t key;
pid_t cli_pid;
int mid, n;
MESSAGE msg;
static char m_key[10];
cli_pid = getpid();
key = ftok(".", SEED);
if ((mid=msgget(key, 0 )) == -1 ) {
mid = msgget(key,IPC_CREAT | 0660);
switch (fork()) {
case 0:
sprintf(m_key, "%d", mid);
execlp("server", "server", m_key, "&", 0);
perror("Client: exec"); exit(4); } }
while (1) {
msg.msg_to = SERVER;
msg.msg_fm = cli_pid;
write(fileno(stdout), "cmd>", 6);
memset(msg.buffer, 0x0, BUFSIZ);
n = read(fileno(stdin), msg.buffer, BUFSIZ);
if (n == 0 ) break;
msgsnd(mid, &msg, sizeof(msg), 0);
n=msgrcv(mid, &msg, sizeof(msg), cli_pid, 0);
write(fileno(stdout), msg.buffer, strlen(msg.buffer));
msgsnd(mid, &msg, 0, 0); exit(0); }
Server.c
main(int argc, char *argv[ ]) {
int mid, n;
MESSAGE msg;
void process_msg(char *, int);
mid = atoi(argv[1]);
while (1) {
if ((n=msgrcv(mid, &msg, sizeof(msg), SERVER, 0)) == -1 ) {
perror("Server: msgrcv"); exit(2);
} else if (n == 0) break; else {
process_msg(msg.buffer, strlen(msg.buffer));
msg.msg_to = msg.msg_fm;
msg.msg_fm = SERVER;
if (msgsnd(mid, &msg, sizeof(msg), 0) == -1 ) {
perror("Server: msgsnd"); exit(3); } } }
msgctl(mid, IPC_RMID, (struct msqid_ds *) 0 );
exit(0); }
void process_msg(char *b, int len) {
int i;
for (i = 0; i < len; ++i)
if (isalpha(*(b + i)))
*(b + i) = toupper(*(b + i)); }
Semaphores
Funcs: wait(), signal(). To create a semaphore or gain access to one that exists, the semget system call is used.
int semget(key_t key, int numberofsems, int semflg);
The semctl system call allows the user to perform a variety of generalized control operations on the system semaphore structure.
int semctl(int semid,int semnum,int cmd,/*union semun arg */);
cmd -> SETALL
semunarg -> {NUM,0}
Shared Memory
Shared memory allows multiple processes to share virtual memory space. The shmget system call is used to create the shared memory.
Funcs:
shmget(key, 1000, 0644|IPC_CREAT)) // Create a shared memory
according to key if there is one memory address exist attach
shmget(IPC_PRIVATE, 20, 0644) // Always create a new shared memory
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
- shmid is a valid shared memory segment identifier
- cmd specifies the operation
- buf reference to a structure of type shmid_ds
operations are:
- IPC_STAT: return the current values of shmid_ds
- IPC_SET: modify permissions
- IPC_RMID: remove shared memory
- SHM_LOCK: lock shared memory
- SHM_UNLOCK: unlock shared memory
The system call shmat is used to attach the
void *shmat(int shmid,void *shmaddr,int shmflg);
int shmdt(void *shmaddr); // return SUCCESS -> 0
shmctl(shmid, IPC_RMID, 0); // Delete shared memory
Example -> Producer Consumer Problem
local.h
// local.h - common header file for parent.c, producer.c consumer.c
#define ROWS 5
#define COLS 3
#define SLOT_LEN 50
#define N_SLOTS 6
union semun {
int val;
struct semid_ds *buf;
ushort *array; };
struct MEMORY {
char buffer[N_SLOTS][SLOT_LEN];
int head, tail; };
struct sembuf acquire = { 0, -1, SEM_UNDO},
release = { 0, 1, SEM_UNDO};
enum {AVAIL_SLOTS, TO_CONSUME};
parent.c
main(int argc, char *argv[]){
static
struct MEMORY memory;
static ushort start_val[2] = {N_SLOTS, 0};
int semid, shmid, croaker;
char *shmptr;
pid_t p_id, c_id, pid = getpid( );
union semun arg;
memory.head = memory.tail = 0; //Create attch init memory segment
shmid=shmget((int)pid, sizeof(memory),IPC_CREAT|0600)); // Create
shmptr=(char *)shmat(shmid, 0, 0));
memcpy(shmptr, (char *)&memory, sizeof(memory)); /* initialize */
/* Create and initialize the semaphores */
semid=semget((int)pid, 2, IPC_CREAT | 0666));
arg.array = start_val;
semctl(semid, 0, SETALL, arg);
if ( (p_id=fork( )) == 0) /* Fork the producer process */
execl( "producer", "producer", argv[1], (char *) 0);
c_id =fork(); /* Fork the consumer process */
if ( c_id == 0 ) {
execl( "consumer", "consumer", argv[2], (char *) 0);
perror("execl -- consumer "); exit(8); }
croaker = (int) wait( (int *) 0 );
/* wait for one to die */
kill( (croaker == p_id ) ? c_id : p_id, SIGKILL);
/* remove other */
shmdt( shmptr );
/* detach */
shmctl( shmid, IPC_RMID, (struct shmid_ds *) 0);
/* remove */
semctl( semid, 0, IPC_RMID, 0); exit(0); }
producer.c
main(int argc, char *argv[]) {
static char *source[ROWS][COLS] = {
{"A", "The", "One"},
{" red", " polka-dot", " yellow"},
{" spider", " dump truck", " tree"},
{" broke", " ran", " fell"},
{" down", " away", " out"} };
static char local_buffer[50];
int i, r, c, sleep_limit, semid, shmid;
pid_t ppid = getppid( );
char *shmptr;
struct MEMORY *memptr;
/* Access, attach and reference the shared memory */
if ((shmid=shmget((int) ppid, 0, 0)) != -1 ){
if((shmptr=(char *)shmat(shmid, (char *)0, 0))==(char *)-1){
perror("shmat -- producer -- attach "); exit(1); }
memptr = (struct MEMORY *) shmptr;
} else { perror("shmget -- producer -- access ");
exit(2);
} /* Access the semaphore set */
if ( (semid=semget((int) ppid, 2, 0)) == -1 ) {
perror("semget -- producer -- access ");
exit(3); }
sleep_limit = atoi(argv[1]) % 20;
i = 20 - sleep_limit;
srand((unsigned)getpid());
while( i-- ) {
memset(local_buffer, '\0', sizeof(local_buffer));
for (r = 0; r < ROWS; ++r) {
/* Make a random string */
c = rand() % COLS; strcat(local_buffer, source[r][c]); }
acquire.sem_num = AVAIL_SLOTS;
if (semop(semid, &acquire, 1 ) == -1 ){
perror("semop -- producer -- acquire "); exit(4); }
strcpy(memptr->buffer[memptr->tail], local_buffer);
printf("P:[%d]%s.",memptr->tail,memptr->buffer[memptr-tail]);
memptr->tail = (memptr->tail +1) % N_SLOTS;
release.sem_num = TO_CONSUME;
if (semop( semid, &release, 1 ) == -1 ) {
perror("semop -- producer -- release "); exit(5); }
sleep( rand( ) % sleep_limit + 1 ); }
exit(0); }
Socket
Stream: Reliable, Allow full-duplex communication, Connection oriented
Datagram: Unreliable, Allow full-duplex communication, Connectionless
UDP(User Datagram Protocol) Echo Request-Reply Server.c
// Server side implementation of UDP client-server model
#define PORT 8080
#define MAXLINE 1024
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
// Creating socket file descriptor
sockfd = socket(AF_INET, SOCK_DGRAM, 0));
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// Bind the socket with the server address
bind(sockfd,(const struct sockaddr *)&servaddr, sizeof(servaddr));
int len, n;
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, ( struct sockaddr *) &cliaddr, &len);
buffer[n] = '\0';
printf("Client : %s\n", buffer);
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &cliaddr, len);
printf("Hello message sent.\n");
return 0; }
Client.c
#define PORT 8080
#define MAXLINE 1024
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from client";
struct sockaddr_in servaddr;
// Creating socket file descriptor
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n, len;
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM,(const struct sockaddr*)&servaddr,sizeof(servaddr));
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, (struct sockaddr *) &servaddr, &len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd); return 0; }
PF UNIX SOCKET
#define BUF_SZ 10
main(void) {
int sock[2], // The socket pair
cpid, i;
static char buf[BUF_SZ]; // Temporary buffer for message
socketpair(PF_UNIX, SOCK_STREAM, 0, sock);
switch (cpid = (int) fork()) {
case 0: // The child process
close(sock[1]);
for (i = 0; i < 10; i += 2) { sleep(1);
sprintf(buf, "c: %d\n", i);
write(sock[0], buf, sizeof(buf));
read(sock[0], buf, BUF_SZ);
printf("c-> %s", buf); } // Message from parent
close(sock[0]); break;
default: // The parent process
close(sock[0]);
for (i = 1; i < 10; i += 2) { sleep(1);
read(sock[1], buf, BUF_SZ);
printf("p-> %s", buf); // Message from child
sprintf(buf, "p: %d\n", i);
write(sock[1], buf, sizeof(buf));
} close(sock[1]);
} return 0; }
TCP Transmission Control Protocol/Internet Protocol)
server.c
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
// Function designed for chat between client and server.
void func(int sockfd) {
char buff[MAX]; int n;
for (;;) { // infinite loop for chat
// read the message from client and copy it in buffer
bzero(buff, MAX);
// print buffer which contains the client contents
read(sockfd, buff, sizeof(buff));
printf("From client: %s\t To client : ", buff);
bzero(buff, MAX); n = 0;
while ((buff[n++]=getchar())!='\n');//copy server msg to buffer
write(sockfd, buff, sizeof(buff));//and send that buffer to client
// if msg contains "Exit" then server exit and chat ended.
if (strncmp("exit", buff, 4) == 0) break; } } // "Server Exit."
int main(){
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n"); exit(0); }
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n"); exit(0); }
else
printf("Socket successfully binded..\n");
// Now server is ready to listen and verification
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n"); exit(0); }
else
printf("Server listening..\n");
len = sizeof(cli);
// Accept the data packet from client and verification
connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("server acccept failed...\n"); exit(0); }
else
printf("server acccept the client...\n");
// Function for chatting between client and server
func(connfd);
// After chatting close the socket
close(sockfd); }
client.c
// Write CPP code here
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
void func(int sockfd) {
char buff[MAX];
int n;
for (;;) {
bzero(buff, sizeof(buff));
printf("Enter the string : ");
n = 0;
while ((buff[n++] = getchar()) != '\n');
write(sockfd, buff, sizeof(buff));
bzero(buff, sizeof(buff));
read(sockfd, buff, sizeof(buff));
printf("From Server : %s", buff);
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit...\n"); break; } } }
int main(){
int sockfd, connfd;
struct sockaddr_in servaddr, cli;
// socket create and varification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
// connect the client socket to server socket
connect(sockfd, (SA*)&servaddr, sizeof(servaddr));
printf("connected to the server..\n");
func(sockfd); // function for chat
close(sockfd); } // close the socket
Thread
#define N 10
void *T( void *id ){
double width, xcoord, ycoord, myArea;
int me=(int)id;
myArea=0.0;
width = (double) 1/ (double)N;
xcoord = (double) me * width;
ycoord = 4.0/((double)(1.0+(xcoord*xcoord)));
printf("I am %d my x: %g my y: %g \n", me, xcoord, ycoord);
myArea = (double) width * ycoord;
printf("I am %d %u myArea %g \n", me, pthread_self(),myArea);
pthread_exit((void *)&myArea); }
int main() {
pthread_t tid[N+1];
double totalArea , *threadArea_pt;
int i;
totalArea=0.0;
for(i=1; i<=N; i++)
pthread_create(&tid[i], NULL, (void *) T, (void *)i);
for(i=1; i<=N; i++){
pthread_join(tid[i], (void **)&threadArea_pt);
printf(" received thread id: %u \n", tid[i]);
totalArea += *threadArea_pt;
printf(" thread %d area %g\n", i, *threadArea_pt); }
printf(" Total area %g", totalArea); }
Thread based echo server.c
main() {
int listenfd, connfd;
int len;
/* Start the usual way */
listenfd = Socket(…);
Bind(listenfd, …);
Listen(listenfd, …)
for ( ; ; ) {
len = addrlen;
connfd = Accept(listenfd, …);
/* Create a thread in service_func routine */
Pthread_create(NULL, NULL, service_func, (void *) connfd); } }
void * service_func(void *arg) {
int local_connfd;
/* release parent from waiting */
Pthread_detach(pthread_self());
/* extract connfd from argument */
local_connfd = (int) arg;
/* receive and echo client’s message */
str_echo(local_connfd);
/* Terminate the connection */
Close(local_connfd); return(NULL); }
client.c
int sockfd;
FILE *fp;
main() {
pthread_t tid;
fp = fopen(…);
/* Start the usual way */
sockfd = Socket(…);
Connect(…);
/* Create a thread to send data */
Pthread_create(&tid, NULL, write_func, NULL);
/* read data from sockfd */
read_func();
/* wait for child thread */
Pthread_join(tid, NULL); }
void * write_func(void *arg) {
char sendline[MAXLINE];
while( more data in fp )
Read from fp into sendline[];
write sendline[] into sockfd;
Shutdown(sockfd, SHUT_WR);
return(NULL); }
void read_func() {
char recvline[MAXLINE];
while ( more data from sockfd )
read from sockfd into recvline[];
write from recvline[] to stdout; }
HostbyName
main() { // Checking host entries
struct hostent *host;
static char who[10];
printf("Enter host name to look up: ");
scanf("%10s", who);
host = gethostbyname( who );
if ( host != (struct hostent *) NULL ) {
printf("Here is what I found about %s :\n", who);
printf("Official name : %s\n", host->h_name);
printf("Aliases : ");
while ( *host->h_aliases ) {
printf("%s ", *host->h_aliases );
++host->h_aliases; }
printf("\nAddress type : %i\n", host->h_addrtype);
printf("Address length: %i\n", host->h_length);
printf("Address list : ");
while ( *host->h_addr_list ) {
struct in_addr in;
memcpy( &in.s_addr, *host->h_addr_list, sizeof (in.s_addr) );
printf("[%s] = %s ", *host->h_addr_list, inet_ntoa(in));
++host->h_addr_list; }
printf("\n"); } }
Daytime client (TCP)
int main(int argc, char **argv) {
int sockfd, n;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
if( argc != 2 )err_quit(“usage : gettime <IP address>”);
/* Create a TCP socket */
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
/* Specify server’s IP address and port */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13); /* daytime server port */
inet_pton(AF_INET, argv[1], &servaddr.sin_addr)
/* Connect to the server */
connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
/* Read the date/time from socket */
while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; /* null terminate */
printf(“%s”, recvline); }
if (n < 0) err_sys("read error");
close(sockfd); }
Daytime server (TCP)
int main(int argc, char **argv) {
int sockfd, n;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
if( argc != 2 )err_quit(“usage : gettime <IP address>”);
/* Create a TCP socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0); // Specify srv IP & port
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13); /* daytime server port */
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
/* Connect to the server */
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
/* Read the date/time from socket */
while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; /* null terminate */
printf(“%s”, recvline); }
if (n < 0) err_sys("read error");
close(sockfd); }
Daytime Client(UDP)
int main(int argc, char **argv) {
int sockfd, n, servlen;
char req[10], recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
if(argc != 2) err_quit(“usage : gettime <IP address>”);
/* Create a UDP socket */
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
/* Specify server’s IP address and port */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13); /* daytime server port */
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
/* Send message to server requesting date/time */
strcpy(req, “GET_TIME”);
Sendto(sockfd, req, strlen(req), 0, (struct sockaddr *)&servaddr,
/* Read date/time from the socket */
servlen = sizeof(servaddr);
n= Recvfrom(sockfd, recvline, MAXLINE, 0,
(struct sockaddr *)&servaddr ,&servlen);
recvlen[n] = 0; printf(“%s”, recvlen); close(sockfd); }
Daytime Server(UDP)
int main(int argc, char **argv) {
int sockfd, clilen;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE], req[REQ_LEN]; time_t ticks;
/* Create a socket */
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
/* Initialize server’s address and well-known port */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(13); /* daytime server */
/* Bind server’s address and port to the socket */
Bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
for ( ; ; ) { /* Wait for client request */
len = sizeof(cliaddr);
n = Recvfrom( sockfd, req, REQ_LEN, 0, &cliaddr, &clilen);
/* Retrieve the system time */
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
/* Send to client*/
Sendto(sockfd, buff, strlen(buff), 0, &cliaddr, clilen); } }
Thread Vize
int A[10]={1,2,3,14,5,6,7,8,9,10}; int B[10];
main() {
int p1[2], p2[2], i, max,m; pipe(p1); pipe(p2);
switch( fork() ) {
case 0: // In the child
close(p1[1]); // close unneeded ends
close(p2[0]);
read(p1[0],&B[0], 10*sizeof(int)); // read from parent
max=B[0];
for (i=0;i<10;i++) // find max
if (B[i]>max)
max=B[i];
write(p2[1], &max, sizeof(int)); // write max to parent
break;
default: // This is parent
close(p1[0]); // close unneeded ends
close(p2[1]);
write(p1[1], &A[0], 10*sizeof(int)); // send array to child
read(p2[0], &m, sizeof(int)); // read max
printf("\n %d",m); } }// print max
Simpler Shared Memory
#define SHM_SIZE 30
extern etext, edata, end;
main(void) {
pid_t pid; int shmid; char c, *shm, *s;
shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666));
shm = (char *) shmat(shmid, 0, 0)); printf("Addresses in parent");
printf("shmem: %X etext: %X edata: %X end: %X", shm, &etext, &edata, &end);
s = shm; /* s now references shared mem */
for (c = 'A'; c <= 'Z'; ++c) /* put some info there */ *s++ = c;
*s = NULL; /* terminate the sequence */
printf("In parent before fork, memory is : %s \n", shm);
switch ( fork() ) {
default : sleep(5);
printf("\nIn parent after fork, memory is : %s\n" , shm);
printf("Parent removing shared memory\n");
shmdt(shm); shmctl(shmid, IPC_RMID, 0); exit(0);
case 0 :
printf("In child after fork, memory is : %s \n" , shm);
for (; *shm; ++shm) /* modify shared memory */
*shm += 32; shmdt(shm); exit(0); } }