📖 18 dakika ↪ Yazılar

System Programming Notes

Unix Processess

When residing in memory, a user process is divided into three segments:

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

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);

operations are:

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);    }   }