3 * Author: Jan Vales (e0726236@student.tuwien.ac.at)
\r
5 * Purpose: Forksorting
\r
7 * Input: <lines to sort>\n<line>\n<line>\n...
\r
8 * Output: sorted input
\r
10 #include "globals.h"
\r
12 char *szCommand = "";
\r
15 (void)fprintf(stderr, "Usage: %s\n", szCommand);
\r
16 exit(EXIT_FAILURE);
\r
19 void bailout(const char *msgstr){
\r
21 (void)fprintf(stderr, "%s(%d(%d)): [ERROR] %s\n", szCommand, getpid(), getppid(), msgstr);
\r
23 (void)fprintf(stderr, "%s(%d(%d)): [ERROR(%d)] %s: %s\n", szCommand, getpid(), getppid(), errno, msgstr, strerror(errno));
\r
28 void myTrim(char *str){
\r
30 if(str == 0 || strlen(str) == 0) return;
\r
31 while(isspace(str[0]))for(c=0; c<strlen(str); c++)str[c] = str[c+1];
\r
32 for(c = strlen(str)-1; isspace(str[c]); c--)str[c] = 0;
\r
35 int readLine(char *lineRet, FILE *fp){
\r
36 char tmpLine[MAX_CHARS];
\r
37 if(fgets(tmpLine, MAX_CHARS, fp)==NULL) {
\r
38 /* (void)fprintf(stderr, "%s (pid %i): [DBG] readLine(): error at fgets, returning EOF\n", szCommand, getpid()); */
\r
41 if((strlen(tmpLine) == (MAX_CHARS-1)) && (tmpLine[strlen(tmpLine)-1] != '\n'))while(fgetc(fp) != '\n');
\r
43 strcpy(lineRet, tmpLine);
\r
44 return EXIT_SUCCESS;
\r
48 int main(int argc, char *argv[]){
\r
49 fprintf(stderr, "%d \n", strcmp("aa","bb"));
\r
50 fprintf(stderr, "%d \n", strcmp("bb","bb"));
\r
52 fprintf(stderr, "%d \n", strcmp("cc","bb"));
\r
58 char tmpLine[MAX_CHARS];
\r
62 p2c = parent 2 child
\r
63 c2p = child 2 parent
\r
78 char tmpLineR[MAX_CHARS];
\r
81 szCommand = argv[0];
\r
82 if(argc != 1)usage();
\r
84 if(readLine(tmpLine, stdin) == EOF)bailout("Cannot read Line");
\r
85 if(sscanf(tmpLine, "%i", &linecnt) != 1)bailout("Cannot parse Line-Count");
\r
87 if(linecnt <= 0)bailout("Linecount must be positive!");
\r
89 readLine(tmpLine, stdin);
\r
90 (void)fprintf(stdout, "%s\n", tmpLine);
\r
94 /* only if linecnt >1: do stuff below this line */
\r
96 if(pipe(lPc2p) == EOF || pipe(lPp2c) == EOF)bailout("LC: Cannot create pipes");
\r
97 if(pipe(rPc2p) == EOF || pipe(rPp2c) == EOF)bailout("Cannot create pipes for R child");
\r
100 /*** MERGE-SORT::SPLIT DATA ***/
\r
103 case -1: bailout("error forking left child!");
\r
105 if((close(lPc2p[0]) < 0) || (close(lPp2c[1]) < 0))bailout("LC: Cannot close unneeded pipe ends");
\r
106 if((dup2(lPc2p[1], fileno(stdout)) == EOF) || (dup2(lPp2c[0], fileno(stdin)) == EOF))bailout("LC: dup2 failed");
\r
107 if(execlp(argv[0], argv[0], (const char*)0) < 0)bailout("LC: execlp() failed");
\r
112 if((lfp2c = fdopen(lPp2c[1], "w")) == NULL)bailout("LC: fdopen(lPp2c[1]) failed");
\r
114 /* write stuff to left child's stdin */
\r
115 if(fprintf(lfp2c, "%i\n", (linecnt/2)) < 0)bailout("LC: Cannot write linecnt.");
\r
116 for(i = 0; i < (linecnt/2); i++){
\r
117 if(readLine(tmpLine, stdin) == EOF)bailout("Cannot read stdin");
\r
118 if(fprintf(lfp2c, "%s\n", tmpLine) < 0)bailout("LC: Cannot write to lfp2c");
\r
120 if(fclose(lfp2c) == EOF)bailout("LC: fclose(lfp2c) failed");
\r
125 case -1: bailout("error forking right child!");
\r
127 if((close(rPc2p[0]) < 0) || (close(rPp2c[1]) < 0))bailout("RC: Cannot close unneeded pipe ends");
\r
128 if((dup2(rPc2p[1], fileno(stdout)) == EOF) || (dup2(rPp2c[0], fileno(stdin)) == EOF))bailout("RC: dup2 failed");
\r
129 if(execlp(argv[0], argv[0], (const char*)0) < 0)bailout("RC: execlp() failed");
\r
134 if((rfp2c = fdopen(rPp2c[1], "w")) == NULL)bailout("RC: fdopen(rPp2c[1]) failed");
\r
136 /* write stuff to left child's stdin */
\r
137 if(fprintf(rfp2c, "%i\n", (linecnt-(linecnt/2))) < 0)bailout("RC: Cannot write linecnt.");
\r
138 for(i = (linecnt/2); i < linecnt; i++) {
\r
139 if(readLine(tmpLine, stdin) == EOF)bailout("Cannot read stdin");
\r
140 if(fprintf(rfp2c, "%s\n", tmpLine) < 0)bailout("RC: Cannot write to rfp2c");
\r
143 if(fclose(rfp2c) == EOF)bailout("RC: fclose(rfp2c) failed");
\r
146 /*** MERGE-SORT::MERGE DATA ***/
\r
147 if((lfc2p = fdopen(lPc2p[0], "r")) == NULL) bailout("fdopen(lPc2p[0], r)");
\r
148 if((rfc2p = fdopen(rPc2p[0], "r")) == NULL) bailout("fdopen(rPc2p[0], r)");
\r
150 if((lStat = readLine(tmpLine, lfc2p)) == EXIT_FAILURE)bailout("LC: Cannot read results");
\r
151 if((rStat = readLine(tmpLineR, rfc2p)) == EXIT_FAILURE)bailout("RC: Cannot read results");
\r
153 while(lStat != EOF || rStat != EOF) {
\r
154 fprintf(stderr, "%d hier %d - %d\n", getpid(), lStat, rStat);
\r
157 while(rStat != EOF) {
\r
158 fprintf(stdout, "%s\n", tmpLineR);
\r
159 if((rStat = readLine(tmpLineR, rfc2p)) == EXIT_FAILURE)bailout("RC: Cannot read results");
\r
161 fprintf(stderr, "%d hier1 %d - %d\n", getpid(), lStat, rStat);
\r
166 while(lStat != EOF) {
\r
167 fprintf(stdout, "%s\n", tmpLine);
\r
168 if((lStat = readLine(tmpLine, lfc2p)) == EXIT_FAILURE)bailout("LC: Cannot read results");
\r
170 fprintf(stderr, "%d hier2 %d - %d\n", getpid(), lStat, rStat);
\r
174 while((lStat != EOF && rStat != EOF) && (strcmp(tmpLine, tmpLineR) > 0)) {
\r
175 fprintf(stdout, "%s\n", tmpLineR);
\r
176 if((rStat = readLine(tmpLineR, rfc2p)) == EXIT_FAILURE)bailout("RC: Cannot read results");
\r
177 fprintf(stderr, "%d hier3 %d - %d\n", getpid(), lStat, rStat);
\r
180 while((lStat != EOF && rStat != EOF) && (strcmp(tmpLine, tmpLineR) <= 0)) {
\r
181 fprintf(stdout, "%s\n", tmpLine);
\r
182 if((lStat = readLine(tmpLine, lfc2p)) == EXIT_FAILURE)bailout("LC: Cannot read results");
\r
183 fprintf(stderr, "%d hier3 %d - %d\n", getpid(), lStat, rStat);
\r
185 fprintf(stderr, "%d hier4 %d - %d\n", getpid(), lStat, rStat);
\r
188 fprintf(stderr, "%d hier5 %d - %d\n", getpid(), lStat, rStat);
\r
190 if(fclose(lfc2p) == EOF) return EXIT_FAILURE;
\r
191 if(fclose(rfc2p) == EOF) return EXIT_FAILURE;
\r
193 waitpid(lPid, 0, 0);
\r
194 waitpid(rPid, 0, 0);
\r