{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "fb2efee8-a9e6-4254-a017-94905bb0aa63",
   "metadata": {},
   "source": [
    "<h1>Lab II: IPC and <tt>pthreads</tt> Library</h1>\n",
    "<hr>\n",
    "<center><b>INSTRUCTIONS</b></center>\n",
    "<ul>\n",
    "    <li>This lab requires you to complete 3 tasks. All <b>MUST be finished and\n",
    "        submitted before leaving the lab.</b></li>\n",
    "    <li>Write all your code in the cells provided below, compile and run the\n",
    "        programs inside this notebook and submit it.</li>\n",
    "    <li><b>Submission instructions</b>\n",
    "        <ul>\n",
    "            <li>Change the name of the notebook to &lt;roll number&gt;_Lab02</li>\n",
    "            <li>Email the notebook to <tt>chakravarthybhagvati@uohyd.ac.in</tt>\n",
    "                with the subject line as <b>Lab02 submission</b></li>\n",
    "        </ul>\n",
    "        <b style=\"color: #c00\">Your lab assignment may not be evaluated or\n",
    "            even considered submitted if you do not follow the submission \n",
    "            instructions exactly.</b>\n",
    "        </li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "269360d6-3f03-4b79-8905-c38281fececf",
   "metadata": {},
   "source": [
    "<hr />\n",
    "<h3>Task 1</h3>\n",
    "Write a program to do the following\n",
    "<ol>\n",
    "    <li>Opens a <tt>pipe</tt></li>\n",
    "    <li>Creates a child process</li>\n",
    "    <li>The parent process opens the file <tt>/etc/passwd</tt> and writes\n",
    "        it one line at time into the pipe</li>\n",
    "    <li>Once the contents of the file are completely written, the parent\n",
    "        process closes the pipe and waits for the child process to\n",
    "        terminate</li>\n",
    "    <li>The parent process prints the word <tt>Done!</tt> and then terminates\n",
    "        after the child process has terminated</li>\n",
    "    <li>The child process reads the pipe, and writes the contents on to the\n",
    "        terminal, prefixing each line with its line number and the word, \n",
    "        <tt>Child: </tt></li>\n",
    "    <li>The child process terminates when there is no more content to be read\n",
    "        from the pipe</li>\n",
    "</ol>\n",
    "Use the code stub given in the cell below.\n",
    "<p>Insert the required code and run the cell to save the contents into the file\n",
    "<tt>lab02_task1.c</tt>. <b>DO NOT CHANGE THE FIRST LINE</b> in the cell.</p>\n",
    "<p>Compile the code in the cell below the code cell and run it. Make sure you get the correct output.</p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "78c4b185-c3d4-45b4-bdeb-9529a1bfda3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%file lab02_task1.c\n",
    "#include <stdio.h>\n",
    "#include <stdlib.h>\n",
    "#include <unistd.h>\n",
    "#include <sys/types.h>\n",
    "#include <sys/wait.h>\n",
    "#include <fcntl.h>\n",
    "\n",
    "#define READ      0\n",
    "#define WRITE     1\n",
    "#define MAXLEN   80\n",
    "\n",
    "int main(int argc, char *argv[])\n",
    "{\n",
    "    int p[2], pid, lnum;\n",
    "    char buffer[MAXLEN];\n",
    "    FILE *fp;\n",
    "\n",
    "    /* Insert code to open pipe and check for error in opening it */\n",
    "\n",
    "    if ((pid = fork()) == 0) {                /* Child Process */\n",
    "        lnum = 1;                             /* For printing line numbers */\n",
    "        /* Insert code to read from pipe */\n",
    "        \n",
    "    } else {                                  /* Parent Process */\n",
    "        /* Open the file /etc/passwd for reading; check for errors */\n",
    "\n",
    "        /* Insert code for reading from the file and writing into the pipe */                                      \n",
    "\n",
    "        /* Be a good programmer and close all open files and descriptors */\n",
    "        close(p[WRITE]);\n",
    "        fclose(fp);\n",
    "        /* Wait for child to complete its job and terminate */\n",
    "        waitpid(pid, NULL, 0);\n",
    "\n",
    "        printf(\"Done!\\n\");\n",
    "    }\n",
    "\n",
    "    exit(0);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee076eab-8667-4510-88ea-aaa1811237b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "gcc lab02_task1.c -o lab02_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88e1bfb3-9d79-4802-84f3-db4e5e14aeee",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "./lab02_1 lab02_task1.c"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "904fc6a2-f9bc-454b-b6f9-39fb92a0604b",
   "metadata": {},
   "source": [
    "<hr>\n",
    "<h3>Task 2</h3>\n",
    "In this task, you will use a <tt>named pipe (FIFO)</tt> and see how it is\n",
    "similar as well as different from a file. Do the following\n",
    "<ol>\n",
    "    <li>Create a named pipe called &lt;your roll number&gt;_fifo using the\n",
    "        following command in a terminal\n",
    "        <center><tt>mknod &lt;your roll number&gt;_fifo p</tt></center></li>\n",
    "    <li>Write a program to read the contents of the named pipe in the cell\n",
    "        below. You can treat the named pipe exactly as a regular file\n",
    "        including the use of <tt>FILE *</tt> file pointer for opening it.</li>\n",
    "    <li>Save it by running the cell and compile it in the next cell\n",
    "        below it.</li>\n",
    "    <li>Open at least two terminals. In one terminal run your program by typing\n",
    "        <tt>./lab02_2</tt> in it. What happened?</li>\n",
    "    <li>Go to the other terminal and copy the file <tt>lab02_task1.c</tt>\n",
    "        to your named pipe. What happened now?</li>\n",
    "    <li>Repeat the above step to copy /etc/passwd again into your named pipe.\n",
    "        What happened now?</li>\n",
    "    <li>What is the size of your named pipe? Type <tt>ls -l</tt> for the\n",
    "        answer.</li>\n",
    "</ol>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d2b0bca-ec92-4989-adc0-c5d169450ecc",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%file lab02_task2.c\n",
    "#include <stdio.h>\n",
    "#include <stdlib.h>\n",
    "\n",
    "#define MAXLEN     80\n",
    "\n",
    "int main(void)\n",
    "{\n",
    "    FILE *mpp;\n",
    "    char buffer[MAXLEN];\n",
    "\n",
    "    /* Insert code to open the named pipe and read from it       */\n",
    "\n",
    "    /* Insert code to write the contents of the pipe to terminal */\n",
    "\n",
    "    fclose(mpp);                       /* We are good students!! */\n",
    "    exit(0);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b064a23d-ac93-4d33-abf8-7a0b84fb8e5a",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "gcc lab02_task2.c -o lab02_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b07d8bdb-ce6a-4f09-8f6a-577849fcc82e",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "./lab02_2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0cc6a460-76a5-4171-bb84-f3b23a6d131d",
   "metadata": {},
   "source": [
    "<hr />\n",
    "<h3>Task 3</h3>\n",
    "In this task, you will see how threads share the address space of the parent process and compare the results with those obtained with parent and child <em>processes.</em> For this task, you need to create three threads. Each thread will modify its variables and output them. Analyse the results to understand how threads work.\n",
    "<ol>\n",
    "    <li>Look at the code below that creates one thread from the main process.</li>\n",
    "    <li>Create two threads that call the function <tt>wfile</tt></li>\n",
    "    <li>Complete the <em>thread function</em> so that it writes into a file.</li>\n",
    "    <li>Create a third thread that runs the function <tt>chg_var()</tt>. See\n",
    "        how we modify the parameter passed to it. Understand it.</li>\n",
    "    <li>Once the program terminates, examine the file to see how the threads\n",
    "        write into the file.</li>\n",
    "    <li>Look at the values printed for the variables.</li>\n",
    "    <li>Run the program several times and see how the results change.</li>\n",
    "</ol>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c494c09-251c-4525-bd9a-01ca66d8f531",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%file lab02_task3.c\n",
    "#include <stdio.h>\n",
    "#include <stdlib.h>\n",
    "#include <pthread.h>\n",
    "#include <malloc.h>\n",
    "#include <string.h>\n",
    "\n",
    "#define MAXTHREADS     6\n",
    "\n",
    "void *wfile(void *), *chgvar(void *);\n",
    "char *extstring;\n",
    "\n",
    "void *wfile(void *wp)\n",
    "{\n",
    "    int i;\n",
    "\n",
    "    /* Insert code here to write 100 lines of text into the file given\n",
    "        by *wp */\n",
    "\n",
    "    return(NULL);\n",
    "}\n",
    "\n",
    "void *chg_var(void *rv)\n",
    "{\n",
    "    *(int *)rv = *(int *)rv * 7;          /* Ugly (or beautiful)! */\n",
    "\n",
    "    return(NULL);\n",
    "}\n",
    "\n",
    "int main(void)\n",
    "{\n",
    "    int regvar=25, i=0, j=0;\n",
    "    pthread_t tid[MAXTHREADS];\n",
    "    FILE *fp;\n",
    "\n",
    "    extstring = malloc(24);\n",
    "    strcpy(extstring, \"Hello, World!\");\n",
    "\n",
    "    /* Insert code here to open a file \"thread_outputs.txt\" for writing */\n",
    "\n",
    "    /* Code to create a single thread running the funtion wfile.\n",
    "        Modify the code to create two threads */\n",
    "    if ((pthread_create(&tid[i++], NULL, wfile, (void *)fp)) != 0) {\n",
    "        printf(\"Error in creating the first thread\\n\");\n",
    "        exit(1);\n",
    "    }\n",
    "\n",
    "    /* Create a third thread here to run the function chg_var */\n",
    "\n",
    "    /* Let us wait for all threads to return */\n",
    "    while (j < i) {\n",
    "        pthread_join(tid[j++], NULL);\n",
    "    }\n",
    "    printf(\"Regvar: %d\\tExtvar: %s\\n\", regvar, extstring);\n",
    "    fclose(fp);\n",
    "    exit(0);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e556b6b1-14d0-42b5-93b5-1ae36b0f6066",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "gcc lab02_task3.c -o lab02_3 -lpthread"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "149f68a7-794d-4f99-9b50-19cddd347c53",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "./lab02_3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3e0e902-6200-44ad-84e3-c7ea21595eec",
   "metadata": {},
   "source": [
    "<hr />\n",
    "<center>THE END</center>\n",
    "<hr />"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
