예제 #1
0
void newclient(int c)
{
    char request[1024];
    int n;
    unsigned int start;
    char *reply;
    extern char *pwcheck();
    
    start = 0;
    while (start < sizeof(request) - 1) {
	n = read(c, request+start, sizeof(request) - 1 - start);
	if (n < 1) {
	    reply = "Error reading request";
	    goto sendreply;
	}
		
	start += n;

	if (request[start-1] == '\0' && strlen(request) < start) {
	    break;
	}
    }

    if (start >= sizeof(request) - 1) {
	reply = "Request too big";
    }
    else {
	reply = pwcheck(request, request + strlen(request) + 1);
    }

sendreply:

    retry_write(c, reply, strlen(reply));
    close(c);
}
예제 #2
0
파일: testfw.c 프로젝트: ggcov/ggcov
void
testrunner_t::_check(int pass, const char *file, int line, const char *fmt, ...)
{
    va_list args;
    char buf[STATUS_LEN];

    /* build a status line.  1st char is a code which
     * is interpreted in run_test() above. */

    snprintf(buf, sizeof(buf)-2, "%c%s:%d: %s: ",
             (pass ? '+' : '-'), file, line, (pass ? "passed" : "FAILED"));

    va_start(args, fmt);
    vsnprintf(buf+strlen(buf), sizeof(buf)-2-strlen(buf), fmt, args);
    va_end(args);

    strcat(buf, "\n");

    if (current_->verbose_)
        fputs(buf+1, stderr);

    if (!pass)
    {
        fflush(stderr);
        if (status_pipe >= 0)
            retry_write(status_pipe, buf, strlen(buf));
        abort();
        /*NOTREACHED*/
    }
}
예제 #3
0
static void sync_log_base(const char *channel, const char *string)
{
    int fd;
    struct stat sbuffile, sbuffd;
    int retries = 0;
    const char *fname;

    /* are we being supressed? */
    if (!sync_log_enabled(channel)) return;

    fname = sync_log_fname(channel);

    while (retries++ < SYNC_LOG_RETRIES) {
	fd = open(fname, O_WRONLY|O_APPEND|O_CREAT, 0640);
	if (fd < 0 && errno == ENOENT) {
	    if (!cyrus_mkdir(fname, 0755)) {
		fd = open(fname, O_WRONLY|O_APPEND|O_CREAT, 0640);
	    }
	}
	if (fd < 0) {
	    syslog(LOG_ERR, "sync_log(): Unable to write to log file %s: %s",
		   fname, strerror(errno));
	    return;
	}

	if (lock_blocking(fd, fname) == -1) {
	    syslog(LOG_ERR, "sync_log(): Failed to lock %s for %s: %m",
		   fname, string);
	    xclose(fd);
	    return;
	}

	/* Check that the file wasn't renamed after it was opened above */
	if ((fstat(fd, &sbuffd) == 0) &&
	    (stat(fname, &sbuffile) == 0) &&
	    (sbuffd.st_ino == sbuffile.st_ino))
	    break;

	lock_unlock(fd, fname);
	xclose(fd);
    }
    if (retries >= SYNC_LOG_RETRIES) {
	xclose(fd);
	syslog(LOG_ERR,
	       "sync_log(): Failed to lock %s for %s after %d attempts",
	       fname, string, retries);
	return;
    }

    if (retry_write(fd, string, strlen(string)) < 0)
	syslog(LOG_ERR, "write() to %s failed: %s",
	       fname, strerror(errno));

    (void)fsync(fd); /* paranoia */
    lock_unlock(fd, fname);
    xclose(fd);
}
/*
 * shareinput_writer_notifyready
 *
 *  Called by the writer (producer) once it is done producing all tuples and
 *  writing them to disk. It notifies all the readers (consumers) that tuples
 *  are ready to be read from disk.
 *
 *  For planner-generated plans we wait for acks from all the readers before
 *  proceedings. It is a blocking operation.
 *
 *	For optimizer-generated plans we don't wait for acks, we proceed immediately.
 *  It is a non-blocking operation.
 */
void *
shareinput_writer_notifyready(int share_id, int xslice, PlanGenerator planGen)
{
	int n;

	ShareInput_Lk_Context *pctxt = gp_malloc(sizeof(ShareInput_Lk_Context));

	if(!pctxt)
		ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),
			errmsg("Shareinput Writer failed: out of memory")));

	pctxt->readyfd = -1;
	pctxt->donefd = -1;
	pctxt->zcnt = 0;
	pctxt->del_ready = false;
	pctxt->del_done = false;
	pctxt->lkname_ready[0] = '\0';
	pctxt->lkname_done[0] = '\0';

	RegisterXactCallbackOnce(XCallBack_ShareInput_FIFO, pctxt);

	sisc_lockname(pctxt->lkname_ready, MAXPGPATH, share_id, "ready");
	create_tmp_fifo(pctxt->lkname_ready);
	pctxt->del_ready = true;
	pctxt->readyfd = open(pctxt->lkname_ready, O_RDWR, 0600); 
	if(pctxt->readyfd < 0)
	
		elog(ERROR, "could not open fifo \"%s\": %m", pctxt->lkname_ready);
	sisc_lockname(pctxt->lkname_done, MAXPGPATH, share_id, "done");
	create_tmp_fifo(pctxt->lkname_done);
	pctxt->del_done = true;
	pctxt->donefd = open(pctxt->lkname_done, O_RDWR, 0600);
	if(pctxt->donefd < 0)
		elog(ERROR, "could not open fifo \"%s\": %m", pctxt->lkname_done);

	for(n=0; n<xslice; ++n)
	{
#if USE_ASSERT_CHECKING
		int rwsize =
#endif
		retry_write(pctxt->readyfd, "a", 1);
		Assert(rwsize == 1);
	}
	elog(DEBUG1, "SISC WRITER (shareid=%d, slice=%d): wrote notify_ready to %d xslice readers",
						share_id, currentSliceId, xslice);
	
	if (planGen == PLANGEN_PLANNER)
	{
		/* For planner-generated plans, we wait for acks from all the readers */
		writer_wait_for_acks(pctxt, share_id, xslice);
	}

	return (void *) pctxt;
}
/*
 * shareinput_reader_notifydone
 *
 *  Called by the reader (consumer) to notify the writer (producer) that
 *  it is done reading tuples from disk.
 *
 *  This is a non-blocking operation.
 */
void
shareinput_reader_notifydone(void *ctxt, int share_id)
{
	ShareInput_Lk_Context *pctxt = (ShareInput_Lk_Context *) ctxt;
#if USE_ASSERT_CHECKING
	int rwsize  =
#endif
	retry_write(pctxt->donefd, "z", 1);
	Assert(rwsize == 1);

	UnregisterXactCallbackOnce(XCallBack_ShareInput_FIFO, (void *) ctxt);
	shareinput_clean_lk_ctxt(pctxt);
}
예제 #6
0
EXPORTED ssize_t mappedfile_pwrite(struct mappedfile *mf,
                                   const void *base, size_t len,
                                   off_t offset)
{
    ssize_t written;
    off_t pos;

    assert(mf->is_rw);
    assert(mf->fd != -1);
    assert(base);

    if (!len) return 0; /* nothing to write! */

    /* XXX - memcmp and don't both writing if it matches? */

    mf->dirty++;

    /* locate the file handle */
    pos = lseek(mf->fd, offset, SEEK_SET);
    if (pos < 0) {
        syslog(LOG_ERR, "IOERROR: %s seek to %llX: %m", mf->fname,
               (long long unsigned int)offset);
        return -1;
    }

    /* write the buffer */
    written = retry_write(mf->fd, base, len);
    if (written < 0) {
        syslog(LOG_ERR, "IOERROR: %s write %llu bytes at %llX: %m",
               mf->fname, (long long unsigned int)len,
               (long long unsigned int)offset);
        return -1;
    }

    _ensure_mapped(mf, pos+written, /*update*/1);

    return written;
}
예제 #7
0
파일: testfw.c 프로젝트: ggcov/ggcov
void
testrunner_t::run_test(testfn_t *fn)
{
    running_ = fn;
    nrun_++;

    int pipefd[2];
    if (pipe(pipefd) < 0)
    {
        perror("pipe");
        return;
    }

    dmsg("Forking");
    pid_t pid = fork();
    if (pid < 0)
    {
        perror("fork");
        close(pipefd[PIPE_READ]);
        close(pipefd[PIPE_WRITE]);
        running_ = 0;
        return;
    }
    if (pid == 0)
    {
        /* child process - return and run the test code, dtor will exit. */
        dmsg("In child process");
        close(pipefd[PIPE_READ]);
        /* record the write end of the status pipe for _check() */
        status_pipe = pipefd[PIPE_WRITE];
        /* run the fixtures and test function */
        fn->run();
        /* send a success message */
        char buf[STATUS_LEN];
        snprintf(buf, sizeof(buf), "+PASS %s.%s", fn->suite(), fn->name());
        retry_write(status_pipe, buf, strlen(buf));
        dmsg("Child process exiting normally");
        exit(0);
    }
    else
    {
        /* parent process - read status and wait for the child to finish */
        dmsg("In parent process");
        close(pipefd[PIPE_WRITE]);

        /* we expect at most one status line, from either a
         * _check() failure or a successful test.  */
        char buf[STATUS_LEN];
        if (read_status(buf, sizeof(buf), pipefd[PIPE_READ]) < 0)
        {
            running_ = 0;
            return;
        }
        close(pipefd[PIPE_READ]);

        /* wait the for child process to exit */
        int r = wait_for_child(pid);

        /* diagnose test failure */
        if (r < 0 && r != -ESRCH)
        {
            running_ = 0;
            return;
        }
        if (r == 0 && buf[0] == '+')
        {
            fprintf(stderr, "PASS %s.%s\n", fn->suite(), fn->name());
            npass_++;
        }
        else if (buf[0] != '\0')
        {
            fprintf(stderr, "Test %s.%s failed:\n", fn->suite(), fn->name());
            fputs(buf+1, stderr);
        }
    }
    running_ = 0;
}
예제 #8
0
파일: mbdump.c 프로젝트: rsto/cyrus-imapd
/* create a downgraded index file in cyrus.index.  We don't copy back
 * expunged messages, sorry */
