summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/cvs/os2/filesubr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/cvs/os2/filesubr.c')
-rw-r--r--gnu/usr.bin/cvs/os2/filesubr.c154
1 files changed, 139 insertions, 15 deletions
diff --git a/gnu/usr.bin/cvs/os2/filesubr.c b/gnu/usr.bin/cvs/os2/filesubr.c
index fdd0753e032..6236a7415ab 100644
--- a/gnu/usr.bin/cvs/os2/filesubr.c
+++ b/gnu/usr.bin/cvs/os2/filesubr.c
@@ -22,17 +22,12 @@
file system semantics. */
#include <io.h>
+#define INCL_DOSFILEMGR /* File Manager values */
+#define INCL_DOSERRORS
+#include <os2.h>
#include "cvs.h"
-/*
- * I don't know of a convenient way to test this at configure time, or else
- * I'd certainly do it there. -JimB
- */
-#if defined(NeXT)
-#define LOSING_TMPNAM_FUNCTION
-#endif
-
static int deep_remove_dir PROTO((const char *path));
/*
@@ -266,6 +261,41 @@ make_directories (name)
(void) mkdir (name);
}
+/* Create directory NAME if it does not already exist; fatal error for
+ other errors. Returns 0 if directory was created; 1 if it already
+ existed. */
+int
+mkdir_if_needed (name)
+ char *name;
+{
+ if (mkdir (name) < 0)
+ {
+ /* Now, let me get this straight. In IBM C/C++
+ under OS/2, the error string for EEXIST is:
+
+ "The file already exists",
+
+ and the error string for EACCESS is:
+
+ "The file or directory specified is read-only".
+
+ Nonetheless, mkdir() will set EACCESS if the
+ directory *exists*, according both to the
+ documentation and its actual behavior.
+
+ I'm sure that this made sense, to someone,
+ somewhere, sometime. Just not me, here, now. */
+ if (errno != EEXIST
+#ifdef EACCESS
+ && errno != EACCESS
+#endif
+ )
+ error (1, errno, "cannot make directory %s", name);
+ return 1;
+ }
+ return 0;
+}
+
/*
* Change the mode of a file, either adding write permissions, or removing
* all write permissions. Adding write permissions honors the current umask
@@ -656,7 +686,7 @@ fncmp (const char *n1, const char *n2)
== OS2_filename_classes[(unsigned char) *n2]))
n1++, n2++;
return (OS2_filename_classes[(unsigned char) *n1]
- - OS2_filename_classes[(unsigned char) *n1]);
+ - OS2_filename_classes[(unsigned char) *n2]);
}
/* Fold characters in FILENAME to their canonical forms.
@@ -672,7 +702,23 @@ fnfold (char *filename)
}
}
-
+
+/* Generate a unique temporary filename. Returns a pointer to a newly
+ malloc'd string containing the name. Returns successfully or not at
+ all. */
+char *
+cvs_temp_name ()
+{
+ char value[L_tmpnam + 1];
+ char *retval;
+
+ /* FIXME: Does OS/2 have some equivalent to TMPDIR? */
+ retval = tmpnam (value);
+ if (retval == NULL)
+ error (1, errno, "cannot generate temporary filename");
+ return xstrdup (retval);
+}
+
/* Return non-zero iff FILENAME is absolute.
Trivial under Unix, but more complicated under other systems. */
int
@@ -739,8 +785,7 @@ get_homedir ()
return getenv ("HOME");
}
-/* See cvs.h for description. On OS/2 this does nothing, but it probably
- should be expanding wildcards like on NT. */
+/* See cvs.h for description. */
void
expand_wild (argc, argv, pargc, pargv)
int argc;
@@ -749,8 +794,87 @@ expand_wild (argc, argv, pargc, pargv)
char ***pargv;
{
int i;
- *pargc = argc;
- *pargv = (char **) xmalloc (argc * sizeof (char *));
+ int new_argc;
+ char **new_argv;
+ /* Allocated size of new_argv. We arrange it so there is always room for
+ one more element. */
+ int max_new_argc;
+
+ new_argc = 0;
+ /* Add one so this is never zero. */
+ max_new_argc = argc + 1;
+ new_argv = (char **) xmalloc (max_new_argc * sizeof (char *));
for (i = 0; i < argc; ++i)
- (*pargv)[i] = xstrdup (argv[i]);
+ {
+ HDIR FindHandle = 0x0001;
+ FILEFINDBUF3 FindBuffer;
+ ULONG FindCount = 1;
+ APIRET rc; /* Return code */
+#define ALL_FILES (FILE_ARCHIVED|FILE_DIRECTORY|FILE_SYSTEM|FILE_HIDDEN|FILE_READONLY)
+
+ rc = DosFindFirst(argv[i], /* File pattern */
+ &FindHandle, /* Directory search handle */
+ ALL_FILES, /* Search attribute */
+ (PVOID) &FindBuffer, /* Result buffer */
+ sizeof(FindBuffer), /* Result buffer length */
+ &FindCount, /* Number of entries to find */
+ FIL_STANDARD); /* Return level 1 file info */
+
+ if (rc != 0)
+ {
+ if (rc == ERROR_FILE_NOT_FOUND)
+ {
+ /* No match. The file specified didn't contain a wildcard (in which case
+ we clearly should return it unchanged), or it contained a wildcard which
+ didn't match (in which case it might be better for it to be an error,
+ but we don't try to do that). */
+ new_argv [new_argc++] = xstrdup (argv[i]);
+ if (new_argc == max_new_argc)
+ {
+ max_new_argc *= 2;
+ new_argv = xrealloc (new_argv, max_new_argc * sizeof (char *));
+ }
+ }
+ else
+ {
+ error (1, rc, "cannot find %s", argv[i]);
+ }
+ }
+ else
+ {
+ while (1)
+ {
+ /*
+ * Don't match ".", "..", and files starting with '.'
+ * (unless pattern also starts with '.'). This is
+ * (more or less) what standard Unix globbing does.
+ */
+ if ((strcmp(FindBuffer.achName, ".") != 0) &&
+ (strcmp(FindBuffer.achName, "..") != 0) &&
+ ((argv[i][0] == '.') || (FindBuffer.achName[0] != '.')))
+ {
+ new_argv [new_argc++] = xstrdup (FindBuffer.achName);
+ if (new_argc == max_new_argc)
+ {
+ max_new_argc *= 2;
+ new_argv = xrealloc (new_argv, max_new_argc * sizeof (char *));
+ }
+ }
+
+ rc = DosFindNext(FindHandle,
+ (PVOID) &FindBuffer,
+ sizeof(FindBuffer),
+ &FindCount);
+ if (rc == ERROR_NO_MORE_FILES)
+ break;
+ else if (rc != NO_ERROR)
+ error (1, rc, "cannot find %s", argv[i]);
+ }
+ rc = DosFindClose(FindHandle);
+ if (rc != 0)
+ error (1, rc, "cannot close %s", argv[i]);
+ }
+ }
+ *pargc = new_argc;
+ *pargv = new_argv;
}