#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sstream>
#include <sys/times.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fstream>
#define Dneedle_max 6
#define Dnew_line 10
using namespace std;
const int maxPar = 3;
const int maxProcess = 32;
static int end_main = 0;
int fd;
int maxproc = 0;
unsigned long len_max;
const key_t shm_id = 8274;
char *fileinmemory;
char needle[Dneedle_max];
struct stat fd_st;
struct process_struct {
pid_t pid;
int returnCode;
time_t timeProcSystem_us;
time_t timeProcUser_us;
time_t countTimeProcess_start;
time_t countTimeProcess_stop;
char *shm_start;
unsigned long shm_diff;
unsigned long shm_len;
int shm_return_len;
};
struct tms bufor;
struct process_struct *process = new process_struct[maxProcess];
void sygnal(int signo, siginfo_t * sigf, void *b);
int
main(int argc, char *argv[])
{
pid_t pid_tmp;
sigset_t sig_mask;
int returnCode,
opt_check;
int i;
struct rusage timeData;
struct sigaction sigA;
long adressum = 0;
unsigned long sizetmp;
unsigned long shmComputeDiv;
char *copyfim = 0;
if (argc == 1) {
cout << "Nie podano parametrow w wywolaniu programu." << endl;
return 128;
}
if (argc > (maxPar + 1)) {
cout << "Za duzo parametrow, maksymalnie podaj " << maxPar <<
" parametrow." << endl;
return 129;
}
if (argc < (maxPar + 1)) {
cout << "Za malo parametrow, podaj " << maxPar << " parametrow." <<
endl;
return 129;
}
while ((opt_check = getopt(argc, argv, "vh")) != (-1)) {
switch (opt_check) {
case 'v':
cout << "Versja 1.0\n" << endl;
return 130;
case 'h':
cout <<
"Poprawne wywolanie programu: szukany ciąg 6 znaków, plik, ile procesów."
<< endl;
cout << "Maksymalnie podaj " << maxPar << " parametrów." <<
endl;
return 130;
}
}
fd = open(argv[2], O_RDONLY);
if (fd == -1) {
perror("Multifind: open.");
return 1;
}
if (fstat(fd, &fd_st) == -1) {
perror("Multifind: fstat.");
return 1;
}
if (!S_ISREG(fd_st.st_mode)) {
fprintf(stderr, "%sMultifind: to nie plik.\n", argv[2]);
return 1;
}
len_max = fd_st.st_size;
int smid =
shmget(shm_id, len_max, IPC_CREAT | SHM_NORESERVE | 0666);
fileinmemory = (char *) shmat(smid, NULL, 0);
if (*fileinmemory == -1) {
perror("Multifind: shmat.");
return 1;
}
int readerr = read(fd, fileinmemory, len_max);
if (readerr == -1) {
fprintf(stderr, "Multifind: read.");
return 1;
}
if (close(fd) == -1) {
perror("Multifind: close.");
return 1;
}
if (strlen(argv[1]) != Dneedle_max) {
fprintf(stderr, "%sZla dlugośc needle.\n", argv[1]);
return 1;
} else {
strcpy(needle, argv[1]);
}
maxproc = atoi(argv[3]);
if (maxproc > maxProcess) {
fprintf(stderr, "Multifind: za duzo prosesow.");
return 1;
} else {
if (maxproc == 0) {
fprintf(stderr, "Multifind: podales zero procesow.");
return 1;
}
}
shmComputeDiv = len_max / maxproc;
for (i = 0; i < maxproc; ++i) {
process[i].shm_start = fileinmemory + (shmComputeDiv * (i));
process[i].shm_len = shmComputeDiv;
}
process[maxproc - 1].shm_len =
(fileinmemory + len_max) - process[maxproc - 1].shm_start;
printf("@ fileinmemory: %p \n", fileinmemory);
printf("@ len_max: 0x%lX \n", len_max);
printf("@ sum: 0x%lX \n",
(long unsigned) fileinmemory + len_max);
for (i = 1; i < maxproc; ++i) {
sizetmp = process[i - 1].shm_len;
copyfim = process[i - 1].shm_start;
while ((copyfim[sizetmp] != (char) Dnew_line)) {
--sizetmp;
}
process[i - 1].shm_len = sizetmp;
process[i].shm_start =
process[i - 1].shm_start + process[i - 1].shm_len;
}
process[maxproc - 1].shm_len =
(fileinmemory + len_max) - process[maxproc - 1].shm_start;
printf("\n");
for (i = 0; i < maxproc; ++i) {
process[i].shm_diff = process[i].shm_start - fileinmemory;
}
adressum = 0;
for (i = 0; i < maxproc; ++i) {
printf("%2d: shm_start: %p ", i, process[i].shm_start);
printf(" shm_len: %lX ", process[i].shm_len);
printf(" shm_diff: %8lX ", process[i].shm_diff);
adressum += process[i].shm_len;
printf(" shm_start+shm_len: %lX \n",
process[i].shm_len + (long int) process[i].shm_start);
}
printf("Addr len_max: %lX \n", len_max);
printf(" Diff sum: %lX \n", adressum);
printf("\n");
sigemptyset(&sig_mask);
sigfillset(&sig_mask);
sigA.sa_handler = NULL;
sigA.sa_sigaction = sygnal;
sigA.sa_mask = sig_mask;
sigA.sa_flags = SA_SIGINFO;
sigA.sa_restorer = NULL;
if (sigaction(SIGCHLD, &sigA, NULL)) {
perror("Blad sigaction:");
exit(33);
}
for (int i = 0; i < maxproc; i++) {
process[i].countTimeProcess_start = times(&bufor);
process[i].pid = fork();
switch (process[i].pid) {
case -1:
cout << "Nie mozna utworzyc nowego procesu nr: " << i << endl;
break;
case 0:{
const int needle_max = Dneedle_max;
unsigned long child_len_max = process[i].shm_len;
char *child_fileinmemory;
int needle_max_minusone = needle_max - 1;
child_fileinmemory = fileinmemory + process[i].shm_diff;
char *endfileinmemory =
child_fileinmemory + child_len_max - needle_max + 1;
char *mark = child_fileinmemory;
char *copymarkstart,
*copymarkstop;
char *needle_maxminus =
needle + needle_max_minusone;
char *needle_plus = needle + 1;
unsigned long needle_max_minustwo = needle_max - 2;
unsigned long copylen_max = child_len_max;
char *mark_buff = mark;
int count_buff;
while ((mark = (char *) memchr(mark, *needle, copylen_max))
&& (mark < endfileinmemory)) {
if (mark[needle_max_minusone] == *needle_maxminus) {
if (memcmp
(++mark, needle_plus,
needle_max_minustwo) == 0) {
copymarkstart = mark;
while (*(--copymarkstart) != (char) Dnew_line);
copymarkstop = mark + needle_max;
while (*(++copymarkstop) != (char) Dnew_line);
mark = copymarkstop;
count_buff = copymarkstop - copymarkstart;
memmove(mark_buff, ++copymarkstart,
count_buff);
mark_buff += count_buff;
copylen_max = endfileinmemory - mark;
break;
} else {
--copylen_max;
}
} else {
++mark;
--copylen_max;
}
}
while ((mark = (char *) memchr(mark, *needle, copylen_max))
&& (mark < endfileinmemory)) {
if (mark[needle_max_minusone] == *needle_maxminus) {
if (memcmp
(++mark, needle_plus,
needle_max_minustwo) == 0) {
copymarkstart = mark;
while (*(--copymarkstart) != (char) Dnew_line);
copymarkstop = mark + needle_max;
while (*(++copymarkstop) != (char) Dnew_line);
mark = copymarkstop;
count_buff = copymarkstop - copymarkstart;
memcpy(mark_buff, ++copymarkstart, count_buff);
mark_buff += count_buff;
copylen_max = endfileinmemory - mark;
} else {
--copylen_max;
}
} else {
++mark;
--copylen_max;
}
}
int *tmmp =
(int *) (child_fileinmemory + child_len_max - 8);
*tmmp = mark_buff - child_fileinmemory;
return (44);
break;
}
default:
break;
}
}
do {
pause();
}
while (end_main < (maxproc - 1));
while ((pid_tmp = wait4(0, &returnCode, 0, &timeData)) != (-1)) {
for (int i = 0; i < maxproc; i++) {
if (process[i].pid == pid_tmp) {
process[i].timeProcSystem_us = timeData.ru_stime.tv_usec;
process[i].timeProcUser_us = timeData.ru_utime.tv_usec;
process[i].returnCode = returnCode;
i = maxproc;
}
}
}
int *len_buff;
fstream file_out;
file_out.open("wynik_multifind.txt", ios::out);
if (file_out.good() == true) {
for (int i = 0; i < maxproc; ++i) {
len_buff =
(int *) (fileinmemory + process[i].shm_diff +
process[i].shm_len - 8);
file_out.write(process[i].shm_start, *len_buff);
}
file_out.close();
}
for (int i = 0; i < maxproc; ++i) {
cout << "*** Proces: [" << i << "], kod zakonczenia: " <<
(process[i].returnCode >> 8) << endl;
cout << "Czas pracy procesu: " << (double) (process[i].
countTimeProcess_stop -
process[i].
countTimeProcess_start)
/ sysconf(_SC_CLK_TCK)
<< "s" << endl;
cout << "Czas procesora w trybie uzytkownika: "
<< setw(8) << (double) process[i].timeProcUser_us /
CLOCKS_PER_SEC << "s" << endl;
cout << "Czas procesora w trybie systemowym: " << setw(9) <<
(double) process[i].timeProcSystem_us /
CLOCKS_PER_SEC << "s" << endl << endl;
}
int r = shmdt(fileinmemory);
if (r == -1) {
perror("Multifind: shmdt.");
}
r = shmctl(smid, IPC_RMID, NULL);
if (r == -1) {
perror("Multifind: shmCTL.");
}
cout << endl;
return 0;
}
void
sygnal(int signo, siginfo_t * sigf, void *b)
{
for (int i = 0; i < maxproc; ++i) {
if (process[i].pid == sigf->si_pid) {
process[i].countTimeProcess_stop = times(&bufor);
i = maxproc;
}
}
end_main += 1;
}