Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] View of /sml/branches/SMLNJ/src/runtime/c-libs/posix-filesys/readlink.c
ViewVC logotype

View of /sml/branches/SMLNJ/src/runtime/c-libs/posix-filesys/readlink.c

Parent Directory Parent Directory | Revision Log Revision Log

Revision 8 - (download) (as text) (annotate)
Sun Jan 18 01:01:29 1998 UTC (22 years, 5 months ago) by monnier
File size: 2183 byte(s)
*** empty log message ***
/* readlink.c
 * COPYRIGHT (c) 1995 by AT&T Bell Laboratories.

#include "ml-unixdep.h"
#include <unistd.h>
#include <sys/stat.h>
#include <limits.h>
#include <sys/param.h>
#include "ml-base.h"
#include "ml-values.h"
#include "ml-objects.h"
#include "ml-c.h"
#include "cfun-proto-list.h"

/* _ml_P_FileSys_readlink : string -> string
 * Read the value of a symbolic link.
 * The following implementation assumes that the system readlink
 * fills the given buffer as much as possible, without nul-termination,
 * and returns the number of bytes copied. If the buffer is not large
 * enough, the return value will be at least the buffer size. In that
 * case, we find out how big the link really is, allocate a buffer to
 * hold it, and redo the readlink.
 * Note that the above semantics are not those of POSIX, which requires
 * null-termination on success, and only fills the buffer up to as most 
 * the penultimate byte even on failure.
 * Should this be written to avoid the extra copy, using heap memory?
ml_val_t _ml_P_FileSys_readlink (ml_state_t *msp, ml_val_t arg)
    char        *path = PTR_MLtoC(char, arg);
    char	buf[MAXPATHLEN];
    int         len;

    len = readlink(path, buf, MAXPATHLEN);

    if (len < 0)
	return RAISE_SYSERR(msp, len);
    else if (len < MAXPATHLEN) {
	buf[len] = '\0';
	return ML_CString (msp, buf);
    else {  /* buffer not big enough */
	char         *nbuf;
	ml_val_t     obj;
	struct stat  sbuf;
	int          res;
	int          nlen;

      /* Determine how big the link text is and allocate a buffer */
	res = lstat (path, &sbuf);
	if (res < 0)
	    return RAISE_SYSERR(msp, res);
	nlen = sbuf.st_size + 1;
	nbuf = MALLOC(nlen);
	if (nbuf == 0)
	    return RAISE_ERROR(msp, "out of malloc memory");

        /* Try the readlink again. Give up on error or if len is still bigger
         * than the buffer size.
	len = readlink(path, buf, len);
	if (len < 0)
	    return RAISE_SYSERR(msp, len);
	else if (len >= nlen)
	    return RAISE_ERROR(msp, "readlink failure");

	nbuf[len] = '\0';
	obj = ML_CString (msp, nbuf);
	FREE (nbuf);
	return obj;

} /* end of _ml_P_FileSys_readlink */

ViewVC Help
Powered by ViewVC 1.0.0