Skip to content

Instantly share code, notes, and snippets.

@tejasri-v
Created December 30, 2021 04:02
Show Gist options
  • Save tejasri-v/2c730ba776a14e327c21e5c412f43fca to your computer and use it in GitHub Desktop.
Save tejasri-v/2c730ba776a14e327c21e5c412f43fca to your computer and use it in GitHub Desktop.
Lab5
Part 1: Remote access to mdb-lookup-cs3157 using netcat (100 points)
---------------------------------------------------------------------
(a)
You learned in class how to use a named pipe (aka FIFO) and the netcat
(nc) program to turn mdb-lookup-cs3157 into a network server.
mkfifo mypipe
cat mypipe | nc -l some_port_num | /some_path/mdb-lookup-cs3157 > mypipe
Write a shell script that executes the pipeline.
- The name of the script is "mdb-lookup-server-nc.sh"
- A shell script starts with the following line (the '#' is the 1st
character without any leading space):
#!/bin/sh
And the line must be the VERY FIRST LINE in the script.
- You must make the file executable using "chmod" command.
- The script takes one parameter, port number, on which nc will
listen.
- The script should create a named pipe named mypipe-<pid>, where
<pid> indicates the process ID of the shell running the script. The
named pipe should be removed at the end of the script.
- See section 3.4 in the Bash Reference Manual
(http://www.gnu.org/software/bash/manual/bashref.html) for how to
refer to the arguments and the process ID from your script.
- Because the named pipe gets removed only at the end of the script, if you
quit out of the script by hitting Ctrl-C while it's running, the FIFO will
not get removed. This is ok. You can manually clean up the FIFOs in the
directory. If this annoys you, you can optionally add the following lines
to your script after the first line:
on_ctrl_c() {
echo "Ignoring Ctrl-C"
}
# Call on_ctrl_c() when the interrupt signal is received.
# The interrupt signal is sent when you press Ctrl-C.
trap on_ctrl_c INT
(b)
Here is a program that runs the shell script from (a) as a child
process (mdb-lookup-server-nc-1.c):
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
static void die(const char *s)
{
perror(s);
exit(1);
}
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(1);
}
pid_t pid = fork();
if (pid < 0) {
die("fork failed");
} else if (pid == 0) {
// child process
fprintf(stderr, "[pid=%d] ", (int)getpid());
fprintf(stderr, "mdb-lookup-server started on port %s\n", argv[1]);
execl("./mdb-lookup-server-nc.sh", "mdb-lookup-server-nc.sh",
argv[1], (char *)0);
die("execl failed");
} else {
// parent process
if (waitpid(pid,
NULL, // no status
0) // no options
!= pid)
die("waitpid failed");
fprintf(stderr, "[pid=%d] ", (int)pid);
fprintf(stderr, "mdb-lookup-server terminated\n");
}
return 0;
}
Study this program and the man pages for the system calls used in it.
Run it to make sure it works with your shell script from (a). Make
sure you understand how everything works.
While this program is running, run the following command from another
terminal window logged into the same machine:
ps ajxfww
Find the process tree that contains ALL ancestors and children of this
program, and include it in your README.txt.
Make sure you understand the process relationships in that tree.
Identify the files that are shell scripts and list them in your
README.txt.
(c)
Write an improved version: mdb-lookup-server-nc-2.c
mdb-lookup-server-nc-1.c from (b) forked once, exec'ed the script,
waited until it's done, and then exited.
mdb-lookup-server-nc-2.c will do the following:
- It has a loop in which it displays a prompt, "port number: ". It
reads the port number typed in by the user and then fork/exec the
script from (a) using that port number. It also prints out a
message stating that an instance of mdb-lookup-server has started.
The message should include the child's process ID and the port
number on which it's listening.
- Hitting ENTER on the prompt should simply display another prompt.
- On every iteration, before it displays a prompt, it should check if any of
the child processes have terminated. It should display the process IDs of
all mdb-lookup-server processes that have terminated since the last prompt
was displayed, along with messages saying that they have terminated. For
this, you need to use the non-blocking version of waitpid() system call.
Here is how you use it:
pid = waitpid( (pid_t) -1, NULL, WNOHANG);
- Use Ctrl-C to quit.
CC = gcc
CXX = g++
INCLUDES =
CFLAGS = -g -Wall $(INCLUDES)
CXXFLAGS = -g -Wall $(INCLUDES)
LDFLAGS = -g
LDLIBS =
.PHONY: default
default: mdb-lookup-server-nc-2 mdb-lookup-server-nc-1
.PHONY: clean
clean:
rm -f *.o ~* a.out core mdb-lookup-server-nc
/*
* mdb-lookup-server-nc-1.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
static void die(const char *s)
{
perror(s);
exit(1);
}
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(1);
}
pid_t pid = fork();
if (pid < 0) {
die("fork failed");
} else if (pid == 0) {
// child process
fprintf(stderr, "[pid=%d] ", (int)getpid());
fprintf(stderr, "mdb-lookup-server started on port %s\n", argv[1]);
execl("./mdb-lookup-server-nc.sh", "mdb-lookup-server-nc.sh",
argv[1], (char *)0);
die("execl failed");
} else {
// parent process
if (waitpid(pid,
NULL, // no status
0) // no options
!= pid)
die("waitpid failed");
fprintf(stderr, "[pid=%d] ", (int)pid);
fprintf(stderr, "mdb-lookup-server terminated\n");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("port number: ");
char portnum[1000];
while(fgets((char * restrict)portnum, sizeof(portnum), stdin)){
if(portnum[0] != '\n'){
pid_t pid = fork();
if(pid == 0){
execl("./mdb-lookup-server-nc-1", "mdb-lookup-server-nc-1", portnum, (char *)0);
}
while(waitpid(-1, NULL, WNOHANG) > 0){
printf("[pid=%d] mdb-lookup-server terminated\n", (int)waitpid(-1, NULL, WNOHANG));
}
sleep(1);
}
printf("port number: ");
}
return 0;
// ENTER should restart the big while loop
}
#!/bin/sh
mkfifo mypipe-$$
cat mypipe-$$ | nc -l $1 | /home/jae/cs3157-pub/bin/mdb-lookup-cs3157 > mypipe-$$
rm mypipe-$$
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment