示例#1
0
void* work_on_array(void* temp_lock) {
	Lock lock_tmp = (Lock)temp_lock;
	int i;
	bool is_change = false;

	get_write_lock(lock_tmp);
	counter++;
	release_exclusive_lock(lock_tmp);

	for (i = 0; i < ARR_SIZE; ++i) {
		get_may_write_lock(lock_tmp);
		if (array[i] == (pthread_self() % ARR_SIZE)) {
			upgrade_may_write_lock(lock_tmp);
			array[i] = pthread_self();
			printf("Thread number: %d was here :)\n", array[i]);
			is_change = true;
			break;
		}
		release_shared_lock(lock_tmp);
	}

	if (is_change) {
		release_exclusive_lock(lock_tmp);
	}

	return NULL;
}
示例#2
0
void* work_on_array4(void* temp_lock) {
	Lock lock_tmp = (Lock)temp_lock;
	int i;
	for (i = ARR_SIZE - 1; i >= 0; i -= 2) {
		get_write_lock(lock_tmp);
		array[i] += 3;
		release_exclusive_lock(lock_tmp);
	}

	return NULL;
}
示例#3
0
int open_logfile_obj(obj_t *logfile)
{
/*  (Re)opens the specified 'logfile' obj.
 *  Since this logfile can be re-opened after the daemon has chdir()'d,
 *    it must be specified with an absolute pathname.
 *  Returns 0 if the logfile is successfully opened; o/w, returns -1.
 */
    char  dirname[PATH_MAX];
    int   flags;
    char *now;
    char *msg;

    assert(logfile != NULL);
    assert(is_logfile_obj(logfile));
    assert(logfile->name != NULL);
    assert(logfile->name[0] == '/');
    assert(logfile->aux.logfile.console != NULL);
    assert(logfile->aux.logfile.console->name != NULL);

    if (logfile->fd >= 0) {
        if (close(logfile->fd) < 0)     /* log err and continue */
            log_msg(LOG_WARNING, "Unable to close logfile \"%s\": %s",
                logfile->name, strerror(errno));
        logfile->fd = -1;
    }
    /*  Perform conversion specifier expansion.
     */
    if (logfile->aux.logfile.fmtName) {

        char buf[MAX_LINE];

        if (format_obj_string(buf, sizeof(buf),
          logfile->aux.logfile.console,
          logfile->aux.logfile.fmtName) < 0) {
            log_msg(LOG_WARNING,
                "Unable to open logfile for [%s]: filename exceeded buffer",
                logfile->aux.logfile.console->name);
            logfile->fd = -1;
            return(-1);
        }
        free(logfile->name);
        logfile->name = create_string(buf);
    }
    /*  Create intermediate directories.
     */
    if (get_dir_name(logfile->name, dirname, sizeof(dirname))) {
        (void) create_dirs(dirname);
    }
    /*  Only truncate on the initial open if ZeroLogs was enabled.
     */
    flags = O_WRONLY | O_CREAT | O_APPEND | O_NONBLOCK;
    if (logfile->aux.logfile.gotTruncate) {
        logfile->aux.logfile.gotTruncate = 0;
        flags |= O_TRUNC;
    }
    if ((logfile->fd = open(logfile->name, flags, S_IRUSR | S_IWUSR)) < 0) {
        log_msg(LOG_WARNING, "Unable to open logfile \"%s\": %s",
            logfile->name, strerror(errno));
        return(-1);
    }
    if (logfile->aux.logfile.opts.enableLock
            && (get_write_lock(logfile->fd) < 0)) {
        log_msg(LOG_WARNING, "Unable to lock \"%s\"", logfile->name);
        close(logfile->fd);             /* ignore err on close() */
        logfile->fd = -1;
        return(-1);
    }
    logfile->gotEOF = 0;
    set_fd_nonblocking(logfile->fd);    /* redundant, just playing it safe */
    set_fd_closed_on_exec(logfile->fd);

    now = create_long_time_string(0);
    msg = create_format_string("%sConsole [%s] log opened at %s%s",
        CONMAN_MSG_PREFIX, logfile->aux.logfile.console->name, now,
        CONMAN_MSG_SUFFIX);
    write_obj_data(logfile, msg, strlen(msg), 0);
    free(now);
    free(msg);
    /*
     *  Since the above console log message is not marked "informational",
     *    the test in write_obj_data() to re-init the line state will not
     *    be triggered.  Thusly, we re-initialize the line state here.
     */
    logfile->aux.logfile.lineState = CONMAN_LOG_LINE_INIT;

    DPRINTF((9, "Opened [%s] logfile: fd=%d file=%s.\n",
        logfile->aux.logfile.console->name, logfile->fd, logfile->name));
    return(0);
}
示例#4
0
static void open_daemon_logfile(server_conf_t *conf)
{
/*  (Re)opens the daemon logfile.
 *  Since this logfile can be re-opened after the daemon has chdir()'d,
 *    it must be specified with an absolute pathname.
 */
    static int  once = 1;
    const char *mode = "a";
    mode_t      mask;
    char        dirname[PATH_MAX];
    FILE       *fp = NULL;
    int         fd;

    assert(conf->logFileName != NULL);
    assert(conf->logFileName[0] == '/');
    assert(!conf->enableForeground);

    /*  Only truncate logfile at startup if needed.
     */
    if (once) {
        if (conf->enableZeroLogs) {
            mode = "w";
        }
        once = 0;
    }
    /*  Perform conversion specifier expansion.
     */
    if (conf->logFmtName) {

        char buf[MAX_LINE];

        if (format_obj_string(buf, sizeof(buf), NULL, conf->logFmtName) < 0) {
            log_msg(LOG_WARNING,
                "Unable to open daemon logfile: filename too long");
            goto err;
        }
        free(conf->logFileName);
        conf->logFileName = create_string(buf);
    }
    /*  Protect logfile against unauthorized writes by removing
     *    group+other write-access from current mask.
     */
    mask = umask(0);
    umask(mask | 022);
    /*
     *  Create intermediate directories.
     */
    if (get_dir_name(conf->logFileName, dirname, sizeof(dirname))) {
        (void) create_dirs(dirname);
    }
    /*  Open the logfile.
     */
    fp = fopen(conf->logFileName, mode);
    umask(mask);

    if (!fp) {
        log_msg(LOG_WARNING, "Unable to open daemon logfile \"%s\": %s",
            conf->logFileName, strerror(errno));
        goto err;
    }
    if ((fd = fileno(fp)) < 0) {
        log_msg(LOG_WARNING,
            "Unable to obtain descriptor for daemon logfile \"%s\": %s",
            conf->logFileName, strerror(errno));
        goto err;
    }
    if (get_write_lock(fd) < 0) {
        log_msg(LOG_WARNING, "Unable to lock daemon logfile \"%s\"",
            conf->logFileName);
        goto err;
    }
    set_fd_closed_on_exec(fd);
    /*
     *  Transition to new log file.
     */
    log_set_file(fp, conf->logFileLevel, 1);
    if (conf->logFilePtr) {
        if (fclose(conf->logFilePtr) == EOF) {
            log_msg(LOG_WARNING, "Unable to close daemon logfile \"%s\"",
                conf->logFileName);
        }
    }
    conf->logFilePtr = fp;
    DPRINTF((9, "Opened logfile \"%s\": fd=%d.\n", conf->logFileName, fd));
    return;

err:
    if (fp) {
        (void) fclose(fp);
    }
    /*  Abandon old log file and go logless.
     */
    log_set_file(NULL, 0, 0);
    if (conf->logFilePtr) {
        if (fclose(conf->logFilePtr) == EOF) {
            log_msg(LOG_WARNING, "Unable to close daemon logfile \"%s\"",
                conf->logFileName);
        }
    }
    conf->logFilePtr = NULL;
    return;
}
示例#5
0
int open_serial_obj(obj_t *serial)
{
/*  (Re)opens the specified 'serial' obj.
 *  Returns 0 if the serial console is successfully opened; o/w, returns -1.
 *
 *  FIXME: Check to see if "downed" serial consoles are ever resurrected.
 */
    int fd;
    int flags;
    struct termios tty;

    assert(serial != NULL);
    assert(is_serial_obj(serial));

    if (serial->fd >= 0) {
        write_notify_msg(serial, LOG_INFO,
            "Console [%s] disconnected from \"%s\"",
            serial->name, serial->aux.serial.dev);
        set_tty_mode(&serial->aux.serial.tty, serial->fd);
        if (close(serial->fd) < 0)      /* log err and continue */
            log_msg(LOG_WARNING, "Unable to close [%s] device \"%s\": %s",
                serial->name, serial->aux.serial.dev, strerror(errno));
        serial->fd = -1;
    }
    flags = O_RDWR | O_NONBLOCK | O_NOCTTY;
    if ((fd = open(serial->aux.serial.dev, flags)) < 0) {
        log_msg(LOG_WARNING, "Unable to open [%s] device \"%s\": %s",
            serial->name, serial->aux.serial.dev, strerror(errno));
        goto err;
    }
    if (get_write_lock(fd) < 0) {
        log_msg(LOG_WARNING, "Unable to lock [%s] device \"%s\"",
            serial->name, serial->aux.serial.dev);
        goto err;
    }
    if (!isatty(fd)) {
        log_msg(LOG_WARNING, "[%s] device \"%s\" not a terminal",
            serial->name, serial->aux.serial.dev);
        goto err;
    }
    /*  According to the UNIX Programming FAQ v1.37
     *    <http://www.faqs.org/faqs/unix-faq/programmer/faq/>
     *    (Section 3.6: How to Handle a Serial Port or Modem),
     *    systems seem to differ as to whether a nonblocking
     *    open on a tty will affect subsequent read()s.
     *    Play it safe and be explicit!
     */
    set_fd_nonblocking(fd);
    set_fd_closed_on_exec(fd);
    /*
     *  Note that while the initial state of the console dev's termios
     *    are saved, the 'opts' settings are not.  This is because the
     *    settings do not change until the obj is destroyed, at which time
     *    the termios is reverted back to its initial state.
     *
     *  FIXME: Re-evaluate this thinking since a SIGHUP should attempt
     *         to resurrect "downed" serial objs.
     */
    get_tty_mode(&serial->aux.serial.tty, fd);
    get_tty_raw(&tty, fd);
    set_serial_opts(&tty, serial, &serial->aux.serial.opts);
    set_tty_mode(&tty, fd);
    serial->fd = fd;
    serial->gotEOF = 0;
    /*
     *  Success!
     */
    write_notify_msg(serial, LOG_INFO, "Console [%s] connected to \"%s\"",
        serial->name, serial->aux.serial.dev);
    DPRINTF((9, "Opened [%s] serial: fd=%d dev=%s bps=%d.\n",
        serial->name, serial->fd, serial->aux.serial.dev,
        bps_to_int(serial->aux.serial.opts.bps)));
    return(0);

err:
    if (fd >= 0) {
        close(fd);                      /* ignore errors */
    }
    return(-1);
}