command_t makeBaseCommand(command_t command, char *input, char *output) { if (!command) { command = AllocateCommand(); } command->input = input; command->output = output; return command; }
void hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags) { ULONG capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember-1); PCommand pCmd; UINT result; int needsync=0, retry=0, needdelete=0; void *buffer = NULL; _VBUS_INST(&pAdapter->VBus) if (pArray->u.array.rf_broken==1 || pArray->u.array.RebuildSectors>=capacity) return; mtx_lock(&pAdapter->lock); switch(flags) { case DUPLICATE: case REBUILD_PARITY: if(pArray->u.array.rf_rebuilding == 0) { pArray->u.array.rf_rebuilding = 1; hpt_printk(("Rebuilding started.\n")); ioctl_ReportEvent(ET_REBUILD_STARTED, pArray); } break; case INITIALIZE: if(pArray->u.array.rf_initializing == 0) { pArray->u.array.rf_initializing = 1; hpt_printk(("Initializing started.\n")); ioctl_ReportEvent(ET_INITIALIZE_STARTED, pArray); } break; case VERIFY: if(pArray->u.array.rf_verifying == 0) { pArray->u.array.rf_verifying = 1; hpt_printk(("Verifying started.\n")); ioctl_ReportEvent(ET_VERIFY_STARTED, pArray); } break; } retry_cmd: pCmd = AllocateCommand(_VBUS_P0); HPT_ASSERT(pCmd); pCmd->cf_control = 1; End_Job = 0; if (pArray->VDeviceType==VD_RAID_1) { #define MAX_REBUILD_SECTORS 0x40 /* take care for discontinuous buffer in R1ControlSgl */ buffer = malloc(SECTOR_TO_BYTE(MAX_REBUILD_SECTORS), M_DEVBUF, M_NOWAIT); if(!buffer) { FreeCommand(_VBUS_P pCmd); hpt_printk(("can't allocate rebuild buffer\n")); goto fail; } switch(flags) { case DUPLICATE: pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD; pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS; break; case VERIFY: pCmd->uCmd.R1Control.Command = CTRL_CMD_VERIFY; pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS/2; break; case INITIALIZE: pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD; pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS; break; } pCmd->uCmd.R1Control.Lba = pArray->u.array.RebuildSectors; if (capacity - pArray->u.array.RebuildSectors < pCmd->uCmd.R1Control.nSectors) pCmd->uCmd.R1Control.nSectors = capacity - pArray->u.array.RebuildSectors; pCmd->uCmd.R1Control.Buffer = buffer; pCmd->pfnBuildSgl = R1ControlSgl; } else if (pArray->VDeviceType==VD_RAID_5) { switch(flags) { case DUPLICATE: case REBUILD_PARITY: pCmd->uCmd.R5Control.Command = CTRL_CMD_REBUILD; break; case VERIFY: pCmd->uCmd.R5Control.Command = CTRL_CMD_VERIFY; break; case INITIALIZE: pCmd->uCmd.R5Control.Command = CTRL_CMD_INIT; break; } pCmd->uCmd.R5Control.StripeLine=pArray->u.array.RebuildSectors>>pArray->u.array.bArBlockSizeShift; } else
IOReturn SATSMARTUserClient::ReadDataThresholds (UInt32 * dataOut, IOByteCount * outputSize) { IOReturn status = kIOReturnSuccess; IOSATCommand * command = NULL; IOMemoryDescriptor * buffer = NULL; DEBUG_LOG("%s[%p]::%s\n", getClassName(), this, __FUNCTION__); if (!dataOut || !outputSize || *outputSize != sizeof ( ATASMARTDataThresholds ) ) { return kIOReturnBadArgument; } fOutstandingCommands++; if ( isInactive ( ) ) { status = kIOReturnNoDevice; goto ErrorExit; } fProvider->retain ( ); command = AllocateCommand ( ); if ( command == NULL ) { status = kIOReturnNoResources; goto ReleaseProvider; } buffer = IOMemoryDescriptor::withAddress(dataOut, sizeof ( ATASMARTDataThresholds ), kIODirectionIn); if ( buffer == NULL ) { status = kIOReturnNoResources; goto ReleaseCommand; } status = buffer->prepare ( ); if ( status != kIOReturnSuccess ) { goto ReleaseBuffer; } command->setBuffer ( buffer ); command->setByteCount ( sizeof ( ATASMARTDataThresholds ) ); command->setFeatures ( kFeaturesRegisterReadDataThresholds ); command->setOpcode ( kATAFnExecIO ); command->setTimeoutMS ( kATAThirtySecondTimeoutInMS ); command->setCylLo ( kSMARTMagicCylinderLoValue ); command->setCylHi ( kSMARTMagicCylinderHiValue ); command->setCommand ( kATAcmdSMART ); command->setFlags ( mATAFlagIORead ); status = SendSMARTCommand ( command ); if ( status == kIOReturnIOError ) { if ( command->getEndErrorReg ( ) & 0x04 ) { ERROR_LOG ( "ReadDataThresholds unsupported\n" ); status = kIOReturnUnsupported; } if ( command->getEndErrorReg ( ) & 0x10 ) { ERROR_LOG ( "ReadDataThresholds Not readable\n" ); status = kIOReturnNotReadable; } } *outputSize = buffer->getLength(); buffer->complete ( ); ReleaseBuffer: buffer->release ( ); buffer = NULL; ReleaseCommand: DeallocateCommand ( command ); command = NULL; ReleaseProvider: fProvider->release ( ); ErrorExit: fOutstandingCommands--; DEBUG_LOG("%s[%p]::%s result %d\n", getClassName(), this, __FUNCTION__, status); return status; }
IOReturn SATSMARTUserClient::ExecuteOfflineImmediate ( UInt32 extendedTest ) { IOReturn status = kIOReturnSuccess; IOSATCommand * command = NULL; DEBUG_LOG("%s[%p]::%s\n", getClassName(), this, __FUNCTION__); fOutstandingCommands++; if ( isInactive ( ) ) { status = kIOReturnNoDevice; goto ErrorExit; } fProvider->retain ( ); command = AllocateCommand ( ); if ( command == NULL ) { status = kIOReturnNoResources; goto ReleaseProvider; } command->setFeatures ( kFeaturesRegisterExecuteOfflineImmed ); command->setOpcode ( kATAFnExecIO ); command->setTimeoutMS ( kATAThirtySecondTimeoutInMS ); command->setSectorNumber ( ( extendedTest == 0 ) ? 0x01 : 0x02 ); command->setCylLo ( kSMARTMagicCylinderLoValue ); command->setCylHi ( kSMARTMagicCylinderHiValue ); command->setCommand ( kATAcmdSMART ); status = SendSMARTCommand ( command ); if ( status == kIOReturnIOError ) { if ( command->getEndErrorReg ( ) & 0x04 ) { ERROR_LOG ( "Execute Offline Immediate unsupported\n" ); status = kIOReturnUnsupported; } } DeallocateCommand ( command ); command = NULL; ReleaseProvider: fProvider->release ( ); ErrorExit: fOutstandingCommands--; DEBUG_LOG("%s[%p]::%s result %d\n", getClassName(), this, __FUNCTION__, status); return status; }
IOReturn SATSMARTUserClient::ReturnStatus ( UInt32 * exceededCondition ) { IOReturn status = kIOReturnSuccess; IOSATCommand * command = NULL; UInt8 lbaMid = kSMARTMagicCylinderLoValue; UInt8 lbaHigh = kSMARTMagicCylinderHiValue; DEBUG_LOG("%s[%p]::%s\n", getClassName(), this, __FUNCTION__); fOutstandingCommands++; if ( isInactive ( ) ) { status = kIOReturnNoDevice; goto ErrorExit; } fProvider->retain ( ); command = AllocateCommand ( ); if ( command == NULL ) { status = kIOReturnNoResources; goto ReleaseProvider; } command->setFeatures ( kFeaturesRegisterReturnStatus ); command->setOpcode ( kATAFnExecIO ); command->setTimeoutMS ( kATAThirtySecondTimeoutInMS ); command->setCylLo ( lbaMid ); command->setCylHi ( lbaHigh ); command->setCommand ( kATAcmdSMART ); command->setRegMask ( ( ataRegMask ) ( mATACylinderHiValid | mATACylinderLoValid ) ); command->setFlags ( mATAFlagTFAccessResult ); status = SendSMARTCommand ( command ); lbaMid = command->getCylLo ( ); lbaHigh = command->getCylHi ( ); if ( status == kIOReturnSuccess ) { // Check if threshold exceeded if ( ( lbaMid == kSMARTReturnStatusValidLoValue ) && ( lbaHigh == kSMARTReturnStatusValidHiValue ) ) { *exceededCondition = 1; } else { *exceededCondition = 0; } } if ( status == kIOReturnIOError ) { if ( command->getEndErrorReg ( ) & 0x04 ) { ERROR_LOG ( "Return Status unsupported\n" ); status = kIOReturnUnsupported; } } DeallocateCommand ( command ); command = NULL; ReleaseProvider: fProvider->release ( ); ErrorExit: fOutstandingCommands--; DEBUG_LOG("%s[%p]::%s result %d\n", getClassName(), this, __FUNCTION__, status); return status; }
IOReturn SATSMARTUserClient::EnableDisableAutoSave ( UInt32 enable ) { IOReturn status = kIOReturnSuccess; IOSATCommand * command; DEBUG_LOG("%s[%p]::%s\n", getClassName(), this, __FUNCTION__); fOutstandingCommands++; if ( isInactive ( ) ) { status = kIOReturnNoDevice; goto ErrorExit; } fProvider->retain ( ); command = AllocateCommand ( ); if ( command == NULL ) { status = kIOReturnNoResources; goto ReleaseProvider; } if ( enable == 0 ) { // They want to disable SMART autosave operations. command->setSectorCount ( kSMARTAutoSaveDisable ); } else { // They want to enable SMART autosave operations. command->setSectorCount ( kSMARTAutoSaveEnable ); } command->setFeatures ( kFeaturesRegisterEnableDisableAutoSave ); command->setOpcode ( kATAFnExecIO ); command->setTimeoutMS ( kATAThirtySecondTimeoutInMS ); command->setCylLo ( kSMARTMagicCylinderLoValue ); command->setCylHi ( kSMARTMagicCylinderHiValue ); command->setCommand ( kATAcmdSMART ); status = SendSMARTCommand ( command ); if ( status == kIOReturnIOError ) { if ( command->getEndErrorReg ( ) & 0x04 ) { ERROR_LOG ( "Enable/Disable autosave unsupported\n" ); status = kIOReturnUnsupported; } } DeallocateCommand ( command ); command = NULL; ReleaseProvider: fProvider->release ( ); ErrorExit: fOutstandingCommands--; DEBUG_LOG("%s[%p]::%s result %d\n", getClassName(), this, __FUNCTION__, status); return status; }
IOReturn SATSMARTUserClient::GetIdentifyData (UInt32 * dataOut, IOByteCount * outputSize) { IOReturn status = kIOReturnSuccess; IOSATCommand * command = NULL; IOMemoryDescriptor * buffer = NULL; DEBUG_LOG("%s[%p]::%s %p(%ld)\n", getClassName(), this, __FUNCTION__, dataOut, (long)(outputSize)); if (!dataOut || !outputSize || *outputSize < kATADefaultSectorSize ) { return kIOReturnBadArgument; } fOutstandingCommands++; if ( isInactive ( ) ) { status = kIOReturnNoDevice; goto ErrorExit; } fProvider->retain ( ); command = AllocateCommand ( ); if ( command == NULL ) { status = kIOReturnNoResources; goto ReleaseProvider; } buffer = IOMemoryDescriptor::withAddress(dataOut, kATADefaultSectorSize, kIODirectionIn); if ( buffer == NULL ) { status = kIOReturnNoResources; goto ReleaseCommand; } status = buffer->prepare ( ); if ( status != kIOReturnSuccess ) { goto ReleaseBuffer; } command->setBuffer ( buffer ); command->setByteCount ( kATADefaultSectorSize ); command->setTransferChunkSize ( kATADefaultSectorSize ); command->setOpcode ( kATAFnExecIO ); command->setTimeoutMS ( kATAThirtySecondTimeoutInMS ); command->setCommand ( kATAcmdDriveIdentify ); command->setFlags ( mATAFlagIORead ); command->setRegMask ( ( ataRegMask ) ( mATAErrFeaturesValid | mATAStatusCmdValid ) ); status = SendSMARTCommand ( command ); if ( status == kIOReturnSuccess ) { #if defined(__BIG_ENDIAN__) UInt8 * bufferToCopy = identifyDataPtr; // The identify device info needs to be byte-swapped on big-endian (ppc) // systems becuase it is data that is produced by the drive, read across a // 16-bit little-endian PCI interface, directly into a big-endian system. // Regular data doesn't need to be byte-swapped because it is written and // read from the host and is intrinsically byte-order correct. IOByteCount index; UInt8 temp; UInt8 * firstBytePtr; UInt8 * identifyDataPtr = ( UInt8 * )dataOut; for ( index = 0; index < buffer->getLength ( ); index += 2 ) { firstBytePtr = identifyDataPtr; // save pointer temp = *identifyDataPtr++; // Save Byte0, point to Byte1 *firstBytePtr = *identifyDataPtr; // Byte0 = Byte1 *identifyDataPtr++ = temp; // Byte1 = Byte0 } #endif *outputSize = buffer->getLength ( ); DEBUG_LOG("%s[%p]::%s cpy %p %p\n", getClassName(), this, __FUNCTION__, (void*)*outputSize, (void*)buffer->getLength()); } ReleaseBufferPrepared: buffer->complete ( ); ReleaseBuffer: buffer->release ( ); buffer = NULL; ReleaseCommand: DeallocateCommand ( command ); command = NULL; ReleaseProvider: fProvider->release ( ); ErrorExit: fOutstandingCommands--; DEBUG_LOG("%s[%p]::%s result %x\n", getClassName(), this, __FUNCTION__, status); return status; }
IOReturn SATSMARTUserClient::WriteLogAtAddress ( ATASMARTWriteLogStruct * writeLogData, UInt32 inStructSize ) { IOReturn status = kIOReturnSuccess; IOSATCommand * command = NULL; IOMemoryDescriptor * buffer = NULL; DEBUG_LOG("%s[%p]::%s\n", getClassName(), this, __FUNCTION__); if ( inStructSize != sizeof ( ATASMARTWriteLogStruct ) || writeLogData->numSectors > 16 || writeLogData->data_length > kSATMaxDataSize) { return kIOReturnBadArgument; } fOutstandingCommands++; if ( isInactive ( ) ) { status = kIOReturnNoDevice; goto ErrorExit; } fProvider->retain ( ); command = AllocateCommand ( ); if ( command == NULL ) { status = kIOReturnNoResources; goto ReleaseProvider; } //buffer = IOMemoryDescriptor::withAddress(writeLogData->buffer, writeLogData->bufferSize, kIODirectionOut); buffer = IOMemoryDescriptor::withAddressRange(writeLogData->data_pointer, writeLogData->data_length, kIODirectionOut, fTask); if ( buffer == NULL ) { status = kIOReturnVMError; goto ReleaseCommand; } status = buffer->prepare ( ); if ( status != kIOReturnSuccess ) { goto ReleaseBuffer; } command->setBuffer ( buffer ); command->setByteCount ( writeLogData->data_length ); command->setFeatures ( kFeaturesRegisterWriteLogAtAddress ); command->setOpcode ( kATAFnExecIO ); command->setTimeoutMS ( kATAThirtySecondTimeoutInMS ); command->setSectorCount ( writeLogData->numSectors ); command->setSectorNumber ( writeLogData->logAddress ); command->setCylLo ( kSMARTMagicCylinderLoValue ); command->setCylHi ( kSMARTMagicCylinderHiValue ); command->setCommand ( kATAcmdSMART ); command->setFlags ( mATAFlagIOWrite ); status = SendSMARTCommand ( command ); if ( status == kIOReturnIOError ) { if ( command->getEndErrorReg ( ) & 0x04 ) { ERROR_LOG ( "WriteLogAtAddress %d unsupported\n", writeLogData->logAddress ); status = kIOReturnUnsupported; } if ( command->getEndErrorReg ( ) & 0x10 ) { ERROR_LOG ( "WriteLogAtAddress %d unwriteable\n", writeLogData->logAddress ); status = kIOReturnNotWritable; } } buffer->complete ( ); ReleaseBuffer: buffer->release ( ); buffer = NULL; ReleaseCommand: DeallocateCommand ( command ); command = NULL; ReleaseProvider: fProvider->release ( ); ErrorExit: fOutstandingCommands--; DEBUG_LOG("%s[%p]::%s result %d\n", getClassName(), this, __FUNCTION__, status); return status; }
IOReturn SATSMARTUserClient::ReadLogAtAddress ( ATASMARTReadLogStruct * structIn, void * structOut, IOByteCount inStructSize, IOByteCount *outStructSize) { IOReturn status = kIOReturnSuccess; IOSATCommand * command = NULL; IOMemoryDescriptor * buffer = NULL; DEBUG_LOG("%s[%p]::%s %p(%ld) %p(%ld)\n", getClassName(), this, __FUNCTION__, structIn, (long)inStructSize, structOut, (long)(outStructSize)); if ( inStructSize != sizeof ( ATASMARTReadLogStruct ) || !outStructSize || *outStructSize < 1) { return kIOReturnBadArgument; } fOutstandingCommands++; if ( isInactive ( ) ) { status = kIOReturnNoDevice; goto ErrorExit; } fProvider->retain ( ); command = AllocateCommand ( ); if ( command == NULL ) { status = kIOReturnNoResources; goto ReleaseProvider; } buffer = IOMemoryDescriptor::withAddress (structOut, *outStructSize, kIODirectionIn); if ( buffer == NULL ) { status = kIOReturnNoResources; goto ReleaseCommand; } status = buffer->prepare ( ); DEBUG_LOG("%s[%p]::%s status %x\n", getClassName(), this, __FUNCTION__, status); if ( status != kIOReturnSuccess ) { goto ReleaseBuffer; } command->setBuffer ( buffer ); command->setByteCount ( buffer->getLength()); command->setFeatures ( kFeaturesRegisterReadLogAtAddress ); command->setOpcode ( kATAFnExecIO ); command->setTimeoutMS ( kATAThirtySecondTimeoutInMS ); command->setSectorCount ( structIn->numSectors ); command->setSectorNumber ( structIn->logAddress ); command->setCylLo ( kSMARTMagicCylinderLoValue ); command->setCylHi ( kSMARTMagicCylinderHiValue ); command->setCommand ( kATAcmdSMART ); command->setFlags ( mATAFlagIORead ); status = SendSMARTCommand ( command ); if ( status == kIOReturnIOError ) { if ( command->getEndErrorReg ( ) & 0x04 ) { ERROR_LOG ( "ReadLogAtAddress %d unsupported\n", structIn->logAddress ); status = kIOReturnUnsupported; } if ( command->getEndErrorReg ( ) & 0x10 ) { ERROR_LOG ( "ReadLogAtAddress %d unreadable\n", structIn->logAddress ); status = kIOReturnNotReadable; } } *outStructSize = buffer->getLength(); buffer->complete ( ); ReleaseBuffer: buffer->release ( ); buffer = NULL; ReleaseCommand: DeallocateCommand ( command ); command = NULL; ReleaseProvider: fProvider->release ( ); ErrorExit: fOutstandingCommands--; DEBUG_LOG("%s[%p]::%s result %d\n", getClassName(), this, __FUNCTION__, status); return status; }
command_t makeCommandStreamUtil(int (*get_next_byte) (void *), void *get_next_byte_argument, STATE *state) { char **tokenPTR = checked_malloc(sizeof(char**)); char *token = NULL; int len = 0; TOKENTYPE type; command_t command = NULL; char *input = NULL, *output = NULL; type = readNextToken(tokenPTR, &len, get_next_byte, get_next_byte_argument); if (type == NOT_DEFINED) { free(tokenPTR); return NULL; } else if (type == O_PAR) { token = "("; } else { token = *tokenPTR; } command = AllocateCommand(); if (!command) { return NULL; } if (!strncmp(token, "then", 4)) { if (!(pop() == IF)) { printErr(); } push(THEN); *state = THEN; goto ret_null; } else if (!strncmp(token, "done", 4)) { if (!(pop() == DO)) { printErr(); } *state = DONE; CScount--; goto ret_null; } else if (!strncmp(token, "do", 4)) { STATE tmp = pop(); if (!((tmp == WHILE) || (tmp == UNTIL))) { printErr(); } push(DO); *state = DO; goto ret_null; } else if (!strncmp(token, "else", 4)) { if (!(pop() == THEN)) { printErr(); } push(ELSE); *state = ELSE; goto ret_null; } else if (!strncmp(token, "fi", 4)) { STATE tmp = pop(); if (!((tmp == THEN) || (tmp == ELSE))) { printErr(); } CScount--; *state = FI; goto ret_null; } else if (!strncmp(token, ")", 1)) { CScount--; *state = CLOSE_PAR; goto ret_null; } else if (!strncmp(token, "if", 2)) { push(IF); CScount++; command = makeCommand(command, NULL, IF_COMMAND, input, output); free(tokenPTR); command->u.command[0] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); while (*state != THEN) { if (!makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state)) { type = NOT_DEFINED; break; } } if (type == NOT_DEFINED && *state != THEN) { return NULL; } command->u.command[1] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); if (*state != ELSE && *state != FI) { // HANDLE error; ; } else if (*state == ELSE || (*state == FI && CScount)) { command->u.command[2] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); } else { command->u.command[2] = NULL; } } else if (!strncmp(token, "while", 5)) { push(WHILE); (CScount)++; command = makeCommand(command, NULL, WHILE_COMMAND, input, output); free(tokenPTR); command->u.command[0] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); if (*state != DO) { // Handle Error ; } command->u.command[1] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); if (*state != DONE) { // HANDLE error; ; } else if (*state == DONE) { if (checkRedirection(get_next_byte, get_next_byte_argument)) { fillRedirectionOperands(&command->input, &command->output, get_next_byte, get_next_byte_argument); } command->u.command[2] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); /* if (command->u.command[2]) { */ /* command_t newCommand = makeCommand(NULL, NULL, SEQUENCE_COMMAND, */ /* NULL, NULL); */ /* newCommand->u.command[0] = command->u.command[1]; */ /* newCommand->u.command[1] = command->u.command[2]; */ /* command->u.command[1] = newCommand; */ /* command->u.command[2] = NULL; */ /* } */ } else { command->u.command[2] = NULL; } } else if (!strncmp(token, "until", 5)) { push(UNTIL); (CScount)++; command = makeCommand(command, NULL, UNTIL_COMMAND, input, output); free(tokenPTR); command->u.command[0] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); if (*state != DO) { // Handle Error ; } command->u.command[1] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); if (*state != DONE) { // HANDLE error; ; } else if (*state == DONE) { if (checkRedirection(get_next_byte, get_next_byte_argument)) { fillRedirectionOperands(&command->input, &command->output, get_next_byte, get_next_byte_argument); } command->u.command[2] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); /* if (command->u.command[2]) { */ /* command_t newCommand = makeCommand(NULL, NULL, SEQUENCE_COMMAND, */ /* NULL, NULL); */ /* newCommand->u.command[0] = command->u.command[1]; */ /* newCommand->u.command[1] = command->u.command[2]; */ /* command->u.command[1] = newCommand; */ /* command->u.command[2] = NULL; */ /* } */ } else { command->u.command[2] = NULL; } } else if (!strncmp(token, "(", 1)) { CScount++; command = makeCommand(command, NULL, SUBSHELL_COMMAND, input, output); free(tokenPTR); command->u.command[0] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); if (*state != CLOSE_PAR) { // Handle Error } else if (*state == CLOSE_PAR && CScount) { command->u.command[0] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); } } else { // SIMPLE_COMMAND while (1) { STATE prevState = *state; if (isKeyWordUpdate(token, state) && (prevState == COMMAND)) { removeWhiteSpace(token); command = makeSimpleCommand(command, tokenPTR, input, output); break; } if (type == REDIRECTION1 || type == REDIRECTION2) { type = fillRedirectionOperands(&input, &output, get_next_byte, get_next_byte_argument); // command = makeSimpleCommand(command, tokenPTR, input, output); // break; // type = readNextToken(tokenPTR, &len, get_next_byte, get_next_byte_argument); } else if (type == SPACE) { appendChar(token, ' '); type = readNextToken(tokenPTR, &len, get_next_byte, get_next_byte_argument); } else if (type == NEWLINE && !CScount) { command = makeSimpleCommand(command, tokenPTR, input, output); break; } else if (type == PIPE || type == SEMICOLON || type == NEWLINE) { removeWhiteSpace(token); if (((type == PIPE) || (type == SEMICOLON)) && !strlen(token)) { printErr(); } command = makeCommand(command, tokenPTR, type == PIPE ? PIPE_COMMAND : SEQUENCE_COMMAND, input, output); command->u.command[1] = makeCommandStreamUtil(get_next_byte, get_next_byte_argument, state); if (!command->u.command[1]) { command = convertToSimple(command); } break; } *state = COMMAND; } } return command; ret_null: free(command); free(tokenPTR); return NULL; }