// fifo_init_internal(path) // If path is NULL, reopen existing fifo, else open anew. static int fifo_init_internal(const char *fifo_path) { if (fifo_path) { fifo_deinit(); fifo_name = expand_filename(fifo_path); if (!check_fifo(fifo_name)) { scr_LogPrint(LPRINT_LOGNORM, "WARNING: Cannot create the FIFO. " "%s already exists and is not a pipe", fifo_name); g_free(fifo_name); fifo_name = NULL; return -1; } } else if (fifo_name) g_source_remove_by_user_data(fifo_channel); else return -1; if (!attach_fifo(fifo_name)) { scr_LogPrint(LPRINT_LOGNORM, "Error: Cannot open fifo"); return -1; } setenv(FIFO_ENV_NAME, fifo_name, 1); scr_LogPrint(LPRINT_LOGNORM, "FIFO initialized (%s)", fifo_path); return 1; }
/** * Base loop for the background CCN task * * This is the main execution loop for the background task responsible for * interacting with the CCN network. It is from this point that many of the above methods are * called to work the inbound messages from ccnx as well as sending out the data messages. * * \param data the task context information setup by the parent sink element thread */ static void ccn_event_thread (void *data) { Gstccnxsink *me = (Gstccnxsink *) data; struct ccn_charbuf *filtName; struct ccn_charbuf *temp; int res = 0; GST_DEBUG ("CCNxSink event: *** event thread starting"); temp = ccn_charbuf_create (); filtName = ccn_charbuf_create (); /* A closure is what defines what to do when an inbound interest arrives */ if ((me->ccn_closure = calloc (1, sizeof (struct ccn_closure))) == NULL) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("closure alloc failed")); return; } /* We setup the closure to contain the sink element context reference, and also tell it what function to call */ me->ccn_closure->data = me; me->ccn_closure->p = new_interests; me->timeouts = 0; ccn_charbuf_append (filtName, me->name->buf, me->name->length); /* This call will set up a handler for interests we expect to get from clients */ // hDump(DUMP_ADDR(filtName->buf), DUMP_SIZE(filtName->length)); ccn_set_interest_filter (me->ccn, filtName, me->ccn_closure); GST_DEBUG ("CCNxSink event: interest filter registered\n"); /* Some debugging information */ temp->length = 0; ccn_uri_append (temp, me->name->buf, me->name->length, TRUE); GST_DEBUG ("CCNxSink event: using uri: %s\n", ccn_charbuf_as_string (temp)); /* Now that the interest is registered, we loop around waiting for something to do */ /* We pass control to ccnx for a while so it can work with any incoming or outgoing data */ /* and then we check our fifo queue for work to do. That's about it! */ /* We check to see if any problems have caused our ccnd connection to fail, and we reconnect */ while (res >= 0) { GST_DEBUG ("CCNxSink event: *** looping"); res = ccn_run (me->ccn, 50); check_fifo (me); if (res < 0 && ccn_get_connection_fd (me->ccn) == -1) { GST_DEBUG ("CCNxSink event: need to reconnect..."); /* Try reconnecting, after a bit of delay */ msleep ((30 + (getpid () % 30)) * 1000); res = ccn_connect (me->ccn, ccndHost ()); } } GST_DEBUG ("CCNxSink event: *** event thread ending"); }
void fifo_deinit(void) { unsetenv(FIFO_ENV_NAME); if (fifo_channel) g_source_remove_by_user_data(fifo_channel); /* channel itself should be destroyed by destruction callback */ /* destroy open fifo */ if (fifo_name) { /* well, that may create fifo, and then unlink, * but at least we will not destroy non-fifo data */ if (check_fifo(fifo_name)) unlink(fifo_name); g_free(fifo_name); fifo_name = NULL; } }
static gboolean check_fifo(const char *name) { struct stat finfo; if (stat(name, &finfo) == -1) { /* some unknown error */ if (errno != ENOENT) return FALSE; /* fifo not yet exists */ if (mkfifo(name, S_IRUSR|S_IWUSR) != -1) return check_fifo(name); else return FALSE; } /* file exists */ if (S_ISFIFO(finfo.st_mode)) return TRUE; else return FALSE; }
int main(int argc, char **argv) { int ret = EXIT_FAILURE, ffd = -1, c_status; pid_t child; char pbuf[IPC_MQSIZ+1]; bool csetup_ok = false; signal(SIGINT, SIG_IGN); signal(SIGTERM, sigfunc); if ( parse_cmd(argc, argv) != 0 ) exit(EXIT_FAILURE); if (OPT(CRYPT_CMD).found == 0) { fprintf(stderr, "%s: crypt cmd is mandatory\n", argv[0]); goto error; } if (check_fifo(GETOPT(FIFO_PATH).str) == false) goto error; if ((ffd = open(GETOPT(FIFO_PATH).str, O_NONBLOCK | O_RDWR)) < 0) { fprintf(stderr, "%s: fifo '%s' error: %d (%s)\n", argv[0], GETOPT(FIFO_PATH).str, errno, strerror(errno)); goto error; } if (ui_ipc_init(1) != 0) { fprintf(stderr, "%s: can not create semaphore/message queue: %d (%s)\n", argv[0], errno, strerror(errno)); goto error; } memset(pbuf, '\0', IPC_MQSIZ+1); log_init( GETOPT(LOG_FILE).str ); logs("%s\n", "log init"); logs_dbg("%s\n", "debug mode active"); ui_ipc_sempost(SEM_UI); ui_ipc_sempost(SEM_IN); if ((child = fork()) == 0) { /* child */ logs("%s\n", "child"); if (ffd >= 0) close(ffd); #ifndef DEBUG fclose(stderr); #endif /* Slave process: TUI */ if (ui_ipc_init(0) == 0) { do_ui(); } ui_ipc_free(0); exit(0); } else if (child > 0) { /* parent */ logs("%s\n", "parent"); fclose(stdin); fclose(stdout); /* Master process: mainloop (read passwd from message queue or fifo and exec cryptcreate */ while ( ui_ipc_getvalue(SEM_UI) > 0 ) { if (read(ffd, pbuf, IPC_MQSIZ) >= 0) { ui_ipc_semwait(SEM_IN); logs_dbg("%s\n", "fifo password"); if (run_cryptcreate(pbuf, GETOPT(CRYPT_CMD).str) != 0) { logs_dbg("%s\n", "cryptcreate error"); sleep(3); } else { csetup_ok = true; logs_dbg("%s\n", "cryptcreate success"); ui_ipc_semtrywait(SEM_UI); } ui_ipc_sempost(SEM_IN); } else if ( ui_ipc_msgcount(MQ_PW) > 0 ) { //ui_ipc_semwait(SEM_IN); ui_ipc_msgrecv(MQ_PW, pbuf, 0); logs_dbg("%s\n", "password"); ui_ipc_msgsend(MQ_IF, MSG(MSG_BUSY)); if (run_cryptcreate(pbuf, GETOPT(CRYPT_CMD).str) != 0) { logs_dbg("%s\n", "cryptcreate error"); ui_ipc_msgsend(MQ_IF, MSG(MSG_CRYPTCMD_ERR)); } else { csetup_ok = true; logs_dbg("%s\n", "cryptcreate success"); ui_ipc_semtrywait(SEM_UI); } //ui_ipc_sempost(SEM_IN); } usleep(100000); } logs("%s\n", "waiting for child"); wait(&c_status); memset(pbuf, '\0', IPC_MQSIZ+1); } else { /* fork error */ perror("fork"); goto error; } if (csetup_ok) ret = EXIT_SUCCESS; else ret = EXIT_FAILURE; ui_ipc_free(1); error: logs("%s\n", "exiting .."); if (ffd >= 0) close(ffd); log_free(); exit(ret); }