summaryrefslogtreecommitdiff
path: root/usr/src/lib/librt/common/pos4obj.c
diff options
context:
space:
mode:
authorraf <none@none>2006-06-20 19:21:46 -0700
committerraf <none@none>2006-06-20 19:21:46 -0700
commitf841f6ad96ea6675d6c6b35c749eaac601799fdf (patch)
tree698db5d44fc99bd070613c93a497f5e93e803bc5 /usr/src/lib/librt/common/pos4obj.c
parent545e5dad7996785cfebf226c5ef410c1b154740f (diff)
downloadillumos-joyent-f841f6ad96ea6675d6c6b35c749eaac601799fdf.tar.gz
6416832 libaio and librt can and should be folded into libc
--HG-- rename : usr/src/cmd/perl/5.8.4/distrib/ext/Time/HiRes/hints/solaris.pl => deleted_files/usr/src/cmd/perl/5.8.4/distrib/ext/Time/HiRes/hints/solaris.pl rename : usr/src/lib/libaio/common/Makefile => deleted_files/usr/src/lib/libaio/common/Makefile rename : usr/src/lib/libaio/common/scalls.c => deleted_files/usr/src/lib/libaio/common/scalls.c rename : usr/src/lib/libaio/common/sig.c => deleted_files/usr/src/lib/libaio/common/sig.c rename : usr/src/lib/libaio/common/subr.c => deleted_files/usr/src/lib/libaio/common/subr.c rename : usr/src/lib/libaio/spec/Makefile => deleted_files/usr/src/lib/libaio/spec/Makefile rename : usr/src/lib/libaio/spec/Makefile.targ => deleted_files/usr/src/lib/libaio/spec/Makefile.targ rename : usr/src/lib/libaio/spec/amd64/Makefile => deleted_files/usr/src/lib/libaio/spec/amd64/Makefile rename : usr/src/lib/libaio/spec/i386/Makefile => deleted_files/usr/src/lib/libaio/spec/i386/Makefile rename : usr/src/lib/libaio/spec/sparc/Makefile => deleted_files/usr/src/lib/libaio/spec/sparc/Makefile rename : usr/src/lib/libaio/spec/sparcv9/Makefile => deleted_files/usr/src/lib/libaio/spec/sparcv9/Makefile rename : usr/src/lib/libaio/spec/versions => deleted_files/usr/src/lib/libaio/spec/versions rename : usr/src/lib/librt/common/Makefile => deleted_files/usr/src/lib/librt/common/Makefile rename : usr/src/lib/librt/common/aio.c => deleted_files/usr/src/lib/librt/common/aio.c rename : usr/src/lib/librt/common/fdatasync.c => deleted_files/usr/src/lib/librt/common/fdatasync.c rename : usr/src/lib/librt/common/mqlib.h => deleted_files/usr/src/lib/librt/common/mqlib.h rename : usr/src/lib/librt/common/pos4.c => deleted_files/usr/src/lib/librt/common/pos4.c rename : usr/src/lib/librt/common/pos4.h => deleted_files/usr/src/lib/librt/common/pos4.h rename : usr/src/lib/librt/common/sigrt.c => deleted_files/usr/src/lib/librt/common/sigrt.c rename : usr/src/lib/librt/req.flg => deleted_files/usr/src/lib/librt/req.flg rename : usr/src/lib/librt/spec/Makefile => deleted_files/usr/src/lib/librt/spec/Makefile rename : usr/src/lib/librt/spec/Makefile.targ => deleted_files/usr/src/lib/librt/spec/Makefile.targ rename : usr/src/lib/librt/spec/amd64/Makefile => deleted_files/usr/src/lib/librt/spec/amd64/Makefile rename : usr/src/lib/librt/spec/i386/Makefile => deleted_files/usr/src/lib/librt/spec/i386/Makefile rename : usr/src/lib/librt/spec/sparc/Makefile => deleted_files/usr/src/lib/librt/spec/sparc/Makefile rename : usr/src/lib/librt/spec/sparcv9/Makefile => deleted_files/usr/src/lib/librt/spec/sparcv9/Makefile rename : usr/src/lib/librt/spec/versions => deleted_files/usr/src/lib/librt/spec/versions rename : usr/src/lib/libaio/common/libaio.h => usr/src/lib/libc/inc/asyncio.h rename : usr/src/lib/librt/common/thread_pool.h => usr/src/lib/libc/inc/thread_pool.h rename : usr/src/lib/libaio/common/aio.c => usr/src/lib/libc/port/aio/aio.c rename : usr/src/lib/libaio/common/ma.c => usr/src/lib/libc/port/aio/aio_alloc.c rename : usr/src/lib/libaio/common/posix_aio.c => usr/src/lib/libc/port/aio/posix_aio.c rename : usr/src/lib/librt/common/clock_timer.c => usr/src/lib/libc/port/rt/clock_timer.c rename : usr/src/lib/librt/common/fallocate.c => usr/src/lib/libc/port/rt/fallocate.c rename : usr/src/lib/librt/common/mqueue.c => usr/src/lib/libc/port/rt/mqueue.c rename : usr/src/lib/librt/common/pos4obj.c => usr/src/lib/libc/port/rt/pos4obj.c rename : usr/src/lib/librt/common/pos4obj.h => usr/src/lib/libc/port/rt/pos4obj.h rename : usr/src/lib/librt/common/sched.c => usr/src/lib/libc/port/rt/sched.c rename : usr/src/lib/librt/common/sem.c => usr/src/lib/libc/port/rt/sem.c rename : usr/src/lib/librt/common/shm.c => usr/src/lib/libc/port/rt/shm.c rename : usr/src/lib/librt/common/sigev_thread.c => usr/src/lib/libc/port/rt/sigev_thread.c rename : usr/src/lib/librt/common/sigev_thread.h => usr/src/lib/libc/port/rt/sigev_thread.h rename : usr/src/lib/librt/common/thread_pool.c => usr/src/lib/libc/port/tpool/thread_pool.c rename : usr/src/lib/librt/common/thread_pool_impl.h => usr/src/lib/libc/port/tpool/thread_pool_impl.h rename : usr/src/lib/libaio/spec/aio.spec => usr/src/lib/libc/spec/aio.spec rename : usr/src/lib/librt/spec/rt.spec => usr/src/lib/libc/spec/rt.spec rename : usr/src/lib/libaio/asynch.h => usr/src/uts/common/sys/asynch.h
Diffstat (limited to 'usr/src/lib/librt/common/pos4obj.c')
-rw-r--r--usr/src/lib/librt/common/pos4obj.c504
1 files changed, 0 insertions, 504 deletions
diff --git a/usr/src/lib/librt/common/pos4obj.c b/usr/src/lib/librt/common/pos4obj.c
deleted file mode 100644
index 7c344d3a43..0000000000
--- a/usr/src/lib/librt/common/pos4obj.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "c_synonyms.h"
-#include <sys/types.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <pthread.h>
-#include <thread.h>
-#include <string.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <dlfcn.h>
-#include <md5.h>
-#include "pos4.h"
-#include "pos4obj.h"
-
-#define HASHSTRLEN 32
-
-static char *__pos4obj_name(const char *, const char *);
-static void __pos4obj_md5toa(unsigned char *, unsigned char *);
-static void __pos4obj_clean(char *);
-
-static char objroot[] = "/tmp/";
-static long int name_max = 0;
-
-int
-__open_nc(const char *path, int oflag, mode_t mode)
-{
- int canstate, val;
- struct stat64 statbuf;
-
- /*
- * Ensure path is not a symlink to somewhere else. This provides
- * a modest amount of protection against easy security attacks.
- */
- if (lstat64(path, &statbuf) == 0) {
- if (S_ISLNK(statbuf.st_mode)) {
- errno = EINVAL;
- return (-1);
- }
- }
-
- (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &canstate);
- val = open64(path, oflag, mode);
- (void) pthread_setcancelstate(canstate, &canstate);
-
- return (val);
-}
-
-int
-__close_nc(int fildes)
-{
- int canstate, val;
-
- (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &canstate);
- val = close(fildes);
- (void) pthread_setcancelstate(canstate, &canstate);
-
- return (val);
-}
-
-/*
- * This is to avoid loading libmd.so.1 unless we absolutely have to.
- */
-typedef void (*md5_calc_t)(unsigned char *, unsigned char *, unsigned int);
-static void *md5_handle = NULL;
-static md5_calc_t real_md5_calc = NULL;
-mutex_t md5_lock = DEFAULTMUTEX;
-
-static void
-load_md5_calc(void)
-{
- /*
- * _sigoff() and _sigon() are consolidation-private interfaces
- * in libc that defer and then reenable signals.
- */
- extern void _sigoff(void);
- extern void _sigon(void);
-
- _sigoff();
- (void) mutex_lock(&md5_lock);
- if (real_md5_calc == NULL) {
- md5_handle = dlopen("libmd.so.1", RTLD_LAZY);
- if (md5_handle == NULL)
- real_md5_calc = (md5_calc_t)(-1);
- else {
- real_md5_calc =
- (md5_calc_t)dlsym(md5_handle, "md5_calc");
- if (real_md5_calc == NULL) {
- (void) dlclose(md5_handle);
- md5_handle = NULL;
- real_md5_calc = (md5_calc_t)(-1);
- }
- }
- }
- (void) mutex_unlock(&md5_lock);
- _sigon();
-}
-
-/*
- * If librt.so.1 is dlclose()d, take libmd.so.1 down with us.
- */
-#pragma fini(unload_md5_calc)
-static void
-unload_md5_calc(void)
-{
- if (md5_handle != NULL)
- (void) dlclose(md5_handle);
- md5_handle = NULL;
- real_md5_calc = NULL;
-}
-
-static char *
-__pos4obj_name(const char *path, const char *type)
-{
- int shortpath = 1;
- int olderrno;
- size_t len;
- char *dfile;
- unsigned char hashbuf[HASHSTRLEN + 1];
- unsigned char md5_digest[MD5_DIGEST_LENGTH];
-
- /*
- * If the path is path_max - strlen(type) characters or less,
- * the name of the file to use will be the path prefixed by
- * the type.
- *
- * In the special case where the path is longer than
- * path_max - strlen(type) characters, we create a string based on the
- * MD5 hash of the path. We prefix that string with a '.' to
- * make it obscure, and create a directory in objroot with
- * that name. In that directory, we create a directory named
- * after the type of object requested. Inside the type
- * directory, the filename will be the path of the object. This
- * prevents collisions in all namespaces.
- *
- * Example:
- * Let objroot = "/tmp/", path = "/<longpath>", and type = ".MQD"
- * Let the MD5 hash of "<longpath>" = "<hash>"
- *
- * The desired file is /tmp/.<hash>/.MQD/<longpath>
- */
-
- /*
- * Do not include the leading '/' in the path length.
- * Assumes __pos4obj_check(path) has already been called.
- */
- if ((strlen(path) - 1) > (name_max - strlen(type)))
- shortpath = 0;
-
- if (shortpath) {
- /*
- * strlen(path) includes leading slash as space for NUL.
- */
- len = strlen(objroot) + strlen(type) + strlen(path);
- } else {
- /*
- * Long path name. Add 3 for extra '/', '.' and '\0'
- */
- len = strlen(objroot) + HASHSTRLEN + strlen(type) +
- strlen(path) + 3;
- }
-
- if ((dfile = malloc(len)) == NULL)
- return (NULL);
-
- (void) memset(dfile, 0, len);
- (void) strcpy(dfile, objroot);
-
- if (shortpath) {
- (void) strcat(dfile, type);
- (void) strcat(dfile, path + 1);
- return (dfile);
- }
-
- /*
- * If we can successfully load it, call md5_calc().
- * Otherwise, (this "can't happen") return NULL.
- */
- if (real_md5_calc == NULL)
- load_md5_calc();
- if (real_md5_calc == (md5_calc_t)(-1)) {
- free(dfile);
- return (NULL);
- }
-
- real_md5_calc(md5_digest, (unsigned char *)path + 1, strlen(path + 1));
- __pos4obj_md5toa(hashbuf, md5_digest);
- (void) strcat(dfile, ".");
- (void) strcat(dfile, (const char *)hashbuf);
-
- /*
- * Errno must be preserved across the following calls to
- * mkdir. This needs to be done to prevent incorrect error
- * reporting in certain cases. When librt attempts to open a
- * non-existent object without the O_CREAT flag, it will
- * always create a lock file first. The lock file is created
- * and then the open is attempted, but fails with ENOENT. The
- * lock file is then destroyed. In the following code path, we
- * are finding the absolute path to the lock file after
- * already having attempted the open (which set errno to
- * ENOENT). The following calls to mkdir will return -1 and
- * set errno to EEXIST, since the hash and type directories
- * were created when the lock file was created. The correct
- * errno is the ENOENT from the attempted open of the desired
- * object.
- */
- olderrno = errno;
-
- /*
- * Create hash directory. Use 777 permissions so everyone can use it.
- */
- if (mkdir(dfile, S_IRWXU|S_IRWXG|S_IRWXO) == 0) {
- if (chmod(dfile, S_IRWXU|S_IRWXG|S_IRWXO) == -1) {
- free(dfile);
- return (NULL);
- }
- } else {
- if (errno != EEXIST) {
- free(dfile);
- return (NULL);
- }
- }
-
- (void) strcat(dfile, "/");
- (void) strcat(dfile, type);
-
- /*
- * Create directory for requested type. Use 777 perms so everyone
- * can use it.
- */
- if (mkdir(dfile, S_IRWXU|S_IRWXG|S_IRWXO) == 0) {
- if (chmod(dfile, S_IRWXU|S_IRWXG|S_IRWXO) == -1) {
- free(dfile);
- return (NULL);
- }
- } else {
- if (errno != EEXIST) {
- free(dfile);
- return (NULL);
- }
- }
-
- errno = olderrno;
- (void) strcat(dfile, path);
- return (dfile);
-}
-
-/*
- * Takes a 128-bit MD5 digest and transforms to a sequence of 32 ASCII
- * characters. Output is the hexadecimal representation of the digest.
- *
- * The output buffer must be at least HASHSTRLEN + 1 characters
- * long. HASHSTRLEN is the size of the MD5 digest (128 bits)
- * divided by the number of bits used per char of output (4). The
- * extra character at the end is for the NUL terminating character.
- */
-
-static void
-__pos4obj_md5toa(unsigned char *dest, unsigned char *src)
-{
- int i;
- uint32_t *p;
-
- /* LINTED pointer cast may result in improper alignment */
- p = (uint32_t *)src;
-
- for (i = 0; i < (MD5_DIGEST_LENGTH / 4); i++)
- (void) snprintf((char *)dest + (i * 8), 9, "%.8x", *p++);
-
- dest[HASHSTRLEN] = '\0';
-}
-
-/*
- * This open function assume that there is no simultaneous
- * open/unlink operation is going on. The caller is supposed
- * to ensure that both open in O_CREAT mode happen atomically.
- * It returns the crflag as 1 if file is created else 0.
- */
-int
-__pos4obj_open(const char *name, char *type, int oflag,
- mode_t mode, int *crflag)
-{
- int fd;
- char *dfile;
-
- errno = 0;
- *crflag = 0;
-
- if ((dfile = __pos4obj_name(name, type)) == NULL) {
- return (-1);
- }
-
- if (!(oflag & O_CREAT)) {
- if ((fd = __open_nc(dfile, oflag, mode)) == -1)
- __pos4obj_clean(dfile);
-
- free(dfile);
- return (fd);
- }
-
- /*
- * We need to make sure that crflag is set iff we actually create
- * the file. We do this by or'ing in O_EXCL, and attempting an
- * open. If that fails with an EEXIST, and O_EXCL wasn't specified
- * by the caller, then the file seems to exist; we'll try an
- * open with O_CREAT cleared. If that succeeds, then the file
- * did indeed exist. If that fails with an ENOENT, however, the
- * file was removed between the opens; we need to take another
- * lap.
- */
- for (;;) {
- if ((fd = __open_nc(dfile, (oflag | O_EXCL), mode)) == -1) {
- if (errno == EEXIST && !(oflag & O_EXCL)) {
- fd = __open_nc(dfile, oflag & ~O_CREAT, mode);
-
- if (fd == -1 && errno == ENOENT)
- continue;
- break;
- }
- } else {
- *crflag = 1;
- }
- break;
- }
-
- free(dfile);
- return (fd);
-}
-
-
-int
-__pos4obj_unlink(const char *name, const char *type)
-{
- int err;
- char *dfile;
-
- if ((dfile = __pos4obj_name(name, type)) == NULL) {
- return (-1);
- }
-
- err = unlink(dfile);
-
- __pos4obj_clean(dfile);
-
- free(dfile);
-
- return (err);
-}
-
-/*
- * This function opens the lock file for each named object
- * the presence of this file in the file system is the lock
- */
-int
-__pos4obj_lock(const char *name, const char *ltype)
-{
- char *dfile;
- int fd;
- int limit = 64;
-
- if ((dfile = __pos4obj_name(name, ltype)) == NULL) {
- return (-1);
- }
-
- while (limit-- > 0) {
- if ((fd = __open_nc(dfile, O_RDWR | O_CREAT | O_EXCL, 0666))
- < 0) {
- if (errno != EEXIST)
- break;
- (void) sleep(1);
- continue;
- }
-
- (void) __close_nc(fd);
- free(dfile);
- return (1);
- }
-
- free(dfile);
- return (-1);
-}
-
-/*
- * Unlocks the file by unlinking it from the filesystem
- */
-int
-__pos4obj_unlock(const char *path, const char *type)
-{
- return (__pos4obj_unlink(path, type));
-}
-
-/*
- * Removes unused hash and type directories that may exist in specified path.
- */
-static void
-__pos4obj_clean(char *path)
-{
- char *p;
- int olderrno;
-
- /*
- * path is either
- * 1) /<objroot>/<type><path> or
- * 2) /<objroot>/.<hash>/<type>/<path>
- *
- * In case 1, there is nothing to clean.
- *
- * Detect case 2 by looking for a '/' after /objroot/ and
- * remove the two trailing directories, if empty.
- */
- if (strchr(path + strlen(objroot), '/') == NULL)
- return;
-
- /*
- * Preserve errno across calls to rmdir. See block comment in
- * __pos4obj_name() for explanation.
- */
- olderrno = errno;
-
- if ((p = strrchr(path, '/')) == NULL)
- return;
- *p = '\0';
-
- (void) rmdir(path);
-
- if ((p = strrchr(path, '/')) == NULL)
- return;
- *p = '\0';
-
- (void) rmdir(path);
-
- errno = olderrno;
-}
-
-
-/*
- * Check that path starts with a /, does not contain a / within it
- * and is not longer than PATH_MAX or NAME_MAX
- */
-int
-__pos4obj_check(const char *path)
-{
- long int i;
-
- /*
- * This assumes that __pos4obj_check() is called before
- * any of the other functions in this file
- */
- if (name_max == 0 || name_max == -1) {
- name_max = pathconf(objroot, _PC_NAME_MAX);
- if (name_max == -1)
- return (-1);
- }
-
- if (*path++ != '/') {
- errno = EINVAL;
- return (-1);
- }
-
- for (i = 0; *path != '\0'; i++) {
- if (*path++ == '/') {
- errno = EINVAL;
- return (-1);
- }
- }
-
- if (i > PATH_MAX || i > name_max) {
- errno = ENAMETOOLONG;
- return (-1);
- }
-
- return (0);
-}