OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib/] [newlib/] [libc/] [sys/] [go32/] [stat.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 39 lampret
/*
2
  (c) Copyright 1992 Eric Backus
3
 
4
  This software may be used freely so long as this copyright notice is
5
  left intact.  There is no warrantee on this software.
6
*/
7
 
8
#include <sys/stat.h>
9
#include <string.h>
10
#include <stdlib.h>
11
 
12
#include "dos.h"
13
#include <errno.h>
14
#include <stdio.h>
15
 
16
extern int      _stat_assist(const char *, struct stat *);
17
extern void     _fixpath(const char *, char *);
18
 
19
struct path_list
20
{
21
    struct path_list    *next;
22
    char                *path;
23
    int                 inode;
24
};
25
 
26
static int
27
fixinode(const char *path, struct stat *buf)
28
{
29
    static struct path_list     *path_list[1256];
30
    /* Start the inode count at three, since root path should be two */
31
    static int                  inode_count = 3;
32
 
33
    struct path_list            *path_ptr, *prev_ptr;
34
    const char                  *p;
35
    int                         hash;
36
 
37
    /* Skip over device and leading '/' */
38
    if (path[1] == ':' && path[2] == '/') path += 3;
39
 
40
    /* We could probably use a better hash than this */
41
    p = path;
42
    hash = 0;
43
    while (*p != '\0') hash += *p++;
44
    hash = hash & 0xff;
45
 
46
    /* Have we seen this string? */
47
    path_ptr = path_list[hash];
48
    prev_ptr = path_ptr;
49
    while (path_ptr)
50
    {
51
        if (strcmp(path, path_ptr->path) == 0) break;
52
        prev_ptr = path_ptr;
53
        path_ptr = path_ptr->next;
54
    }
55
 
56
    if (path_ptr)
57
        /* Same string, so same inode */
58
        buf->st_ino = path_ptr->inode;
59
    else
60
    {
61
        /* New string with same hash code */
62
        path_ptr = malloc(sizeof *path_ptr);
63
        if (path_ptr == NULL)
64
          {
65
            errno = ENOMEM;
66
            return -1;
67
          }
68
        path_ptr->next = NULL;
69
        path_ptr->path = strdup(path);
70
        if (path_ptr->path == NULL)
71
          {
72
            errno = ENOMEM;
73
            return -1;
74
          }
75
        path_ptr->inode = inode_count;
76
        if (prev_ptr)
77
            prev_ptr->next = path_ptr;
78
        else
79
            path_list[hash] = path_ptr;
80
        buf->st_ino = inode_count;
81
        inode_count++;
82
    }
83
    return 0;
84
}
85
 
86
int
87
stat(const char *path, struct stat *buf)
88
{
89
    static int  stat_called_before = 0;
90
    char        p[1090];        /* Should be p[PATH_MAX+1] */
91
    int         status;
92
 
93
    /* Normalize the path */
94
    _fixpath(path, p);
95
 
96
    /* Work around strange bug with stat and time */
97
    if (!stat_called_before)
98
    {
99
        stat_called_before = 1;
100
        (void) time((time_t *) 0);
101
    }
102
 
103
    /* Check for root path */
104
    if (strcmp(p, "/") == 0 || strcmp(p + 1, ":/") == 0)
105
    {
106
        /* Handle root path as special case, stat_assist doesn't like
107
           the root directory. */
108
        if (p[1] == ':')
109
        {
110
            if (p[0] >= 'a' && p[0] <= 'z')
111
                buf->st_dev = p[0] - 'a';
112
            else
113
                buf->st_dev = p[0] - 'A';
114
        }
115
        else
116
            buf->st_dev = -1;   /* No device? */
117
        buf->st_ino = 2;        /* Root path always inode 2 */
118
        buf->st_mode = S_IFDIR | S_IREAD | S_IWRITE | S_IEXEC;
119
        buf->st_nlink = 1;
120
        buf->st_uid = getuid();
121
        buf->st_gid = getgid();
122
        buf->st_rdev = buf->st_dev;
123
        buf->st_size = 0;
124
        buf->st_atime = 0;
125
        buf->st_mtime = 0;
126
        buf->st_ctime = 0;
127
        buf->st_blksize = 512;  /* Not always correct? */
128
        status = 0;
129
    }
130
    else
131
    {
132
        status = _stat_assist(p, buf);
133
 
134
        /* Make inode numbers unique */
135
        if (status == 0) status = fixinode(p, buf);
136
 
137
        /* The stat_assist does something weird with st_dev, but sets
138
           st_rdev to the drive number.  Fix st_dev. */
139
        buf->st_dev = buf->st_rdev;
140
 
141
        /* Make all files owned by ourself. */
142
        buf->st_uid = getuid();
143
        buf->st_gid = getgid();
144
 
145
        /* Make all directories writable.  They always are in DOS, but
146
           stat_assist doesn't think so. */
147
        if (S_ISDIR(buf->st_mode)) buf->st_mode |= S_IWRITE;
148
    }
149
 
150
    return status;
151
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.