source: trunk/third/xmh/miscfuncs.c @ 9658

Revision 9658, 4.0 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9657, which included commits to RCS files with non-trunk default branches.
RevLine 
[9657]1/* $XConsortium: miscfuncs.c,v 1.6 91/07/13 17:52:59 gildea Exp $ */
2
3#include <X11/Xos.h>
4
5#ifndef X_NOT_POSIX
6#include <dirent.h>
7#else
8#ifdef SYSV
9#include <dirent.h>
10#else
11#ifdef USG
12#include <dirent.h>
13#else
14#include <sys/dir.h>
15#ifndef dirent
16#define dirent direct
17#endif
18#endif
19#endif
20#endif
21
22char *malloc();
23char *realloc();
24
25
26
27#if defined(SYSV) && (defined(SYSV386) || defined(MOTOROLA))
28
29/* These systems don't have the ftruncate() system call, so we emulate it.
30 * This emulation can only shorten, not lengthen.
31 * For convenience, we pass in the name of the file, even though the
32 * real ftruncate doesn't.
33 */
34
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <fcntl.h>
38#include <stdio.h>
39
40#define CHUNKSIZE 1024
41
42int ftruncate_emu(fd, length, name)
43    int fd;
44    off_t length;
45    char *name;
46{
47    char            tmp_file[15];
48    int             new_fid, bytes_left, i;
49    unsigned char   buffer[CHUNKSIZE];
50    struct stat     stat_val;
51
52    /* Open a temp file. */
53    sprintf(tmp_file, ".xmhtmp%d~", getpid());
54    (void) unlink(tmp_file);
55    new_fid = open(tmp_file, O_RDWR | O_CREAT);
56    lseek(fd, (off_t)0, 0);
57       
58    /* Copy original file to temp file. */
59    for (i = 0; i < length / CHUNKSIZE; i++) {
60        if (read(fd, buffer, CHUNKSIZE) != CHUNKSIZE) {
61            (void)fprintf(stderr, "xmh: read error in ftruncate emulation\n");
62            return -1;
63        }
64        else if (write(new_fid, buffer, CHUNKSIZE) != CHUNKSIZE) {
65            (void)fprintf(stderr, "xmh: write error in ftruncate emulation\n");
66            return -1;
67        }
68    }
69    bytes_left = length % CHUNKSIZE;
70    if (read(fd, buffer, bytes_left) != bytes_left) {
71        (void)fprintf(stderr, "xmh: read error in ftruncate() emulation\n");
72        return -1;
73    }
74    else if (write(new_fid, buffer, bytes_left) != bytes_left) {
75        (void)fprintf(stderr, "xmh: write error in ftruncate() emulation\n");
76        return -1;
77    }
78
79    /* Set mode of temp file to that of original file. */
80    (void) fstat(fd, &stat_val);
81    (void) chmod(tmp_file, stat_val.st_mode);
82
83    /* Close files, delete original, rename temp file to original. */
84    (void) myclose(new_fid);
85    (void) myclose(fd);
86    (void) unlink(name);        /* remove original */
87    (void) rename(tmp_file, name); /* rename temp file */
88
89    /* If we weren't going to close the file right away in the one
90       place this is called from, we'd have to do something like this:
91    new_fid = myopen(name, O_RDWR, 0666);
92    if (new_fid != fd) {
93        dup2(new_fid, fd);
94        close(new_fid);
95    }
96       but the file does get closed, so we don't bother. */
97
98    return 0;
99}
100#endif /* SYSV variant that needs ftruncate emulation */
101
102
103/*
104**  This code is by Rich Salz (rsalz@bbn.com), and ported to SVR4
105**  by David Elliott (dce@smsc.sony.com).  No copyrights were found
106**  in the original.  Subsequently modified by Bob Scheifler.
107*/
108
109/* A convenient shorthand. */
110typedef struct dirent    ENTRY;
111
112/* Initial guess at directory size. */
113#define INITIAL_SIZE    20
114
115static int StrCmp(a, b)
116    char **a, **b;
117{
118    return strcmp(*a, *b);
119}
120
121int
122ScanDir(Name, List, Selector)
123    char                  *Name;
124    char                ***List;
125    int                  (*Selector)();
126{
127    register char        **names;
128    register ENTRY        *E;
129    register DIR          *Dp;
130    register int           i;
131    register int           size;
132
133    /* Get initial list space and open directory. */
134    size = INITIAL_SIZE;
135    if (!(names = (char **)malloc(size * sizeof(char *))) ||
136        !(Dp = opendir(Name)))
137        return(-1);
138
139    /* Read entries in the directory. */
140    for (i = 0; E = readdir(Dp); )
141        if (!Selector || (*Selector)(E->d_name)) {
142            /* User wants them all, or he wants this one. */
143            if (++i >= size) {
144                size <<= 1;
145                names = (char**)realloc((char *)names, size * sizeof(char*));
146                if (!names) {
147                    closedir(Dp);
148                    return(-1);
149                }
150            }
151
152            /* Copy the entry. */
153            if (!(names[i - 1] = (char *)malloc(strlen(E->d_name) + 1))) {
154                closedir(Dp);
155                return(-1);
156            }
157            (void)strcpy(names[i - 1], E->d_name);
158        }
159
160    /* Close things off. */
161    names[i] = (char *)0;
162    *List = names;
163    closedir(Dp);
164
165    /* Sort? */
166    if (i)
167        qsort((char *)names, i, sizeof(char *), StrCmp);
168
169    return(i);
170}
Note: See TracBrowser for help on using the repository browser.