static int dump_index(struct mailbox *mailbox, int oldversion,
                      struct seqset *expunged_seq, int first, int sync,
                      struct protstream *pin, struct protstream *pout)
{
    char oldname[MAX_MAILBOX_PATH];
    const char *fname;
    int oldindex_fd = -1;
    indexbuffer_t headerbuf;
    indexbuffer_t recordbuf;
    char *hbuf = (char *)headerbuf.buf;
    char *rbuf = (char *)recordbuf.buf;
    int header_size;
    int record_size;
    int n, r;

    if (oldversion == 6) {
        header_size = 76;
        record_size = 60;
    }
    else if (oldversion == 7) {
        header_size = 76;
        record_size = 72;
    }
    else if (oldversion == 8) {
        header_size = 92;
        record_size = 80;
    }
    else if (oldversion == 9) {
        header_size = 96;
        record_size = 80;
    }
    else if (oldversion == 10) {
        header_size = 96;
        record_size = 88;
    }
    else {
        return IMAP_MAILBOX_BADFORMAT;
    }

    fname = mailbox_meta_fname(mailbox, META_INDEX);
    snprintf(oldname, MAX_MAILBOX_PATH, "%s.OLD", fname);

    oldindex_fd = open(oldname, O_RDWR|O_TRUNC|O_CREAT, 0666);
    if (oldindex_fd == -1) goto fail;

    downgrade_header(&mailbox->i, hbuf, oldversion,
                     header_size, record_size);

    /* Write header - everything we'll say */
    n = retry_write(oldindex_fd, hbuf, header_size);
    if (n == -1) goto fail;

    struct mailbox_iter *iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_UNLINKED);

    const message_t *msg;

    while ((msg = mailbox_iter_step(iter))) {
        const struct index_record *record = msg_record(msg);
        /* we have to make sure expunged records don't get the
         * file copied, or a reconstruct could bring them back
         * to life!  It we're not creating an expunged file... */
        if (record->system_flags & FLAG_EXPUNGED) {
            if (oldversion < 9) seqset_add(expunged_seq, record->uid, 1);
            continue;
        }
        /* not making sure exists matches, we do trust a bit */
        downgrade_record(record, rbuf, oldversion);
        n = retry_write(oldindex_fd, rbuf, record_size);
        if (n == -1) goto fail;
    }

    mailbox_iter_done(&iter);

    close(oldindex_fd);
    r = dump_file(first, sync, pin, pout, oldname, "cyrus.index", NULL, 0);
    unlink(oldname);
    if (r) return r;

    /* create cyrus.expunge */
    if (oldversion > 8 && mailbox->i.num_records > mailbox->i.exists) {
        int nexpunge = mailbox->i.num_records - mailbox->i.exists;
        fname = mailbox_meta_fname(mailbox, META_EXPUNGE);
        snprintf(oldname, MAX_MAILBOX_PATH, "%s.OLD", fname);

        oldindex_fd = open(oldname, O_RDWR|O_TRUNC|O_CREAT, 0666);
        if (oldindex_fd == -1) goto fail;

        header_set_num_records(hbuf, nexpunge);

        /* Write header - everything we'll say */
        n = retry_write(oldindex_fd, hbuf, header_size);
        if (n == -1) goto fail;

        iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_UNLINKED);
        while ((msg = mailbox_iter_step(iter))) {
            const struct index_record *record = msg_record(msg);
            /* ignore non-expunged records */
            if (!(record->system_flags & FLAG_EXPUNGED))
                continue;
            downgrade_record(record, rbuf, oldversion);
            n = retry_write(oldindex_fd, rbuf, record_size);
            if (n == -1) goto fail;
        }

        close(oldindex_fd);
        r = dump_file(first, sync, pin, pout, oldname, "cyrus.expunge", NULL, 0);
        unlink(oldname);
        if (r) return r;
    }

    return 0;

