almost there!
This commit is contained in:
		
							parent
							
								
									0be4252685
								
							
						
					
					
						commit
						3a67adcfc5
					
				| 
						 | 
					@ -6,6 +6,24 @@ part1.out: part1_searcher.cpp
 | 
				
			||||||
run-part1: part1.out
 | 
					run-part1: part1.out
 | 
				
			||||||
	./part1.out file.txt NGTNIJGK 0 67108863
 | 
						./part1.out file.txt NGTNIJGK 0 67108863
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part2_partitioner.out: part2_partitioner.cpp
 | 
				
			||||||
 | 
						g++ -g part2_partitioner.cpp -o part2_partitioner.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part2_searcher.out: part2_searcher.cpp
 | 
				
			||||||
 | 
						g++ -g part2_searcher.cpp -o part2_searcher.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run-part2: part2_partitioner.out part2_searcher.out
 | 
				
			||||||
 | 
						./part2_partitioner.out file.txt NGTNIJGK 0 67108863 8388608
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part3_partitioner.out: part3_partitioner.cpp
 | 
				
			||||||
 | 
						g++ -g part3_partitioner.cpp -o part3_partitioner.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part3_searcher.out: part3_searcher.cpp
 | 
				
			||||||
 | 
						g++ -g part3_searcher.cpp -o part3_searcher.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run-part3: part3_partitioner.out part3_searcher.out
 | 
				
			||||||
 | 
						./part3_partitioner.out file.txt NGTNIJGK 0 67108863 8388608
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean-part1:
 | 
					clean-part1:
 | 
				
			||||||
	rm part1.out
 | 
						rm part1.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,358 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env perl
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Please read all the comments down to the line that says "STOP".
 | 
				
			||||||
 | 
					# These comments are divided into three sections:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     1. usage instructions
 | 
				
			||||||
 | 
					#     2. installation instructions
 | 
				
			||||||
 | 
					#     3. standard copyright
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Feel free to share this script with other instructors of programming
 | 
				
			||||||
 | 
					# classes, but please do not place the script in a publicly accessible
 | 
				
			||||||
 | 
					# place.  Comments, questions, and bug reports should be sent to
 | 
				
			||||||
 | 
					# moss-request@moss.stanford.edu.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# IMPORTANT: This script is known to work on Unix and on Windows using Cygwin.
 | 
				
			||||||
 | 
					# It is not known to work on other ways of using Perl under Windows.  If the
 | 
				
			||||||
 | 
					# script does not work for you under Windows, you can try the email-based
 | 
				
			||||||
 | 
					# version for Windows (available on the Moss home page).
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#  Section 1. Usage instructions
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#  moss [-l language] [-d] [-b basefile1] ... [-b basefilen] [-m #] [-c "string"] file1 file2 file3 ...
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The -l option specifies the source language of the tested programs.
 | 
				
			||||||
 | 
					# Moss supports many different languages; see the variable "languages" below for the
 | 
				
			||||||
 | 
					# full list.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Example: Compare the lisp programs foo.lisp and bar.lisp:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    moss -l lisp foo.lisp bar.lisp
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The -d option specifies that submissions are by directory, not by file.
 | 
				
			||||||
 | 
					# That is, files in a directory are taken to be part of the same program,
 | 
				
			||||||
 | 
					# and reported matches are organized accordingly by directory.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Example: Compare the programs foo and bar, which consist of .c and .h
 | 
				
			||||||
 | 
					# files in the directories foo and bar respectively.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    moss -d foo/*.c foo/*.h bar/*.c bar/*.h
 | 
				
			||||||
 | 
					#   
 | 
				
			||||||
 | 
					# Example: Each program consists of the *.c and *.h files in a directory under
 | 
				
			||||||
 | 
					# the directory "assignment1."
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    moss -d assignment1/*/*.h assignment1/*/*.c
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The -b option names a "base file".  Moss normally reports all code
 | 
				
			||||||
 | 
					# that matches in pairs of files.  When a base file is supplied,
 | 
				
			||||||
 | 
					# program code that also appears in the base file is not counted in matches.
 | 
				
			||||||
 | 
					# A typical base file will include, for example, the instructor-supplied 
 | 
				
			||||||
 | 
					# code for an assignment.  Multiple -b options are allowed.  You should 
 | 
				
			||||||
 | 
					# use a base file if it is convenient; base files improve results, but 
 | 
				
			||||||
 | 
					# are not usually necessary for obtaining useful information. 
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# IMPORTANT: Unlike previous versions of moss, the -b option *always*
 | 
				
			||||||
 | 
					# takes a single filename, even if the -d option is also used.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Examples:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#  Submit all of the C++ files in the current directory, using skeleton.cc
 | 
				
			||||||
 | 
					#  as the base file:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    moss -l cc -b skeleton.cc *.cc
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#  Submit all of the ML programs in directories asn1.96/* and asn1.97/*, where
 | 
				
			||||||
 | 
					#  asn1.97/instructor/example.ml and asn1.96/instructor/example.ml contain the base files.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    moss -l ml -b asn1.97/instructor/example.ml -b asn1.96/instructor/example.ml -d asn1.97/*/*.ml asn1.96/*/*.ml 
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The -m option sets the maximum number of times a given passage may appear
 | 
				
			||||||
 | 
					# before it is ignored.  A passage of code that appears in many programs
 | 
				
			||||||
 | 
					# is probably legitimate sharing and not the result of plagiarism.  With -m N,
 | 
				
			||||||
 | 
					# any passage appearing in more than N programs is treated as if it appeared in 
 | 
				
			||||||
 | 
					# a base file (i.e., it is never reported).  Option -m can be used to control
 | 
				
			||||||
 | 
					# moss' sensitivity.  With -m 2, moss reports only passages that appear
 | 
				
			||||||
 | 
					# in exactly two programs.  If one expects many very similar solutions
 | 
				
			||||||
 | 
					# (e.g., the short first assignments typical of introductory programming
 | 
				
			||||||
 | 
					# courses) then using -m 3 or -m 4 is a good way to eliminate all but
 | 
				
			||||||
 | 
					# truly unusual matches between programs while still being able to detect
 | 
				
			||||||
 | 
					# 3-way or 4-way plagiarism.  With -m 1000000 (or any very 
 | 
				
			||||||
 | 
					# large number), moss reports all matches, no matter how often they appear.  
 | 
				
			||||||
 | 
					# The -m setting is most useful for large assignments where one also a base file 
 | 
				
			||||||
 | 
					# expected to hold all legitimately shared code.  The default for -m is 10.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Examples:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   moss -l pascal -m 2 *.pascal 
 | 
				
			||||||
 | 
					#   moss -l cc -m 1000000 -b mycode.cc asn1/*.cc
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# 
 | 
				
			||||||
 | 
					# The -c option supplies a comment string that is attached to the generated
 | 
				
			||||||
 | 
					# report.  This option facilitates matching queries submitted with replies
 | 
				
			||||||
 | 
					# received, especially when several queries are submitted at once.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Example:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   moss -l scheme -c "Scheme programs" *.sch
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The -n option determines the number of matching files to show in the results.
 | 
				
			||||||
 | 
					# The default is 250.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Example:
 | 
				
			||||||
 | 
					#   moss -c java -n 200 *.java
 | 
				
			||||||
 | 
					# The -x option sends queries to the current experimental version of the server.
 | 
				
			||||||
 | 
					# The experimental server has the most recent Moss features and is also usually
 | 
				
			||||||
 | 
					# less stable (read: may have more bugs).
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Example:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   moss -x -l ml *.ml
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Section 2.  Installation instructions.
 | 
				
			||||||
 | 
					#     
 | 
				
			||||||
 | 
					# You may need to change the very first line of this script
 | 
				
			||||||
 | 
					# if perl is not in /usr/bin on your system.  Just replace /usr/bin
 | 
				
			||||||
 | 
					# with the pathname of the directory where perl resides.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#  3. Standard Copyright
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#Copyright (c) 1997 The Regents of the University of California.
 | 
				
			||||||
 | 
					#All rights reserved.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					#purpose, without fee, and without written agreement is hereby granted,
 | 
				
			||||||
 | 
					#provided that the above copyright notice and the following two
 | 
				
			||||||
 | 
					#paragraphs appear in all copies of this software.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 | 
				
			||||||
 | 
					#DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 | 
				
			||||||
 | 
					#OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 | 
				
			||||||
 | 
					#CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 | 
				
			||||||
 | 
					#INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 | 
				
			||||||
 | 
					#AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 | 
				
			||||||
 | 
					#ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 | 
				
			||||||
 | 
					#PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# STOP.  It should not be necessary to change anything below this line
 | 
				
			||||||
 | 
					# to use the script.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					use IO::Socket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# As of the date this script was written, the following languages were supported.  This script will work with 
 | 
				
			||||||
 | 
					# languages added later however.  Check the moss website for the full list of supported languages.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					@languages = ("c", "cc", "java", "ml", "pascal", "ada", "lisp", "scheme", "haskell", "fortran", "ascii", "vhdl", "perl", "matlab", "python", "mips", "prolog", "spice", "vb", "csharp", "modula2", "a8086", "javascript", "plsql");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$server = 'moss.stanford.edu';
 | 
				
			||||||
 | 
					$port = '7690';
 | 
				
			||||||
 | 
					$noreq = "Request not sent.";
 | 
				
			||||||
 | 
					$usage = "usage: moss [-x] [-l language] [-d] [-b basefile1] ... [-b basefilen] [-m #] [-c \"string\"] file1 file2 file3 ...";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The userid is used to authenticate your queries to the server; don't change it!
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					$userid=717747575;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Process the command line options.  This is done in a non-standard
 | 
				
			||||||
 | 
					# way to allow multiple -b's.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					$opt_l = "c";   # default language is c
 | 
				
			||||||
 | 
					$opt_m = 10;
 | 
				
			||||||
 | 
					$opt_d = 0;
 | 
				
			||||||
 | 
					$opt_x = 0;
 | 
				
			||||||
 | 
					$opt_c = "";
 | 
				
			||||||
 | 
					$opt_n = 250;
 | 
				
			||||||
 | 
					$bindex = 0;    # this becomes non-zero if we have any base files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					while (@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
 | 
				
			||||||
 | 
					    ($first,$rest) = ($1,$2);	
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    shift(@ARGV);
 | 
				
			||||||
 | 
					    if ($first eq "d") {
 | 
				
			||||||
 | 
						$opt_d = 1;
 | 
				
			||||||
 | 
						next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($first eq "b") {
 | 
				
			||||||
 | 
						if($rest eq '') {
 | 
				
			||||||
 | 
						    die "No argument for option -b.\n" unless @ARGV;
 | 
				
			||||||
 | 
						    $rest = shift(@ARGV);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						$opt_b[$bindex++] = $rest;
 | 
				
			||||||
 | 
						next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($first eq "l") {
 | 
				
			||||||
 | 
						if ($rest eq '') {
 | 
				
			||||||
 | 
						    die "No argument for option -l.\n" unless @ARGV;
 | 
				
			||||||
 | 
						    $rest = shift(@ARGV);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						$opt_l = $rest;
 | 
				
			||||||
 | 
						next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($first eq "m") {
 | 
				
			||||||
 | 
						if($rest eq '') {
 | 
				
			||||||
 | 
						    die "No argument for option -m.\n" unless @ARGV;
 | 
				
			||||||
 | 
						    $rest = shift(@ARGV);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						$opt_m = $rest;
 | 
				
			||||||
 | 
						next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($first eq "c") {
 | 
				
			||||||
 | 
						if($rest eq '') {
 | 
				
			||||||
 | 
						    die "No argument for option -c.\n" unless @ARGV;
 | 
				
			||||||
 | 
						    $rest = shift(@ARGV);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						$opt_c = $rest;
 | 
				
			||||||
 | 
						next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($first eq "n") {
 | 
				
			||||||
 | 
						if($rest eq '') {
 | 
				
			||||||
 | 
						    die "No argument for option -n.\n" unless @ARGV;
 | 
				
			||||||
 | 
						    $rest = shift(@ARGV);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						$opt_n = $rest;
 | 
				
			||||||
 | 
						next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($first eq "x") {
 | 
				
			||||||
 | 
						$opt_x = 1;
 | 
				
			||||||
 | 
						next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # Override the name of the server.  This is used for testing this script.
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    if ($first eq "s") {
 | 
				
			||||||
 | 
						$server = shift(@ARGV);
 | 
				
			||||||
 | 
						next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # Override the port.  This is used for testing this script.
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    if ($first eq "p") {
 | 
				
			||||||
 | 
						$port = shift(@ARGV);
 | 
				
			||||||
 | 
						next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    die "Unrecognized option -$first.  $usage\n"; 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Check a bunch of things first to ensure that the
 | 
				
			||||||
 | 
					# script will be able to run to completion.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Make sure all the argument files exist and are readable.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					print "Checking files . . . \n";
 | 
				
			||||||
 | 
					$i = 0;
 | 
				
			||||||
 | 
					while($i < $bindex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    die "Base file $opt_b[$i] does not exist. $noreq\n" unless -e "$opt_b[$i]";
 | 
				
			||||||
 | 
					    die "Base file $opt_b[$i] is not readable. $noreq\n" unless -r "$opt_b[$i]";
 | 
				
			||||||
 | 
					    die "Base file $opt_b is not a text file. $noreq\n" unless -T "$opt_b[$i]";
 | 
				
			||||||
 | 
					    $i++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					foreach $file (@ARGV)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    die "File $file does not exist. $noreq\n" unless -e "$file";
 | 
				
			||||||
 | 
					    die "File $file is not readable. $noreq\n" unless -r "$file";
 | 
				
			||||||
 | 
					    die "File $file is not a text file. $noreq\n" unless -T "$file";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ("@ARGV" eq '') {
 | 
				
			||||||
 | 
					    die "No files submitted.\n $usage";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					print "OK\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Now the real processing begins.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$sock = new IO::Socket::INET (
 | 
				
			||||||
 | 
					                                  PeerAddr => $server,
 | 
				
			||||||
 | 
					                                  PeerPort => $port,
 | 
				
			||||||
 | 
					                                  Proto => 'tcp',
 | 
				
			||||||
 | 
					                                 );
 | 
				
			||||||
 | 
					die "Could not connect to server $server: $!\n" unless $sock;
 | 
				
			||||||
 | 
					$sock->autoflush(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sub read_from_server {
 | 
				
			||||||
 | 
					    $msg = <$sock>;
 | 
				
			||||||
 | 
					    print $msg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sub upload_file {
 | 
				
			||||||
 | 
					    local ($file, $id, $lang) = @_;
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The stat function does not seem to give correct filesizes on windows, so
 | 
				
			||||||
 | 
					# we compute the size here via brute force.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					    open(F,$file);
 | 
				
			||||||
 | 
					    $size = 0;
 | 
				
			||||||
 | 
					    while (<F>) {
 | 
				
			||||||
 | 
						$size += length($_);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    close(F);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print "Uploading $file ...";
 | 
				
			||||||
 | 
					    print $sock "file $id $lang $size $file\n";
 | 
				
			||||||
 | 
					    open(F,$file);
 | 
				
			||||||
 | 
					    while (<F>) {
 | 
				
			||||||
 | 
						print $sock $_;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    close(F);
 | 
				
			||||||
 | 
					    print "done.\n";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print $sock "moss $userid\n";      # authenticate user
 | 
				
			||||||
 | 
					print $sock "directory $opt_d\n";
 | 
				
			||||||
 | 
					print $sock "X $opt_x\n";
 | 
				
			||||||
 | 
					print $sock "maxmatches $opt_m\n";
 | 
				
			||||||
 | 
					print $sock "show $opt_n\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# confirm that we have a supported languages
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					print $sock "language $opt_l\n";
 | 
				
			||||||
 | 
					$msg = <$sock>;
 | 
				
			||||||
 | 
					chop($msg);
 | 
				
			||||||
 | 
					if ($msg eq "no") {
 | 
				
			||||||
 | 
					    print $sock "end\n";
 | 
				
			||||||
 | 
					    die "Unrecognized language $opt_l.";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# upload any base files
 | 
				
			||||||
 | 
					$i = 0;
 | 
				
			||||||
 | 
					while($i < $bindex) {
 | 
				
			||||||
 | 
					    &upload_file($opt_b[$i++],0,$opt_l);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$setid = 1;
 | 
				
			||||||
 | 
					foreach $file (@ARGV) {
 | 
				
			||||||
 | 
					    &upload_file($file,$setid++,$opt_l); 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print $sock "query 0 $opt_c\n";
 | 
				
			||||||
 | 
					print "Query submitted.  Waiting for the server's response.\n";
 | 
				
			||||||
 | 
					&read_from_server();
 | 
				
			||||||
 | 
					print $sock "end\n";
 | 
				
			||||||
 | 
					close($sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -24,7 +24,7 @@ int main(int argc, char **argv)
 | 
				
			||||||
	int search_start_position = atoi(argv[3]);
 | 
						int search_start_position = atoi(argv[3]);
 | 
				
			||||||
	int search_end_position = atoi(argv[4]);
 | 
						int search_end_position = atoi(argv[4]);
 | 
				
			||||||
	int find = 0;
 | 
						int find = 0;
 | 
				
			||||||
	int pid = getpid();
 | 
						pid_t pid = getpid();
 | 
				
			||||||
	ifstream file(file_to_search_in, ios::binary);
 | 
						ifstream file(file_to_search_in, ios::binary);
 | 
				
			||||||
	int len2 = search_end_position - search_start_position;
 | 
						int len2 = search_end_position - search_start_position;
 | 
				
			||||||
	string buffer;
 | 
						string buffer;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,127 @@
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <cstdlib>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <sys/wait.h>
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (argc != 6)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cout << "usage: ./partitioner.out <path-to-file> <pattern> <search-start-position> <search-end-position> <max-chunk-size>\nprovided arguments:\n";
 | 
				
			||||||
 | 
					        for (int i = 0; i < argc; i++)
 | 
				
			||||||
 | 
					            cout << argv[i] << "\n";
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *file_to_search_in = argv[1];
 | 
				
			||||||
 | 
					    char *pattern_to_search_for = argv[2];
 | 
				
			||||||
 | 
					    int search_start_position = atoi(argv[3]);
 | 
				
			||||||
 | 
					    int search_end_position = atoi(argv[4]);
 | 
				
			||||||
 | 
					    int max_chunk_size = atoi(argv[5]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pid_t my_pid = getpid();
 | 
				
			||||||
 | 
					    pid_t searcher_pid;
 | 
				
			||||||
 | 
					    pid_t children[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cout << "[" << my_pid << "] start position = " << search_start_position << " ; end position = " << search_end_position << "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (search_end_position - search_start_position >= max_chunk_size)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int mid = (search_start_position + search_end_position) / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        children[0] = fork();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (children[0] == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //Left Child
 | 
				
			||||||
 | 
					            char start_str[10], mid_str[10], chunk_size_str[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string temp = to_string(search_start_position);
 | 
				
			||||||
 | 
					            strcpy(start_str, temp.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            temp = to_string(mid);
 | 
				
			||||||
 | 
					            strcpy(mid_str, temp.c_str());
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            temp = to_string(max_chunk_size);
 | 
				
			||||||
 | 
					            strcpy(chunk_size_str, temp.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            char *args[] = { "./part2_partitioner.out",file_to_search_in , pattern_to_search_for, start_str, mid_str, chunk_size_str, NULL };
 | 
				
			||||||
 | 
					            execv("./part2_partitioner.out", args);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Parent process
 | 
				
			||||||
 | 
					            cout << "[" << my_pid << "] forked left child " << children[0] << "\n";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        children[1] = fork();
 | 
				
			||||||
 | 
					        if (children[1] == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //Right Child
 | 
				
			||||||
 | 
					            char mid_next[10], end_str[10], chunk_size_str[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string temp = to_string(mid+1);
 | 
				
			||||||
 | 
					            strcpy(mid_next, temp.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            temp = to_string(search_end_position);
 | 
				
			||||||
 | 
					            strcpy(end_str, temp.c_str());
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            temp = to_string(max_chunk_size);
 | 
				
			||||||
 | 
					            strcpy(chunk_size_str, temp.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            char *args[] = { "./part2_partitioner.out", file_to_search_in, pattern_to_search_for, mid_next, end_str, chunk_size_str, NULL };
 | 
				
			||||||
 | 
					            execv("./part2_partitioner.out", args);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Parent process
 | 
				
			||||||
 | 
					            cout << "[" << my_pid << "] forked right child " << children[1] << "\n";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        waitpid(children[0], NULL, 0);
 | 
				
			||||||
 | 
					        cout << "[" << my_pid << "] left child returned\n";
 | 
				
			||||||
 | 
					        waitpid(children[1], NULL, 0);
 | 
				
			||||||
 | 
					        cout << "[" << my_pid << "] right child returned\n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        searcher_pid = fork();
 | 
				
			||||||
 | 
					        if (searcher_pid == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Child process
 | 
				
			||||||
 | 
					            char start_str[10], end_str[10];
 | 
				
			||||||
 | 
					            sprintf(start_str, "%d", search_start_position);
 | 
				
			||||||
 | 
					            sprintf(end_str, "%d", search_end_position);
 | 
				
			||||||
 | 
					            char *args[] = { "./part2_searcher.out", file_to_search_in, pattern_to_search_for, start_str, end_str ,NULL};
 | 
				
			||||||
 | 
					            execv("./part2_searcher.out", args);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Parent process
 | 
				
			||||||
 | 
					            cout << "[" << my_pid << "] forked searcher child " << searcher_pid << "\n";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        waitpid(searcher_pid, NULL, 0);
 | 
				
			||||||
 | 
					        cout << "[" << my_pid << "] searcher child returned \n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //TODO
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] start position = " << search_start_position << " ; end position = " << search_end_position << "\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] forked left child " << my_children[0] << "\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] forked right child " << my_children[1] << "\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] left child returned\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] right child returned\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] left child returned\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] right child returned\n";*/
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] forked searcher child " << searcher_pid << "\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] searcher child returned \n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] received SIGTERM\n"; //applicable for Part III of the assignment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -0,0 +1,47 @@
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <chrono>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						auto startmain = chrono::high_resolution_clock::now();
 | 
				
			||||||
 | 
						if(argc != 5)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							cout <<"usage: ./partitioner.out <path-to-file> <pattern> <search-start-position> <search-end-position>\nprovided arguments:\n";
 | 
				
			||||||
 | 
							for(int i = 0; i < argc; i++)
 | 
				
			||||||
 | 
								cout << argv[i] << "\n";
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						char *file_to_search_in = argv[1];
 | 
				
			||||||
 | 
						char *pattern_to_search_for = argv[2];
 | 
				
			||||||
 | 
						int len = sizeof(pattern_to_search_for);
 | 
				
			||||||
 | 
						int search_start_position = atoi(argv[3]);
 | 
				
			||||||
 | 
						int search_end_position = atoi(argv[4]);
 | 
				
			||||||
 | 
						int find = 0;
 | 
				
			||||||
 | 
						pid_t pid = getpid();
 | 
				
			||||||
 | 
						ifstream file(file_to_search_in, ios::binary);
 | 
				
			||||||
 | 
						int len2 = search_end_position - search_start_position;
 | 
				
			||||||
 | 
						string buffer;
 | 
				
			||||||
 | 
						buffer.resize(len2);
 | 
				
			||||||
 | 
						file.seekg(search_start_position);
 | 
				
			||||||
 | 
						file.read(&buffer[0], len2);
 | 
				
			||||||
 | 
						//TODO
 | 
				
			||||||
 | 
						auto a = buffer.find(pattern_to_search_for);
 | 
				
			||||||
 | 
						if(a != string::npos) {
 | 
				
			||||||
 | 
							cout << "[" << pid << "]" << " found at" << " " << a + search_start_position << endl;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							 cout << "[" << pid << "]" << " didn't find\n";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto endmain = std::chrono::high_resolution_clock::now();
 | 
				
			||||||
 | 
						chrono::duration<double> mainduration = endmain - startmain;
 | 
				
			||||||
 | 
						cout << mainduration.count() << endl;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -0,0 +1,156 @@
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <cstdlib>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <sys/wait.h>
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void handler(int signo, siginfo_t *info, void *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if(signo == SIGTERM)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							cout <<"["<< getpid()<<"] "<<"received SIGTERM\n";
 | 
				
			||||||
 | 
							exit(0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct sigaction sa;
 | 
				
			||||||
 | 
					    memset(&sa, 0, sizeof(struct sigaction));
 | 
				
			||||||
 | 
					    sa.sa_sigaction = &handler;
 | 
				
			||||||
 | 
					    if (sigaction(SIGTERM, &sa, NULL) == -1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        perror("sigaction");
 | 
				
			||||||
 | 
					        return EXIT_FAILURE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (argc != 6)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cout << "usage: ./partitioner.out <path-to-file> <pattern> <search-start-position> <search-end-position> <max-chunk-size>\nprovided arguments:\n";
 | 
				
			||||||
 | 
					        for (int i = 0; i < argc; i++)
 | 
				
			||||||
 | 
					            cout << argv[i] << "\n";
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *file_to_search_in = argv[1];
 | 
				
			||||||
 | 
					    char *pattern_to_search_for = argv[2];
 | 
				
			||||||
 | 
					    int search_start_position = atoi(argv[3]);
 | 
				
			||||||
 | 
					    int search_end_position = atoi(argv[4]);
 | 
				
			||||||
 | 
					    int max_chunk_size = atoi(argv[5]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pid_t my_pid = getpid();
 | 
				
			||||||
 | 
					    pid_t searcher_pid;
 | 
				
			||||||
 | 
					    pid_t children[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cout << "[" << my_pid << "] start position = " << search_start_position << " ; end position = " << search_end_position << "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (search_end_position - search_start_position >= max_chunk_size)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int mid = (search_start_position + search_end_position) / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        children[0] = fork();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (children[0] == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //Left Child
 | 
				
			||||||
 | 
					            char start_str[10], mid_str[10], chunk_size_str[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string temp = to_string(search_start_position);
 | 
				
			||||||
 | 
					            strcpy(start_str, temp.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            temp = to_string(mid);
 | 
				
			||||||
 | 
					            strcpy(mid_str, temp.c_str());
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            temp = to_string(max_chunk_size);
 | 
				
			||||||
 | 
					            strcpy(chunk_size_str, temp.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            char *args[] = { "./part3_partitioner.out",file_to_search_in , pattern_to_search_for, start_str, mid_str, chunk_size_str, NULL };
 | 
				
			||||||
 | 
					            execv("./part3_partitioner.out", args);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Parent process
 | 
				
			||||||
 | 
					            cout << "[" << my_pid << "] forked left child " << children[0] << "\n";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        children[1] = fork();
 | 
				
			||||||
 | 
					        if (children[1] == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //Right Child
 | 
				
			||||||
 | 
					            char mid_next[10], end_str[10], chunk_size_str[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string temp = to_string(mid+1);
 | 
				
			||||||
 | 
					            strcpy(mid_next, temp.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            temp = to_string(search_end_position);
 | 
				
			||||||
 | 
					            strcpy(end_str, temp.c_str());
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            temp = to_string(max_chunk_size);
 | 
				
			||||||
 | 
					            strcpy(chunk_size_str, temp.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            char *args[] = { "./part3_partitioner.out", file_to_search_in, pattern_to_search_for, mid_next, end_str, chunk_size_str, NULL };
 | 
				
			||||||
 | 
					            execv("./part3_partitioner.out", args);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Parent process
 | 
				
			||||||
 | 
					            cout << "[" << my_pid << "] forked right child " << children[1] << "\n";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(int i = 0; i < 2; ++i) {
 | 
				
			||||||
 | 
					            pid_t returned_pid = wait(NULL);
 | 
				
			||||||
 | 
					            if(returned_pid == children[0]) {
 | 
				
			||||||
 | 
					                cout << "[" << my_pid << "] left child returned\n";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                cout << "[" << my_pid << "] right child returned\n";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // waitpid(children[0], NULL, 0);
 | 
				
			||||||
 | 
					        // cout << "[" << my_pid << "] left child returned\n";
 | 
				
			||||||
 | 
					        // waitpid(children[1], NULL, 0);
 | 
				
			||||||
 | 
					        // cout << "[" << my_pid << "] right child returned\n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        searcher_pid = fork();
 | 
				
			||||||
 | 
					        if (searcher_pid == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Child process
 | 
				
			||||||
 | 
					            char start_str[10], end_str[10];
 | 
				
			||||||
 | 
					            sprintf(start_str, "%d", search_start_position);
 | 
				
			||||||
 | 
					            sprintf(end_str, "%d", search_end_position);
 | 
				
			||||||
 | 
					            char *args[] = { "./part3_searcher.out", file_to_search_in, pattern_to_search_for, start_str, end_str ,NULL};
 | 
				
			||||||
 | 
					            execv("./part3_searcher.out", args);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Parent process
 | 
				
			||||||
 | 
					            cout << "[" << my_pid << "] forked searcher child " << searcher_pid << "\n";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        waitpid(searcher_pid, NULL, 0);
 | 
				
			||||||
 | 
					        cout << "[" << my_pid << "] searcher child returned \n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //TODO
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] start position = " << search_start_position << " ; end position = " << search_end_position << "\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] forked left child " << my_children[0] << "\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] forked right child " << my_children[1] << "\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] left child returned\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] right child returned\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] left child returned\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] right child returned\n";*/
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] forked searcher child " << searcher_pid << "\n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] searcher child returned \n";
 | 
				
			||||||
 | 
						//cout << "[" << my_pid << "] received SIGTERM\n"; //applicable for Part III of the assignment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <chrono>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void handler(int signo, siginfo_t *info, void *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if(signo == SIGTERM)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							cout <<"["<< getpid()<<"] "<<"received SIGTERM\n";
 | 
				
			||||||
 | 
							exit(0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						auto startmain = chrono::high_resolution_clock::now();
 | 
				
			||||||
 | 
						struct sigaction sa;
 | 
				
			||||||
 | 
						memset(&sa, 0, sizeof(struct sigaction));
 | 
				
			||||||
 | 
						sa.sa_sigaction = &handler;
 | 
				
			||||||
 | 
						if (sigaction(SIGTERM, &sa, NULL) == -1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							perror("sigaction");
 | 
				
			||||||
 | 
							return EXIT_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						pid_t pgid = getpgid(getpid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(argc != 5)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							cout <<"usage: ./partitioner.out <path-to-file> <pattern> <search-start-position> <search-end-position>\nprovided arguments:\n";
 | 
				
			||||||
 | 
							for(int i = 0; i < argc; i++)
 | 
				
			||||||
 | 
								cout << argv[i] << "\n";
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						char *file_to_search_in = argv[1];
 | 
				
			||||||
 | 
						char *pattern_to_search_for = argv[2];
 | 
				
			||||||
 | 
						int len = sizeof(pattern_to_search_for);
 | 
				
			||||||
 | 
						int search_start_position = atoi(argv[3]);
 | 
				
			||||||
 | 
						int search_end_position = atoi(argv[4]);
 | 
				
			||||||
 | 
						int find = 0;
 | 
				
			||||||
 | 
						pid_t pid = getpid();
 | 
				
			||||||
 | 
						ifstream file(file_to_search_in, ios::binary);
 | 
				
			||||||
 | 
						int len2 = search_end_position - search_start_position;
 | 
				
			||||||
 | 
						string buffer;
 | 
				
			||||||
 | 
						buffer.resize(len2);
 | 
				
			||||||
 | 
						file.seekg(search_start_position);
 | 
				
			||||||
 | 
						file.read(&buffer[0], len2);
 | 
				
			||||||
 | 
						//TODO
 | 
				
			||||||
 | 
						auto a = buffer.find(pattern_to_search_for);
 | 
				
			||||||
 | 
						if(a != string::npos) {
 | 
				
			||||||
 | 
							cout << "[" << pid << "]" << " found at" << " " << a + search_start_position << endl;
 | 
				
			||||||
 | 
							killpg(pgid,SIGTERM);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							 cout << "[" << pid << "]" << " didn't find\n";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto endmain = std::chrono::high_resolution_clock::now();
 | 
				
			||||||
 | 
						chrono::duration<double> mainduration = endmain - startmain;
 | 
				
			||||||
 | 
						cout << mainduration.count() << endl;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in New Issue