1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
/*
* Written by Robert Rother, Mariah Corporation, August 1985.
*
* If you want it, it's yours. All I ask in return is that if you
* figure out how to do this in a Bourne Shell script you send me
* a copy.
* sdcsvax!rmr or rmr@uscd
*
* Severely hacked over by John Gilmore to make a 4.2BSD compatible
* subroutine. 11Mar86; hoptoad!gnu
*
* Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
* subroutine didn't return EEXIST. It does now.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/stat.h>
#include <errno.h>
#ifndef STD_HEADERS
extern int errno;
#endif
#include <sys/types.h>
#if defined(HAVE_UNISTD_H) || defined(STD_HEADERS)
#include <unistd.h>
#endif
#ifdef _POSIX_VERSION
#include <sys/wait.h>
#else /* !_POSIX_VERSION */
#define WIFSIGNALED(w) (((w) & 0xff) != 0x7f && ((w) & 0xff) != 0)
#define WEXITSTATUS(w) (((w) >> 8) & 0xff)
#endif
/*
* Make a directory.
*/
int
mkdir (dpath, dmode)
char *dpath;
int dmode;
{
int cpid, status;
struct stat statbuf;
if (stat (dpath, &statbuf) == 0)
{
errno = EEXIST; /* Stat worked, so it already exists */
return -1;
}
/* If stat fails for a reason other than non-existence, return error */
if (errno != ENOENT)
return -1;
switch (cpid = fork ())
{
case -1: /* Error in fork() */
return (-1); /* Errno is set already */
case 0: /* Child process */
/*
* Cheap hack to set mode of new directory. Since this
* child process is going away anyway, we zap its umask.
* FIXME, this won't suffice to set SUID, SGID, etc. on this
* directory. Does anybody care?
*/
status = umask (0); /* Get current umask */
status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
_exit (-1); /* Can't exec /bin/mkdir */
default: /* Parent process */
while (cpid != wait (&status)); /* Wait for kid to finish */
}
if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0)
{
errno = EIO; /* We don't know why, but */
return -1; /* /bin/mkdir failed */
}
return 0;
}
int
rmdir (dpath)
char *dpath;
{
int cpid, status;
struct stat statbuf;
if (stat (dpath, &statbuf) != 0)
{
/* Stat just set errno. We don't have to */
return -1;
}
switch (cpid = fork ())
{
case -1: /* Error in fork() */
return (-1); /* Errno is set already */
case 0: /* Child process */
execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
_exit (-1); /* Can't exec /bin/mkdir */
default: /* Parent process */
while (cpid != wait (&status)); /* Wait for kid to finish */
}
if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0)
{
errno = EIO; /* We don't know why, but */
return -1; /* /bin/rmdir failed */
}
return 0;
}
|