fail:
    if (oldindex_fd != -1)
        close(oldindex_fd);
    unlink(oldname);

    return IMAP_IOERROR;
}
/*
 * shareinput_reader_waitready
 *
 *  Called by the reader (consumer) to wait for the writer (producer) to produce
 *  all the tuples and write them to disk.
 *
 *  This is a blocking operation.
 */
void *
shareinput_reader_waitready(int share_id, PlanGenerator planGen)
{
	mpp_fd_set rset;
	struct timeval tval;
	int n;
	char a;

	ShareInput_Lk_Context *pctxt = gp_malloc(sizeof(ShareInput_Lk_Context));

	if(!pctxt)
		ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),
			errmsg("Share input reader failed: out of memory")));

	pctxt->readyfd = -1;
	pctxt->donefd = -1;
	pctxt->zcnt = 0;
	pctxt->del_ready = false;
	pctxt->del_done = false;
	pctxt->lkname_ready[0] = '\0';
	pctxt->lkname_done[0] = '\0';

	RegisterXactCallbackOnce(XCallBack_ShareInput_FIFO, pctxt);

	sisc_lockname(pctxt->lkname_ready, MAXPGPATH, share_id, "ready");
	create_tmp_fifo(pctxt->lkname_ready);
	pctxt->readyfd = open(pctxt->lkname_ready, O_RDWR, 0600); 
	if(pctxt->readyfd < 0)
		elog(ERROR, "could not open fifo \"%s\": %m", pctxt->lkname_ready);
	
	sisc_lockname(pctxt->lkname_done, MAXPGPATH, share_id, "done");
	create_tmp_fifo(pctxt->lkname_done);
	pctxt->donefd = open(pctxt->lkname_done, O_RDWR, 0600);
	if(pctxt->donefd < 0)
		elog(ERROR, "could not open fifo \"%s\": %m", pctxt->lkname_done);

	while(1)
	{
		CHECK_FOR_INTERRUPTS();

		MPP_FD_ZERO(&rset);
		MPP_FD_SET(pctxt->readyfd, &rset);

		tval.tv_sec = 1;
		tval.tv_usec = 0;

		n = select(pctxt->readyfd+1, (fd_set *) &rset, NULL, NULL, &tval);

		if(n==1)
		{
#if USE_ASSERT_CHECKING
			int rwsize =
#endif
			retry_read(pctxt->readyfd, &a, 1);
			Assert(rwsize == 1 && a == 'a');

			elog(DEBUG1, "SISC READER (shareid=%d, slice=%d): Wait ready got writer's handshake",
					share_id, currentSliceId);

			if (planGen == PLANGEN_PLANNER)
			{
				/* For planner-generated plans, we send ack back after receiving the handshake */
				elog(DEBUG1, "SISC READER (shareid=%d, slice=%d): Wait ready writing ack back to writer",
						share_id, currentSliceId);

#if USE_ASSERT_CHECKING
				rwsize =
#endif
				retry_write(pctxt->donefd, "b", 1);
				Assert(rwsize == 1);
			}

			break;
		}
		else if(n==0)
		{
			elog(DEBUG1, "SISC READER (shareid=%d, slice=%d): Wait ready time out once",
					share_id, currentSliceId);
		}
		else
		{
			int save_errno = errno;
			elog(LOG, "SISC READER (shareid=%d, slice=%d): Wait ready try again, errno %d ... ",
					share_id, currentSliceId, save_errno);
		}
	}
	return (void *) pctxt;
}
예제 #10
0
/* create a downgraded index file in cyrus.index.  We don't copy back
 * expunged messages, sorry */
