// Sends an array of normals in buffers on the GPU void Object::sendUvs(const vector<pair<float, float> > &values) { ArrayBinder binder(vaoId); const GLenum attributeUV = 2; // Third attribute in the shader is the uv pushArray(attributeUV, uvsVboId, (GLfloat*) values.data(), values.size(), 2); m_bUvs = true; }
// Sends an array of normals in buffers on the GPU void Object::sendNormals(const vector<Vector3f> &values) { ArrayBinder binder(vaoId); const GLenum attributeNormal = 1; // Second attribute in the shader is the normal pushArray(attributeNormal, normalsVboId, (GLfloat*) values.data(), values.size(), 3); m_bNormals = true; }
// Sends an array of colors in buffers on the GPU void Object::sendColors(const vector<Color> &values) { ArrayBinder binder(vaoId); const GLenum attributeColor = 3; // Fourth attribute in the shader is the color pushArray(attributeColor, colorsVboId, (GLfloat*) values.data(), values.size(), 4); m_bColors = true; }
// Sends an array of vertices and an array of indices in buffers on the GPU void Object::sendPrimitives(const vector<Vector3f> &vertices, const vector<GLuint> &indices) { ArrayBinder binder(vaoId); const GLenum attributePosition = 0; // First attribute in the shader is position pushArray(attributePosition, verticesVboId, (GLfloat*) vertices.data(), vertices.size(), 3); // Binds the other vbo glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesVboId); // Loads up the indices of the vertices glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW); nbIndices = indices.size(); m_bPrimitives = true; }
//------------------------------------------------------------------------------ void pushValue(HSQUIRRELVM vm, const Variant & v) { switch (v.getType().id) { case SN_VT_STRING: { const std::string & s = v.getString(); sq_pushstring(vm, s.c_str(), s.size()); } break; case SN_VT_INT: sq_pushinteger(vm, v.getInt()); break; case SN_VT_FLOAT: sq_pushfloat(vm, static_cast<float>(v.getFloat())); break; case SN_VT_DICTIONARY: pushTable(vm, v.getDictionary()); break; case SN_VT_ARRAY: pushArray(vm, v.getArray()); break; case SN_VT_BOOL: sq_pushbool(vm, v.getBool()); break; case SN_VT_NIL: sq_pushnull(vm); break; default: // TODO Handle special objects (color, vectors, matrix, instances etc) // UNKNOWN break; } }
void eval( Node *node ) { int i, j; Number n1, n2, n3, n4; char *string1; Symbol *s; Node *n; Array *a; /* debugging */ #ifdef __DEBUG_TRACE__ SourceCode *sc; #endif /* init vars */ n1=0; n2=0; n3=0; n4=0; if (node == NULL) { return; } /* test node */ eMemTest( "eval: node is corrupt", node ); eMemTest( "eval: node->left is corrupt", node->left ); eMemTest( "eval: node->right is corrupt", node->right ); /* tracing */ if (node->trace != -1) { runLineId = node->trace; #ifdef __DEBUG_TRACE__ sc = eFindSource( runLineId ); eConsole("%d: %s\n", sc->lineNum, sc->text ); #endif /* sdlBasic_debugging */ if (debug==1){ screendebug(); //////////////////////////////////// } } /* debugging */ #ifdef __DEBUG_TRACE__ eConsole( "Op:%s\n", opcodeName[node->op] ); #endif switch( node->op ) { //case NULL: // break; case OpAdd: eval( node->left ); eval( node->right ); /* add or concat? */ if (getStackType( tos ) == DATA_STRING) { basConcat(); } else { n2 = popNumber(); n1 = popNumber(); pushNumber( n1 + n2 ); } break; case OpAnd: /* short circuit */ eval( node->left ); if (!popNumber()) { pushNumber( (Number)0 ); } else { eval( node->right ); if (popNumber()) { pushNumber( (Number)1 ); } else { pushNumber( (Number)0 ); } } break; case OpArgList: eval( node->left ); eval( node->right ); break; case OpArrayGet: eval( node->left ); /* indices and index */ getArrayElement( node->value.symbol ); break; case OpArrayPtr: pushArray( node->value.symbol ); break; case OpArraySet: eval( node->right ); /* value to store */ eval( node->left ); /* indices and index */ setArrayElement( node->value.symbol ); break; case OpAssign: /* value to be assigned. note the *right* node is used */ eval( node->right ); /* variable to assign to */ setVar( node->value.symbol ); break; case OpBuiltin: case OpBuiltinCall: /* for argcount */ n1 = tos; /* mark start of created objects */ pushCreateStack( 0 ); /* the args */ eval( node->left ); /* builtin symbol */ s = node->value.symbol; if (s == NULL) { ePrintf( Runtime, "builtin pointer is null"); } /* set args */ argCount = (int)(tos - n1); /* call the c function */ (*s->builtin)(); /* destroy created objects */ clearCreateStack(); /* drop result? */ if (node->op == OpBuiltinCall) { dropTos(); } break; case OpCaseSelect: /* top level of a case statement */ /* value to compare */ eval( node->left ); /* resolve into real data */ switch (getStackType( tos )) { case DATA_NUMBER: pushNumber( popNumber() ); break; case DATA_STRING: pushString( popString() ); break; default: ePrintf( Runtime, "OpCaseSelect: can't resolve type %s", datumName[getStackType( tos )] ); } /* get first test */ if (node == NULL) { /* no tests */ break; } else { node = node->right; } /* walk the chain of cases */ while (1) { /* get a test/action pair */ n = node->left; /* perform the tests */ eval( n->left ); /* true? */ if (popNumber()) { /* perform action and leave loop */ eval( n->right ); break; } /* move to next test */ node = node->right; if (node == NULL) { break; } } /* drop the test value from the stack */ dropTos(); break; case OpCaseCmp: case OpCaseRange: case OpCaseElse: /* perform chain of tests until true or end */ while (1) { switch (node->op) { case OpCaseCmp: /* value to compare */ eval(node->left); /* what type of test? */ switch (getStackType( tos-1 )) { case DATA_NUMBER: numberCompare( node->value.iValue, 0 ); break; case DATA_STRING: stringCompare( node->value.iValue, 0 ); break; default: ePrintf( Runtime, "OpCaseCmp: bad data type" ); } break; case OpCaseRange: /* values to compare */ n = node->left; eval( n->left ); eval( n->right ); /* what type of comparison? */ switch (getStackType( tos-2 )) { case DATA_NUMBER: numberRangeCompare(); break; case DATA_STRING: stringRangeCompare(); break; default: ePrintf( Runtime, "OpCaseRange: bad data type" ); break; } break; case OpCaseElse: /* put true on stack */ pushNumber( 1 ); break; default: ePrintf( Runtime, "opcode %s found in Case test chain", opcodeName[node->op] ); } /* was result true? */ if (stack[tos].value.number) { /* leave true flag on stack and exit */ break; } /* move to next test */ node = node->right; if (node == NULL) { /* exit with false flag */ break; } /* drop test result flag */ dropTos(); } break; case OpClassMethod: case OpClassMethodCall: /* the args */ n1 = tos; /* mark start of created objects */ pushCreateStack( 0 ); /* the args */ eval( node->right ); argCount = (int)(tos - n1); me = 0; runMethod( node->left->value.symbol->klass, node->value.string ); /* destroy created objects */ clearCreateStack(); /* drop result? */ if (node->op == OpClassMethodCall) { dropTos(); } break; case OpClose: if (node->left == NULL) { fileCloseAll(); } else { eval( node->left ); i = (int)popNumber(); fileClose( i ); } break; case OpCmp: eval( node->left ); eval( node->right ); switch(getStackType(tos)) { case DATA_NUMBER: numberCompare( node->value.iValue, 1 ); break; case DATA_STRING: stringCompare( node->value.iValue, 1 ); break; default: ePrintf( Runtime, "opCmp: can't handle datatype" ); } break; case OpComma: /* optimized for linked lists */ while (1) { /* exit flag set? */ if (exitForFlag != 0 || exitRoutineFlag != 0 || exitDoFlag != 0 || exitWhileFlag != 0 || continueFlag ) { break; } if (node->left != NULL ) { eval( node->left ); } /* end of list? */ if (node->right == NULL ) { break; /* linked list? */ } else if (node->right->op == OpComma) { node = node->right; /* not a list */ } else { eval( node->right ); break; } } break; case OpConcat: eval( node->left ); eval( node->right ); basConcat(); break; case OpConstGet: s = node->value.symbol; i = s->stackPos; /* this better not be indirected! */ switch (stack[i].datatype) { case DATA_STRING: pushString( stack[i].value.string ); break; case DATA_NUMBER: pushNumber( stack[i].value.number ); break; default: ePrintf( Runtime, "Can't fetch Const type %s", datumName[stack[i].datatype] ); break; } break; case OpConstSet: s = node->value.symbol; eval( node->left ); switch (stack[tos].datatype) { case DATA_STRING: stack[s->stackPos].datatype = DATA_STRING; stack[s->stackPos].value.string = stack[tos].value.string; stack[tos].datatype = DATA_NUMBER; tos--; break; case DATA_NUMBER: stack[s->stackPos].datatype = DATA_NUMBER; stack[s->stackPos].value.number = stack[tos].value.number; tos--; break; default: ePrintf( Runtime, "Can't set Const to %s", datumName[stack[tos].datatype] ); break; } break; case OpDelete: eval( node->left ); runDestructor( (int)popNumber(), OpDelete ); break; case OpDestroy: eval( node->left ); runDestructor( (int)popNumber(), OpDestroy ); break; case OpContinue: continueFlag = 1; break; case OpDiv: eval( node->left ); eval( node->right ); n2 = popNumber(); n1 = popNumber(); if (n2 == 0.0) { ePrintf( Runtime, "Division by zero" ); } pushNumber( n1 / n2 ); break; case OpDo: while (1) { /* test */ eval( node->left ); /*if (!popNumber()){ break; }*/ /* code */ eval( node->right ); //printf("exitDoFlag:%d\n",exitDoFlag); if (exitDoFlag != 0) { exitDoFlag = 0; break; } else if (continueFlag) { continueFlag = 0; } } break; case OpEnd: eShutdown(0); break; case OpErase: if (node->left == NULL) { /* erase entire array */ eraseArray( node->value.symbol ); } else { /* evaluate the indexes */ eval( node->left ); /* erase single element from array */ eraseArrayElement( node->value.symbol ); } break; case OpExitDo: exitDoFlag = 1; break; case OpExitFor: exitForFlag = 1; break; case OpExitRoutine: currentScope=oldScope[oldScopeP--]; exitRoutineFlag = 1; break; case OpExitWhile: exitWhileFlag = 1; break; case OpFloat: pushNumber( node->value.fValue ); break; case OpFor: s = node->value.symbol; eval( node->left ); n2 = popNumber(); n1 = popNumber(); /* initial value */ pushNumber( n3 ); setVar( s ); for( n3=n1; n3 <= n2; n3++ ) { /* set loop variable */ pushNumber( n3 ); setVar( s ); /* run code */ eval( node->right ); /* special exit condition? */ if (exitForFlag) { exitForFlag = 0; break; } else if (continueFlag) { continueFlag = 0; } /* get loop value (in case it changed) */ getVar( s ); n3 = popNumber(); } break; case OpForEach: /* variable to assign */ s = node->value.symbol; /* array to read from */ a = getArray( node->left->value.symbol ); /* iterate through keys */ i = 0; /* put key on stack, or exit */ while (getDynamicKey( a, i )) { /* assign to variable */ setVar( s ); /* run block */ eval( node->right ); /* next */ i += 1; } break; case OpForStep: s = node->value.symbol; eval( node->left ); n3 = popNumber(); /* step */ n2 = popNumber(); /* end */ n1 = popNumber(); /* start */ /* which direction? */ if (n3 > 0) { n2 += ALLOWABLE_ERROR; for( n4=n1; n2 >= n4; n4 += n3 ) { /* set loop variable */ pushNumber( n4 ); setVar( s ); /* run code */ eval( node->right ); /* special exit condition? */ if (exitForFlag) { exitForFlag = 0; break; } else if (continueFlag) { continueFlag = 0; } /* get loop value (in case it changed) */ getVar( s ); n4 = popNumber(); } } else { n2 -= ALLOWABLE_ERROR; for( n4=n1; n2 <= n4; n4 += n3 ) { /* set loop variable */ pushNumber( n4 ); setVar( s ); /* run code */ eval( node->right ); /* special exit condition? */ if (exitForFlag) { exitForFlag = 0; break; } else if (continueFlag) { continueFlag = 0; } /* get loop value (in case it changed) */ getVar( s ); n4 = popNumber(); } } break; case OpFunction: case OpFunctionCall: callFunction( node ); break; case OpInitArray: if (node->left == NULL) { createDynamicArray( node->value.symbol ); } else { eval( node->left ); createStaticArray( node->value.symbol ); } break; case OpInput: if (node->value.iValue == 1) { eval( node->left ); i = (int)popNumber(); string1 = fileLineInput( i ); pushString( string1 ); } else { /* command line */ ePrintf( Runtime, "Input statement is not currently supported" ); } break; case OpInt: pushNumber( node->value.iValue ); break; case OpMethod: case OpMethodCall: /* the index */ eval( node->left ); n1 = popNumber(); /* method name */ string1 = node->value.string; /* mark start of created objects */ pushCreateStack( 0 ); /* args */ n2 = tos; eval( node->right ); argCount = (int)(tos - n2); /* resolve and run method */ resolveMethod( (int)n1, string1 ); /* drop result? */ if (node->op == OpMethodCall) { dropTos(); } /* destroy created objects */ clearCreateStack(); break; case OpMod: eval( node->left ); eval( node->right ); n2 = popNumber(); n1 = popNumber(); //pushNumber( (long)n1 % (long)n2 ); pushNumber( fmod(n1,n2) ); break; case OpMul: eval( node->left ); eval( node->right ); n2 = popNumber(); n1 = popNumber(); pushNumber( n1 * n2 ); break; case OpOpen: /* file name */ eval( node->left ); string1 = popString(); /* mode */ i = node->value.iValue; /* file number */ eval( node->right ); n1 = popNumber(); fileOpen( string1, i, (int)n1 ); free( string1 ); break; case OpOr: /* short circuit */ eval( node->left ); if (popNumber()) { pushNumber( (Number)1 ); } else { eval( node->right ); if (popNumber()) { pushNumber( (Number)1 ); } else { pushNumber( (Number)0 ); } } break; case OpOrBits: eval( node->left ); eval( node->right); i = popNumber(); j = popNumber(); pushNumber( i | j ); break; case OpIDiv: eval( node->left ); eval( node->right ); n2 = popNumber(); n1 = popNumber(); /* check for division by zero */ if (n2 == 0.0) { ePrintf( Runtime, "Division by zero" ); } pushNumber( floor(n1 / n2) ); break; case OpIf: n = node->left; /* test */ eval( n->left ); n1 = popNumber(); if (n1 != 0) { /* true portion */ eval( n->right ); } else { /* false portion */ eval( node->right ); } break; case OpIfTrue: ePrintf( Runtime, "OpIfTrue: internal error" ); break; case OpIn: /* evaluate key */ eval( node->left ); /* look for it in array */ pushNumber( inArray( node->value.symbol ) ); break; case OpInv: ePrintf( Runtime, "Inv is not implemented yet" ); break; case OpNegate: eval( node->left ); n1 = popNumber(); pushNumber( -n1 ); break; case OpNew: case OpNewTmp: /* mark start of created objects */ pushCreateStack( 0 ); /* the args */ n1 = tos; eval( node->left ); argCount = (int)(tos - n1); runMethod( node->value.symbol->klass, "new" ); /* destroy created objects *before* adding new object to stack */ clearCreateStack(); /* add new object to create stack? */ if (node->op == OpNewTmp) { /* track on stack */ copyStackItem( tos ); pushCreateStack( (int)popNumber() ); } break; case OpNoOp: break; case OpNot: eval( node->left ); n1 = popNumber(); pushNumber( !n1 ); break; case OpPower: eval( node->left ); eval( node->right ); n2 = popNumber(); n1 = popNumber(); pushNumber( pow( n1, n2 ) ); break; case OpPrint: if (node->left == NULL) { i = 0; } else { eval( node->left ); i = (int)popNumber(); } node = node->right; /* empty print statement */ if (node == NULL) { if (i==0) { eConsole("\n"); } else { filePrintString( i, "\n" ); } } /* process nodes */ while(node != NULL) { /* data value */ if (node->left != NULL) { eval( node->left ); string1 = popString(); if (i==0) { eConsole("%s", string1 ); } else { filePrintString( i, string1 ); } eFree( string1 ); } /* field delimiter */ switch (node->value.iValue) { case PRINT_TAB: if (i==0) { eConsole("\t"); } else { filePrintString( i, "\t" ); } break; case PRINT_NEWLINE: if (i==0) { eConsole("\n"); } else { filePrintString( i, "\n" ); } break; default: /* no action */ break; } /* link */ node = node->right; } break; case OpReturnValue: eval( node->left ); setReturn(); exitRoutineFlag = 1; break; case OpReturnSetValue: eval( node->left ); setReturn(); break; case OpShl: eval( node->left ); eval( node->right ); n2 = popNumber(); n1 = popNumber(); pushNumber( (long)n1 << (long)n2 ); break; case OpShr: eval( node->left ); eval( node->right ); n2 = popNumber(); n1 = popNumber(); pushNumber( (long)n1 >> (long)n2 ); break; case OpString: pushStringCopy( node->value.string ); break; case OpSub: eval( node->left ); eval( node->right ); n2 = popNumber(); n1 = popNumber(); pushNumber( n1 - n2 ); break; case OpUndefined: ePrintf( Runtime, "Opcode is undefined" ); break; case OpVar: /* check type */ getVar( node->value.symbol ); if (getStackType(tos) == DATA_UNDEFINED) { ePrintf( Runtime, "the value of %s is undefined", node->value.symbol->name ); } break; case OpWhile: while (1) { /* test */ eval( node->left ); if (!popNumber()){ break; } /* code */ eval( node->right ); if (exitWhileFlag != 0) { exitWhileFlag = 0; break; } else if (continueFlag) { continueFlag = 0; } } break; case OpXor: eval( node->left ); eval( node->right ); n2 = popNumber(); n1 = popNumber(); pushNumber( (long)n1 ^ (long)n2 ); break; default: ePrintf( Runtime, "Unknown Opcode: %d", node->op ); } }
static EjsVar *invokeArrayOperator(Ejs *ejs, EjsVar *lhs, int opcode, EjsVar *rhs) { EjsVar *result; if (rhs == 0 || lhs->type != rhs->type) { if ((result = coerceArrayOperands(ejs, lhs, opcode, rhs)) != 0) { return result; } } switch (opcode) { case EJS_OP_COMPARE_EQ: case EJS_OP_COMPARE_STRICTLY_EQ: case EJS_OP_COMPARE_LE: case EJS_OP_COMPARE_GE: return (EjsVar*) ejsCreateBoolean(ejs, (lhs == rhs)); case EJS_OP_COMPARE_NE: case EJS_OP_COMPARE_STRICTLY_NE: case EJS_OP_COMPARE_LT: case EJS_OP_COMPARE_GT: return (EjsVar*) ejsCreateBoolean(ejs, !(lhs == rhs)); /* * Unary operators */ case EJS_OP_COMPARE_NOT_ZERO: return (EjsVar*) ejs->trueValue; case EJS_OP_COMPARE_UNDEFINED: case EJS_OP_COMPARE_NULL: case EJS_OP_COMPARE_FALSE: case EJS_OP_COMPARE_TRUE: case EJS_OP_COMPARE_ZERO: return (EjsVar*) ejs->falseValue; case EJS_OP_LOGICAL_NOT: case EJS_OP_NOT: case EJS_OP_NEG: return (EjsVar*) ejs->oneValue; /* * Binary operators */ case EJS_OP_DIV: case EJS_OP_MUL: case EJS_OP_REM: case EJS_OP_SHR: case EJS_OP_USHR: case EJS_OP_XOR: return (EjsVar*) ejs->zeroValue; #if BLD_FEATURE_EJS_LANG >= EJS_SPEC_PLUS /* * Operator overload */ case EJS_OP_ADD: result = (EjsVar*) ejsCreateArray(ejs, 0); pushArray(ejs, (EjsArray*) result, 1, (EjsVar**) &lhs); pushArray(ejs, (EjsArray*) result, 1, (EjsVar**) &rhs); return result; case EJS_OP_AND: return (EjsVar*) makeIntersection(ejs, (EjsArray*) lhs, (EjsArray*) rhs); case EJS_OP_OR: return (EjsVar*) makeUnion(ejs, (EjsArray*) lhs, (EjsArray*) rhs); case EJS_OP_SHL: return pushArray(ejs, (EjsArray*) lhs, 1, &rhs); case EJS_OP_SUB: return (EjsVar*) removeArrayElements(ejs, (EjsArray*) lhs, (EjsArray*) rhs); #endif default: ejsThrowTypeError(ejs, "Opcode %d not implemented for type %s", opcode, lhs->type->qname.name); return 0; } mprAssert(0); }
static EjsAny *invokeArrayOperator(Ejs *ejs, EjsAny *lhs, int opcode, EjsAny *rhs) { EjsAny *result; if (rhs == 0 || TYPE(lhs) != TYPE(rhs)) { if ((result = coerceArrayOperands(ejs, lhs, opcode, rhs)) != 0) { return result; } } switch (opcode) { case EJS_OP_COMPARE_EQ: case EJS_OP_COMPARE_STRICTLY_EQ: case EJS_OP_COMPARE_LE: case EJS_OP_COMPARE_GE: return ejsCreateBoolean(ejs, (lhs == rhs)); case EJS_OP_COMPARE_NE: case EJS_OP_COMPARE_STRICTLY_NE: case EJS_OP_COMPARE_LT: case EJS_OP_COMPARE_GT: return ejsCreateBoolean(ejs, !(lhs == rhs)); /* Unary operators */ case EJS_OP_COMPARE_NOT_ZERO: return ESV(true); case EJS_OP_COMPARE_UNDEFINED: case EJS_OP_COMPARE_NULL: case EJS_OP_COMPARE_FALSE: case EJS_OP_COMPARE_TRUE: case EJS_OP_COMPARE_ZERO: return ESV(false); case EJS_OP_LOGICAL_NOT: case EJS_OP_NOT: case EJS_OP_NEG: return ESV(one); /* Binary operators */ case EJS_OP_DIV: case EJS_OP_MUL: case EJS_OP_REM: case EJS_OP_SHR: case EJS_OP_USHR: case EJS_OP_XOR: return ESV(zero); /* Operator overload */ case EJS_OP_ADD: result = ejsCreateArray(ejs, 0); pushArray(ejs, result, 1, &lhs); pushArray(ejs, result, 1, &rhs); return result; case EJS_OP_AND: return makeIntersection(ejs, lhs, rhs); case EJS_OP_OR: return makeUnion(ejs, lhs, rhs); case EJS_OP_SHL: return pushArray(ejs, lhs, 1, &rhs); case EJS_OP_SUB: return ejsRemoveItems(ejs, lhs, rhs); default: ejsThrowTypeError(ejs, "Opcode %d not implemented for type %@", opcode, TYPE(lhs)->qname.name); return 0; } assert(0); }
void cmdCD(cmdLog* cLog, cmdLine* line, char* incoming) { pushArray(cLog, incoming); if(chdir(line->arguments[1])!=0) perror("illegal directory"); }
List* execString(cmdLog* cLog, List* env, char* incoming) { cmdLine* line; cmdLine* firstLine; cmdLine* currLine; int pipeCounter = 0; int * pid; int pid2; int i; int j; int **pipefd; line = parseCmdLines(incoming); currLine = line; firstLine = line; if (line==NULL || !strcmp(line->arguments[0], "quit")) { freeList(env); freeCmdLines(line); return (List*)-1; } line= cmdEnvReplace(env, line); if (!strcmp(line->arguments[0], "assign")) { env= cmdAssign(env, line); } else if (!strcmp(line->arguments[0], "unassign")) { env= cmdUnassign(env, line); } else if (!strcmp(line->arguments[0], "cd")) { cmdCD(cLog, line, incoming); } else if (line->arguments[0][0]=='!') { env= cmdReadLog(cLog, env, line); } else { j = 0; pushArray(cLog, incoming); if(line->next) { while(currLine != NULL) { currLine = currLine->next; pipeCounter++; } pipefd= createPipes(pipeCounter-1); pid = (int *)malloc(pipeCounter * sizeof(int)); if (!(pid[j] =fork())) { /* first son*/ close(STDOUT_FILENO); /* Close unused write end */ dup(rightPipe(pipefd, line)[1]); close(rightPipe(pipefd, line)[1]); coreExec(cLog, env, line); } close(rightPipe(pipefd, line)[1]); j++; line = line->next; for (i=0; i<pipeCounter-2; i++) { if (!(pid[j] =fork())) { /* first son*/ close(STDOUT_FILENO); /* Close unused write end */ dup(rightPipe(pipefd, line)[1]); close(rightPipe(pipefd, line)[1]); close(STDIN_FILENO); dup(leftPipe(pipefd, line)[0]); close(leftPipe(pipefd, line)[0]); coreExec(cLog, env, line); } close(leftPipe(pipefd, line)[0]); close(rightPipe(pipefd, line)[1]); j++; line = line->next; } if (!(pid[j] =fork())) { /* first son*/ close(STDIN_FILENO); /* Close unused write end */ dup(leftPipe(pipefd, line)[0]); close(leftPipe(pipefd, line)[0]); coreExec(cLog, env, line); } close(leftPipe(pipefd, line)[0]); for(i=0; i<=j; i++) { if(line->blocking!=0) { waitpid(pid[i],0,0); } } releasePipes(pipefd, pipeCounter-1); } else { if (!(pid2=fork())) { coreExec(cLog, env, line); } } if(line->blocking!=0) { waitpid(pid2,0,0); } } freeCmdLines(firstLine); free(pid); return env; }