httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Clark <mich...@metaparadigm.com>
Subject apr_os_dir_put doesn't create working apr_dir_t
Date Tue, 11 Dec 2007 13:37:10 GMT
apr_os_dir_put doesn't create a working apr_dir_t i.e. apr_dir_read will 
not work on the created apr_dir_t

This is not the case with apr_os_file_put which does in fact create a 
working apr_file_t

Is this a bug or a feature? There doesn't seem to be any users of 
apr_os_dir_put in the httpd tree.

Here is an example from my privilege separated wrapper functions for apr 
file io:

The apr_file_open wrapper is quite simple as the apr_os_file_put works 
as expected:

static apr_status_t privsep_file_open(privsep_token_t *token,
				      apr_file_t **new, 
				      const char *fname, 
				      apr_int32_t flag, 
				      apr_fileperms_t perm, 
				      apr_pool_t *pool)
{
    privsep_message_t msg;
    apr_os_file_t fd;

    if(!privsep_inited || !token)
      return apr_file_open(new, fname, flag, perm, pool);

    memset(&msg, 0, sizeof(msg));
    msg.command = privsep_command_file_open;
    msg.flags = flag;
    msg.perms = perm;
    fd = privsep_send_request(&msg, token, fname);

    if (msg.retval != APR_SUCCESS)
        return msg.retval;

    return apr_os_file_put(new, &fd, flag, pool);
}


But I have to resort to ugly hacks in my apr_dir_open implementation:

static apr_status_t privsep_dir_open(privsep_token_t *token,
				     apr_dir_t **new, const char *dirname, 
				     apr_pool_t *pool)
{
    privsep_message_t msg;
    apr_os_file_t fd;
    DIR *dir;

    if(!privsep_inited || !token)
      return apr_dir_open(new, dirname, pool);

    memset(&msg, 0, sizeof(msg));
    msg.command = privsep_command_dir_open;
    fd = privsep_send_request(&msg, token, dirname);

    if (msg.retval != APR_SUCCESS)
        return msg.retval;

    /* apr_os_dir_put does not create a fullly allocated apr_dir_t
       so we need to open a directory to create one then replace
       the fd in the associated apr_os_dir */
    if(apr_dir_open(new, "/", pool) != APR_SUCCESS) {
	close(fd);
	return APR_EGENERAL;
    }

    /* Ok, now the nasty bit:
       Here we assume that an integer file descriptor is the first 
       element of the opaque DIR structure pointed at by dir
       This is the case on Linux, FreeBSD, Mac OS X and Solaris */
    apr_os_dir_get(&dir, *new);
    close(*(int *)dir);  
    *(int *)dir = fd;
    (*new)->dirname = apr_pstrdup(pool, dirname);
    return apr_os_dir_put(new, dir, pool);
}




Mime
View raw message