static int dump_index(struct mailbox *mailbox, int oldversion,
		      struct seqset *expunged_seq, int first, int sync,
		      struct protstream *pin, struct protstream *pout)
{
    char oldname[MAX_MAILBOX_PATH];
    const char *fname;
    int oldindex_fd = -1;
    indexbuffer_t headerbuf;
    indexbuffer_t recordbuf;
    char *hbuf = (char *)headerbuf.buf;
    char *rbuf = (char *)recordbuf.buf;
    int header_size;
    int record_size;
    int n, r;
    struct index_record record;
    unsigned recno;

    if (oldversion == 6) {
	header_size = 76;
	record_size = 60;
    }
    else if (oldversion == 7) {
	header_size = 76;
	record_size = 72;
    }
    else if (oldversion == 8) {
	header_size = 92;
	record_size = 80;
    }
    else if (oldversion == 9) {
	header_size = 96;
	record_size = 80;
    }
    else if (oldversion == 10) {
	header_size = 96;
	record_size = 88;
    }
    else {
	return IMAP_MAILBOX_BADFORMAT;
    }

    fname = mailbox_meta_fname(mailbox, META_INDEX);
    snprintf(oldname, MAX_MAILBOX_PATH, "%s.OLD", fname);
    
    oldindex_fd = open(oldname, O_RDWR|O_TRUNC|O_CREAT, 0666);
    if (oldindex_fd == -1) goto fail;

    downgrade_header(&mailbox->i, hbuf, oldversion,
		     header_size, record_size);

    /* Write header - everything we'll say */
    n = retry_write(oldindex_fd, hbuf, header_size);
    if (n == -1) goto fail;

    for (recno = 1; recno <= mailbox->i.num_records; recno++) {
	if (mailbox_read_index_record(mailbox, recno, &record))
	    goto fail;
	/* we don't care about unlinked records at all */
	if (record.system_flags & FLAG_UNLINKED)
	    continue;
	/* we have to make sure expunged records don't get the
	 * file copied, or a reconstruct could bring them back
	 * to life!  It we're not creating an expunged file... */
	if (record.system_flags & FLAG_EXPUNGED) {
	    if (oldversion < 9) seqset_add(expunged_seq, record.uid, 1);
	    continue;
	}
	/* not making sure exists matches, we do trust a bit */
	downgrade_record(&record, rbuf, oldversion);
	n = retry_write(oldindex_fd, rbuf, record_size);
	if (n == -1) goto fail;
    }

    close(oldindex_fd);
    r = dump_file(first, sync, pin, pout, oldname, "cyrus.index");
    unlink(oldname);
    if (r) return r;

    /* create cyrus.expunge */
    if (oldversion > 8 && mailbox->i.num_records > mailbox->i.exists) {
	int nexpunge = mailbox->i.num_records - mailbox->i.exists;
	fname = mailbox_meta_fname(mailbox, META_EXPUNGE);
	snprintf(oldname, MAX_MAILBOX_PATH, "%s.OLD", fname);
	
	oldindex_fd = open(oldname, O_RDWR|O_TRUNC|O_CREAT, 0666);
	if (oldindex_fd == -1) goto fail;

	*((bit32 *)(hbuf+OFFSET_NUM_RECORDS)) = htonl(nexpunge);

	/* Write header - everything we'll say */
	n = retry_write(oldindex_fd, hbuf, header_size);
	if (n == -1) goto fail;

	for (recno = 1; recno <= mailbox->i.num_records; recno++) {
	    if (mailbox_read_index_record(mailbox, recno, &record))
		goto fail;
	    /* ignore non-expunged records */
	    if (!(record.system_flags & FLAG_EXPUNGED))
		continue;
	    downgrade_record(&record, rbuf, oldversion);
	    n = retry_write(oldindex_fd, rbuf, record_size);
	    if (n == -1) goto fail;
	}

	close(oldindex_fd);
	r = dump_file(first, sync, pin, pout, oldname, "cyrus.expunge");
	unlink(oldname);
	if (r) return r;
    }

    return 0;

fail:
    if (oldindex_fd != -1)
	close(oldindex_fd);
    unlink(oldname);

    return IMAP_IOERROR;
}
예제 #11
0
static void
memory_out ()
{
  retry_write (2, "virtual memory exhausted\n", 25);
  exit (1);
}