view toys/posix/mkdir.c @ 1189:95ae2805622f draft

Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate Confirmed with him on IRC it's ok to use under toybox license, glued the files together and hammered square peg into round hole, no other changes yet.
author Rob Landley <rob@landley.net>
date Fri, 31 Jan 2014 06:01:30 -0600
parents 2115856395e2
children c6c5565cc859
line wrap: on
line source

/* mkdir.c - Make directories
 *
 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org>
 *
 * See http://opengroup.org/onlinepubs/9699919799/utilities/mkdir.html

USE_MKDIR(NEWTOY(mkdir, "<1vpm:", TOYFLAG_BIN|TOYFLAG_UMASK))

config MKDIR
  bool "mkdir"
  default y
  help
    usage: mkdir [-vp] [-m mode] [dirname...]
    Create one or more directories.

    -m	set permissions of directory to mode.
    -p	make parent directories as needed.
    -v	verbose
*/

#define FOR_mkdir
#include "toys.h"

GLOBALS(
  char *arg_mode;

  mode_t mode;
)

static int do_mkdir(char *dir)
{
  struct stat buf;
  char *s;

  // mkdir -p one/two/three is not an error if the path already exists,
  // but is if "three" is a file.  The others we dereference and catch
  // not-a-directory along the way, but the last one we must explicitly
  // test for. Might as well do it up front.

  if (!stat(dir, &buf) && !S_ISDIR(buf.st_mode)) {
    errno = EEXIST;
    return 1;
  }

  for (s=dir; ; s++) {
    char save=0;
    mode_t mode = 0777&~toys.old_umask;

    // Skip leading / of absolute paths.
    if (s!=dir && *s == '/' && (toys.optflags&FLAG_p)) {
      save = *s;
      *s = 0;
    } else if (*s) continue;

    // Use the mode from the -m option only for the last directory.
    if (save == '/') mode |= 0300;
    else if (toys.optflags&FLAG_m) mode = TT.mode;

    if (mkdir(dir, mode)) {
      if (!(toys.optflags&FLAG_p) || errno != EEXIST) return 1;
    } else if (toys.optflags&FLAG_v)
      fprintf(stderr, "%s: created directory '%s'\n", toys.which->name, dir);
    
    if (!(*s = save)) break;
  }

  return 0;
}

void mkdir_main(void)
{
  char **s;

  if(toys.optflags&FLAG_m) TT.mode = string_to_mode(TT.arg_mode, 0777);

  for (s=toys.optargs; *s; s++) if (do_mkdir(*s)) perror_msg("'%s'", *s);
}