static int lockSmrbt(SmRbt *rbt) { int result; result = sm_SemTake(rbt->lock); if (result < 0) { putErrmsg("Can't lock red-black table.", NULL); } return result; }
static void lockPartition(PartitionMap *map) { int selfTask; pthread_t selfThread; CHKVOID(map->status == MANAGED); selfTask = sm_TaskIdSelf(); selfThread = pthread_self(); if (map->ownerTask == selfTask && pthread_equal(map->ownerThread, selfThread)) { map->depth++; return; } CHKVOID(map->semaphore != -1); oK(sm_SemTake(map->semaphore)); map->ownerThread = selfThread; map->ownerTask = selfTask; map->depth = 1; }
static int ionWaitForZcoSpace(IonVdb *vdb) { int result; vdb->zcoClaimants += 1; result = sm_SemTake(vdb->zcoSemaphore); if (result == 0) { if (sm_SemEnded(vdb->zcoSemaphore)) { writeMemo("[i] ZCO space semaphore ended."); } else { vdb->zcoClaims -= 1; result = 1; } } return result; }
void psm_unmanage(PsmPartition partition) { PartitionMap *map; CHKVOID(partition); map = (PartitionMap *) (partition->space); if (map->status == MANAGED) { /* Wait for partition to be no longer in use; unmanage. */ sm_SemTake(map->semaphore); sm_SemDelete(map->semaphore); map->status = INITIALIZED; } /* Destroy space management structure if necessary. */ if (partition->freeNeeded) { free(partition); } }
int bp_receive(BpSAP sap, BpDelivery *dlvBuffer, int timeoutSeconds) { Sdr sdr = getIonsdr(); VEndpoint *vpoint; OBJ_POINTER(Endpoint, endpoint); Object dlvElt; Object bundleAddr; Bundle bundle; TimerParms timerParms; pthread_t timerThread; int result; char *dictionary; CHKERR(sap && dlvBuffer); if (timeoutSeconds < BP_BLOCKING) { putErrmsg("Illegal timeout interval.", itoa(timeoutSeconds)); return -1; } vpoint = sap->vpoint; sdr_begin_xn(sdr); if (vpoint->appPid != sm_TaskIdSelf()) { sdr_exit_xn(sdr); putErrmsg("Can't receive: not owner of endpoint.", itoa(vpoint->appPid)); return -1; } if (sm_SemEnded(vpoint->semaphore)) { sdr_exit_xn(sdr); writeMemo("[?] Endpoint has been stopped."); /* End task, but without error. */ return -1; } /* Get oldest bundle in delivery queue, if any; wait * for one if necessary. */ GET_OBJ_POINTER(sdr, Endpoint, endpoint, sdr_list_data(sdr, vpoint->endpointElt)); dlvElt = sdr_list_first(sdr, endpoint->deliveryQueue); if (dlvElt == 0) { sdr_exit_xn(sdr); if (timeoutSeconds == BP_POLL) { dlvBuffer->result = BpReceptionTimedOut; return 0; } /* Wait for semaphore to be given, either by the * deliverBundle() function or by timer thread. */ if (timeoutSeconds == BP_BLOCKING) { timerParms.interval = -1; } else /* This is a receive() with a deadline. */ { timerParms.interval = timeoutSeconds; timerParms.semaphore = vpoint->semaphore; if (pthread_create(&timerThread, NULL, timerMain, &timerParms) < 0) { putSysErrmsg("Can't enable interval timer", NULL); return -1; } } /* Take endpoint semaphore. */ if (sm_SemTake(vpoint->semaphore) < 0) { putErrmsg("Can't take endpoint semaphore.", NULL); return -1; } if (sm_SemEnded(vpoint->semaphore)) { writeMemo("[i] Endpoint has been stopped."); /* End task, but without error. */ return -1; } /* Have taken the semaphore, one way or another. */ sdr_begin_xn(sdr); dlvElt = sdr_list_first(sdr, endpoint->deliveryQueue); if (dlvElt == 0) /* Still nothing. */ { /* Either sm_SemTake() was interrupted * or else timer thread gave semaphore. */ sdr_exit_xn(sdr); if (timerParms.interval == 0) { /* Timer expired. */ dlvBuffer->result = BpReceptionTimedOut; pthread_join(timerThread, NULL); } else /* Interrupted. */ { dlvBuffer->result = BpReceptionInterrupted; if (timerParms.interval != -1) { pthread_cancel(timerThread); pthread_join(timerThread, NULL); } } return 0; } else /* Bundle was delivered. */ { if (timerParms.interval != -1) { pthread_cancel(timerThread); pthread_join(timerThread, NULL); } } } /* At this point, we have got a dlvElt and are in an SDR * transaction. */ bundleAddr = sdr_list_data(sdr, dlvElt); sdr_stage(sdr, (char *) &bundle, bundleAddr, sizeof(Bundle)); dictionary = retrieveDictionary(&bundle); if (dictionary == (char *) &bundle) { sdr_cancel_xn(sdr); putErrmsg("Can't retrieve dictionary.", NULL); return -1; } /* Now fill in the data indication structure. */ dlvBuffer->result = BpPayloadPresent; if (printEid(&bundle.id.source, dictionary, &dlvBuffer->bundleSourceEid) < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't print source EID.", NULL); return -1; } dlvBuffer->bundleCreationTime.seconds = bundle.id.creationTime.seconds; dlvBuffer->bundleCreationTime.count = bundle.id.creationTime.count; dlvBuffer->adminRecord = bundle.bundleProcFlags & BDL_IS_ADMIN; dlvBuffer->adu = zco_add_reference(sdr, bundle.payload.content); dlvBuffer->ackRequested = bundle.bundleProcFlags & BDL_APP_ACK_REQUEST; /* Now before returning we send delivery status report * if it is requested. */ if (SRR_FLAGS(bundle.bundleProcFlags) & BP_DELIVERED_RPT) { bundle.statusRpt.flags |= BP_DELIVERED_RPT; getCurrentDtnTime(&bundle.statusRpt.deliveryTime); } if (bundle.statusRpt.flags) { result = sendStatusRpt(&bundle, dictionary); if (result < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't send status report.", NULL); return -1; } } /* Finally delete the delivery list element and, if * possible, destroy the bundle itself. */ if (dictionary) { MRELEASE(dictionary); } sdr_list_delete(sdr, dlvElt, (SdrListDeleteFn) NULL, NULL); bundle.dlvQueueElt = 0; sdr_write(sdr, bundleAddr, (char *) &bundle, sizeof(Bundle)); if (bpDestroyBundle(bundleAddr, 0) < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't destroy bundle.", NULL); return -1; } if (sdr_end_xn(sdr) < 0) { putErrmsg("Failure in bundle reception.", NULL); return -1; } return 0; }
int bp_send(BpSAP sap, int mode, char *destEid, char *reportToEid, int lifespan, int classOfService, BpCustodySwitch custodySwitch, unsigned char srrFlags, int ackRequested, BpExtendedCOS *ecos, Object adu, Object *bundleObj) { Sdr sdr = getIonsdr(); BpVdb *vdb = getBpVdb(); BpExtendedCOS defaultECOS = { 0, 0, 0 }; int aduOccupancy; MetaEid *sourceMetaEid; Throttle *throttle; CHKERR(bundleObj); *bundleObj = 0; CHKERR(adu); if (ecos == NULL) { ecos = &defaultECOS; } else { if (ecos->ordinal == 255) /* Reserved. */ { ecos->ordinal = 254; } } if (sap) { sourceMetaEid = &(sap->endpointMetaEid); } else { sourceMetaEid = NULL; } /* Admission control (bundle production throttling) * happens here. */ throttle = &(vdb->productionThrottle); sdr_begin_xn(sdr); /* Just to lock memory. */ aduOccupancy = zco_occupancy(sdr, adu); while (aduOccupancy > throttle->capacity) { sdr_exit_xn(sdr); if (mode == BP_NONBLOCKING) { errno = EWOULDBLOCK; return 0; } if (sm_SemTake(throttle->semaphore) < 0) { putErrmsg("Can't take throttle semaphore.", NULL); return -1; } if (sm_SemEnded(throttle->semaphore)) { putErrmsg("Bundle agent has been stopped.", NULL); return -1; } sdr_begin_xn(sdr); } sdr_exit_xn(sdr); /* Release memory. */ /* Now go ahead and send the bundle. */ return bpSend(sourceMetaEid, destEid, reportToEid, lifespan, classOfService, custodySwitch, srrFlags, ackRequested, ecos, adu, bundleObj, 0); }
int dtn2fw(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { #else int main(int argc, char *argv[]) { #endif int running = 1; Sdr sdr; VScheme *vscheme; PsmAddress vschemeElt; Scheme scheme; Object elt; Object bundleAddr; Bundle bundle; if (bpAttach() < 0) { putErrmsg("dtn2fw can't attach to BP.", NULL); return 1; } if (dtn2Init(NULL) < 0) { putErrmsg("dtn2fw can't load routing database.", NULL); return 1; } sdr = getIonsdr(); findScheme("dtn", &vscheme, &vschemeElt); if (vschemeElt == 0) { putErrmsg("Scheme name for dtn2 is unknown.", "dtn"); return 1; } CHKZERO(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &scheme, sdr_list_data(sdr, vscheme->schemeElt), sizeof(Scheme)); sdr_exit_xn(sdr); oK(_dtn2fwSemaphore(&vscheme->semaphore)); isignal(SIGTERM, shutDown); /* Main loop: wait until forwarding queue is non-empty, * then drain it. */ writeMemo("[i] dtn2fw is running."); while (running && !(sm_SemEnded(vscheme->semaphore))) { /* We wrap forwarding in an SDR transaction to * prevent race condition with bpclock (which * is destroying bundles as their TTLs expire). */ CHKZERO(sdr_begin_xn(sdr)); elt = sdr_list_first(sdr, scheme.forwardQueue); if (elt == 0) /* Wait for forwarding notice. */ { sdr_exit_xn(sdr); if (sm_SemTake(vscheme->semaphore) < 0) { putErrmsg("Can't take forwarder semaphore.", NULL); running = 0; } continue; } bundleAddr = (Object) sdr_list_data(sdr, elt); sdr_stage(sdr, (char *) &bundle, bundleAddr, sizeof(Bundle)); sdr_list_delete(sdr, elt, NULL, NULL); bundle.fwdQueueElt = 0; /* Must rewrite bundle to note removal of * fwdQueueElt, in case the bundle is abandoned * and bpDestroyBundle re-reads it from the * database. */ sdr_write(sdr, bundleAddr, (char *) &bundle, sizeof(Bundle)); if (enqueueBundle(&bundle, bundleAddr) < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't enqueue bundle.", NULL); running = 0; /* Terminate loop. */ continue; } if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't enqueue bundle.", NULL); running = 0; /* Terminate loop. */ } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } writeErrmsgMemos(); writeMemo("[i] dtn2fw forwarder has ended."); ionDetach(); return 0; }
int bpcp(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { int t; char* argv[5]; int argc; /*Initialize CFDP*/ ion_cfdp_init(); /*Recursive flag is a1*/ iamrecursive = atoi((char*)a1); if(iamrecursive!=0 && iamrecursive!=1) { iamrecursive=0; } /*Pretty progress meter always disabled*/ showprogress=0; /*Lifetime is a2. a2=0 results in default lifetime.*/ t=strtol((char*)a2, NULL, 10); if (t > 0) { parms.utParms.lifespan=t; } /*Custody Switch is a3. 1=ON, 0=OFF*/ t = atoi((char*)a3); if(t==1) { parms.utParms.custodySwitch = SourceCustodyRequired; } else { if(t==0) { parms.utParms.custodySwitch = NoCustodyRequested; } } /*Class of Service is a4.*/ t=strtol((char*)a4, NULL, 10); if (t>=0 && t <= 2) { parms.utParms.classOfService=t; } /*Debug flag is a5.*/ debug=atoi((char*)a5); if(debug>0) { version(); } /*a6-a10 are files to copy/destinations*/ argc=0; if((char*)a6!=NULL) { argv[argc]=(char*)a6; argc++; } if((char*)a7!=NULL) { argv[argc]=(char*)a7; argc++; } if((char*)a8!=NULL) { argv[argc]=(char*)a8; argc++; } if((char*)a9!=NULL) { argv[argc]=(char*)a9; argc++; } if((char*)a10!=NULL) { argv[argc]=(char*)a10; argc++; } #else int main(int argc, char **argv) { int ch; extern char *optarg; extern int optind; int tmpoption; /*Initialize CFDP*/ ion_cfdp_init(); /*Parse commandline options*/ while ((ch = getopt(argc, argv, "dqrL:C:S:v")) != -1) { switch (ch) { case 'r': /*Recursive*/ iamrecursive = 1; break; case 'd': /*Debug*/ debug++; break; case 'v': /*Print Version info*/ version(); break; case 'q': /*Quiet*/ showprogress = 0; break; case 'L': /*Lifetime*/ tmpoption=-1; tmpoption=strtol(optarg, NULL, 10); if (tmpoption > 0) { parms.utParms.lifespan=tmpoption; } else { dbgprintf(0, "Error: Invalid BP Lifetime\n"); exit_nicely(1); } break; case 'C': /*Custody Transfer*/ if (strcmp(optarg, "Yes")==0 || strcmp(optarg, "YES")==0 || strcmp(optarg, "yes")==0 || strcmp(optarg, "y")==0 || strcmp(optarg, "On")==0 || strcmp(optarg, "ON")==0 || strcmp(optarg, "on")==0 || strcmp(optarg, "1")==0) { parms.utParms.custodySwitch = SourceCustodyRequired; } else { if (strcmp(optarg, "No")==0 || strcmp(optarg, "NO")==0 || strcmp(optarg, "yes")==0 || strcmp(optarg, "n")==0 || strcmp(optarg, "Off")==0 || strcmp(optarg, "OFF")==0 || strcmp(optarg, "off")==0 || strcmp(optarg, "0")==0) { parms.utParms.custodySwitch = NoCustodyRequested; } else { dbgprintf(0, "Error: Invalid Custody Transfer Setting\n"); } } break; case 'S': /*Class of Service*/ tmpoption=-1; tmpoption=strtol(optarg, NULL, 10); if (tmpoption>=0 && tmpoption <= 2) { parms.utParms.classOfService=tmpoption; } else { dbgprintf(0, "Error: Invalid BP Class of Service\n"); exit_nicely(1); } break; default: usage(); } } argc -= optind; argv += optind; #endif char *targ; /*Initialize tmp file array*/ memset(tmp_files,0, NUM_TMP_FILES*255); #ifdef SIG_HANDLER /*Set SIGTERM and SIGINT handlers*/ isignal(SIGTERM, handle_sigterm); isignal(SIGINT, handle_sigterm); #endif /*Additional argument checks*/ if (!isatty(STDOUT_FILENO)) { showprogress = 0; } if (argc < 2) { usage(); } if (argc > 2) { /*We are moving multiple files, destination must be a directory*/ targetshouldbedirectory = 1; } /*Connect to CFDP*/ if (cfdp_attach() < 0) { dbgprintf(0, "Error: Can't initialize CFDP. Is ION running?\n"); exit(1); } /*Create receiver thread*/ events_sem=sm_SemCreate(SM_NO_KEY, SM_SEM_FIFO); if (events_sem==SM_SEM_NONE || sm_SemTake(events_sem)<0) { dbgprintf(0, "Error: Can't create semaphore\n"); exit(1); } recv_running=1; if (pthread_begin(&rcv_thread, NULL, &rcv_msg_thread, (void*)&recv_running)) { dbgprintf(0, "Error: Can't start message thread\n"); sm_SemDelete(events_sem); exit(1); } /*Parse Paths*/ if ((targ = remote_path(argv[argc - 1]))) { /* Last path is remote path * Destination is remote host*/ toremote(targ, argc, argv); } else { /*Destination is localhost*/ if (targetshouldbedirectory) { /*If we are moving multiple files, check that destination * is directory*/ if (is_dir(argv[argc - 1])) { tolocal(argc, argv); } else { dbgprintf(0, "Error: Destination is not a directory\n"); exit_nicely(1); } } else { /*Single file copy*/ tolocal(argc, argv); } } exit_nicely(0); return 0; }
static int checkNodeListParms(IonParms *parms, char *wdName, uvast nodeNbr) { char *nodeListDir; sm_SemId nodeListMutex; char nodeListFileName[265]; int nodeListFile; int lineNbr = 0; int lineLen; char lineBuf[256]; uvast lineNodeNbr; int lineWmKey; char lineSdrName[MAX_SDR_NAME + 1]; char lineWdName[256]; int result; nodeListDir = getenv("ION_NODE_LIST_DIR"); if (nodeListDir == NULL) /* Single node on machine. */ { if (parms->wmKey == 0) { parms->wmKey = ION_DEFAULT_SM_KEY; } if (parms->wmKey != ION_DEFAULT_SM_KEY) { putErrmsg("Config parms wmKey != default.", itoa(ION_DEFAULT_SM_KEY)); return -1; } if (parms->sdrName[0] == '\0') { istrcpy(parms->sdrName, ION_DEFAULT_SDR_NAME, sizeof parms->sdrName); } if (strcmp(parms->sdrName, ION_DEFAULT_SDR_NAME) != 0) { putErrmsg("Config parms sdrName != default.", ION_DEFAULT_SDR_NAME); return -1; } return 0; } /* Configured for multi-node operation. */ nodeListMutex = sm_SemCreate(NODE_LIST_SEMKEY, SM_SEM_FIFO); if (nodeListMutex == SM_SEM_NONE || sm_SemUnwedge(nodeListMutex, 3) < 0 || sm_SemTake(nodeListMutex) < 0) { putErrmsg("Can't lock node list file.", NULL); return -1; } isprintf(nodeListFileName, sizeof nodeListFileName, "%.255s%cion_nodes", nodeListDir, ION_PATH_DELIMITER); if (nodeNbr == 0) /* Just attaching. */ { nodeListFile = iopen(nodeListFileName, O_RDONLY, 0); } else /* Initializing the node. */ { nodeListFile = iopen(nodeListFileName, O_RDWR | O_CREAT, 0666); } if (nodeListFile < 0) { sm_SemGive(nodeListMutex); putSysErrmsg("Can't open ion_nodes file", nodeListFileName); writeMemo("[?] Remove ION_NODE_LIST_DIR from env?"); return -1; } while (1) { if (igets(nodeListFile, lineBuf, sizeof lineBuf, &lineLen) == NULL) { if (lineLen < 0) { close(nodeListFile); sm_SemGive(nodeListMutex); putErrmsg("Failed reading ion_nodes file.", nodeListFileName); return -1; } break; /* End of file. */ } lineNbr++; if (sscanf(lineBuf, UVAST_FIELDSPEC " %d %31s %255s", &lineNodeNbr, &lineWmKey, lineSdrName, lineWdName) < 4) { close(nodeListFile); sm_SemGive(nodeListMutex); putErrmsg("Syntax error at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } if (lineNodeNbr == nodeNbr) /* Match. */ { /* lineNodeNbr can't be zero (we never * write such lines to the file), so this * must be matching non-zero node numbers. * So we are re-initializing this node. */ close(nodeListFile); if (strcmp(lineWdName, wdName) != 0) { sm_SemGive(nodeListMutex); putErrmsg("CWD conflict at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } if (parms->wmKey == 0) { parms->wmKey = lineWmKey; } if (parms->wmKey != lineWmKey) { sm_SemGive(nodeListMutex); putErrmsg("WmKey conflict at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } if (parms->sdrName[0] == '\0') { istrcpy(parms->sdrName, lineSdrName, sizeof parms->sdrName); } if (strcmp(parms->sdrName, lineSdrName) != 0) { sm_SemGive(nodeListMutex); putErrmsg("SdrName conflict at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } return 0; } /* lineNodeNbr does not match nodeNbr (which may * be zero). */ if (strcmp(lineWdName, wdName) == 0) /* Match. */ { close(nodeListFile); sm_SemGive(nodeListMutex); if (nodeNbr == 0) /* Attaching. */ { parms->wmKey = lineWmKey; istrcpy(parms->sdrName, lineSdrName, MAX_SDR_NAME + 1); return 0; } /* Reinitialization conflict. */ putErrmsg("NodeNbr conflict at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } /* Haven't found matching line yet. Continue. */ } /* No matching lines in file. */ if (nodeNbr == 0) /* Attaching to existing node. */ { close(nodeListFile); sm_SemGive(nodeListMutex); putErrmsg("No node has been initialized in this directory.", wdName); return -1; } /* Initializing, so append line to the nodes list file. */ if (parms->wmKey == 0) { parms->wmKey = ION_DEFAULT_SM_KEY; } if (parms->sdrName[0] == '\0') { istrcpy(parms->sdrName, ION_DEFAULT_SDR_NAME, sizeof parms->sdrName); } isprintf(lineBuf, sizeof lineBuf, UVAST_FIELDSPEC " %d %.31s %.255s\n", nodeNbr, parms->wmKey, parms->sdrName, wdName); result = iputs(nodeListFile, lineBuf); close(nodeListFile); sm_SemGive(nodeListMutex); if (result < 0) { putErrmsg("Failed writing to ion_nodes file.", NULL); return -1; } return 0; }
static IonVdb *_ionvdb(char **name) { static IonVdb *vdb = NULL; PsmAddress vdbAddress; PsmAddress elt; Sdr sdr; PsmPartition ionwm; IonDB iondb; if (name) { if (*name == NULL) /* Terminating. */ { vdb = NULL; return vdb; } /* Attaching to volatile database. */ ionwm = _ionwm(NULL); if (psm_locate(ionwm, *name, &vdbAddress, &elt) < 0) { putErrmsg("Failed searching for vdb.", *name); return NULL; } if (elt) { vdb = (IonVdb *) psp(ionwm, vdbAddress); return vdb; } /* ION volatile database doesn't exist yet. */ sdr = _ionsdr(NULL); CHKNULL(sdr_begin_xn(sdr)); /* To lock memory. */ vdbAddress = psm_zalloc(ionwm, sizeof(IonVdb)); if (vdbAddress == 0) { sdr_exit_xn(sdr); putErrmsg("No space for volatile database.", *name); return NULL; } vdb = (IonVdb *) psp(ionwm, vdbAddress); memset((char *) vdb, 0, sizeof(IonVdb)); vdb->zcoSemaphore = sm_SemCreate(SM_NO_KEY, SM_SEM_FIFO); if (vdb->zcoSemaphore == SM_SEM_NONE) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", *name); return NULL; } sm_SemTake(vdb->zcoSemaphore); /* Lock it. */ if ((vdb->nodes = sm_rbt_create(ionwm)) == 0 || (vdb->neighbors = sm_rbt_create(ionwm)) == 0 || (vdb->contactIndex = sm_rbt_create(ionwm)) == 0 || (vdb->rangeIndex = sm_rbt_create(ionwm)) == 0 || (vdb->timeline = sm_rbt_create(ionwm)) == 0 || (vdb->probes = sm_list_create(ionwm)) == 0 || psm_catlg(ionwm, *name, vdbAddress) < 0) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", *name); return NULL; } vdb->clockPid = ERROR; /* None yet. */ sdr_read(sdr, (char *) &iondb, _iondbObject(NULL), sizeof(IonDB)); vdb->deltaFromUTC = iondb.deltaFromUTC; sdr_exit_xn(sdr); /* Unlock memory. */ } return vdb; }
int main(int argc, char **argv) #endif { char *wmspace; int wmid; PsmPartition wm = NULL; PsmMgtOutcome outcome; PsmAddress testlist; sm_SemId semaphore; int cycleNbr = 1; char fileName[256]; int outputFile; PsmAddress lineListElt; PsmAddress lineAddress; char *line; if (sm_ipc_init() < 0) { return 0; } if (sm_ShmAttach(0x1108, 10000000, &wmspace, &wmid) < 0) { PERROR("can't attach to shared memory"); return 0; } if (psm_manage(wmspace, 10000000, "file2sm", &wm, &outcome) < 0 || outcome == Refused) { PUTS("can't manage shared memory"); return 0; } testlist = psm_get_root(wm); if (testlist == 0) { testlist = sm_list_create(wm); if (testlist == 0) { PUTS("can't create shared memory list"); return 0; } psm_set_root(wm, testlist); } semaphore = sm_SemCreate(0x1101, SM_SEM_FIFO); if (semaphore < 0) { PUTS("can't create semaphore"); return 0; } PUTMEMO("Working on cycle", utoa(cycleNbr)); isprintf(fileName, sizeof fileName, "file_copy_%d", cycleNbr); outputFile = iopen(fileName, O_WRONLY | O_APPEND, 0666); if (outputFile < 0) { PERROR("can't open output file"); return 0; } while (1) { while (sm_list_length(wm, testlist) == 0) { sm_SemTake(semaphore); /* Wait for line. */ } lineListElt = sm_list_first(wm, testlist); lineAddress = sm_list_data(wm, lineListElt); line = psp(wm, lineAddress); /* Process text of line. */ if (strcmp(line, "*** End of the file ***\n") == 0) { /* Close file, open next one. */ close(outputFile); cycleNbr++; PUTMEMO("Working on cycle", utoa(cycleNbr)); isprintf(fileName, sizeof fileName, "file_copy_%d", cycleNbr); outputFile = iopen(fileName, O_WRONLY | O_APPEND, 0666); if (outputFile < 0) { PERROR("Can't open output file"); return 0; } } else /* Just write line to output file. */ { if (iputs(outputFile, line) < 0) { close(outputFile); PERROR("Can't write to output file"); return 0; } } /* Delete line from shared memory list. */ psm_free(wm, lineAddress); CHKZERO(sm_list_delete(wm, lineListElt, (SmListDeleteFn) NULL, NULL) == 0); } }
static int lockSmlist(SmList *list) { return sm_SemTake(list->lock); }