-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmkdir.cc
129 lines (107 loc) · 3.36 KB
/
mkdir.cc
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
126
127
128
129
/** Rohit Sindhu [sindh010]
* Aravind Alagiri Ramkumar [alagi005]
* Aparna Mahadevan [mahad028]
*/
/**
* An mkdir for a simulated file system.
* @author Ray Ontko -> Converted to C++ by Kwangsung
*/
#include "Kernel.h"
#include "DirectoryEntry.h"
#include "Stat.h"
#include <stdlib.h>
#include <cstring>
int main(int argc, char ** argv)
{
char PROGRAM_NAME[8];
strcpy(PROGRAM_NAME, "mkdir");
char name[64];
char parentName[64];
memset(name, '\0', 64);
memset(parentName, '\0', 64);
// initialize the file system simulator kernel
if(Kernel::initialize() == false)
{
cout << "Failed to initialized Kernel" << endl;
Kernel::exit(1);
}
// print a helpful message if no command line arguments are given
if(argc < 2)
{
cout << PROGRAM_NAME << ": too few arguments" << endl;
Kernel::exit( 1 ) ;
}
// create a buffer for writing directory entries
char directoryEntryBuffer[DirectoryEntry::DIRECTORY_ENTRY_SIZE];
memset(directoryEntryBuffer, '\0', DirectoryEntry::DIRECTORY_ENTRY_SIZE);
// for each argument given on the command line
for( int i = 1 ; i < argc; i ++ )
{
strcpy(name, argv[i]);
int status = 0 ;
// call creat() to create the file
int newDir = Kernel::creat( name , Kernel::S_IFDIR ) ;
if( newDir < 0 )
{
Kernel::perror( PROGRAM_NAME ) ;
cout << PROGRAM_NAME << ": \"" << name << "\"" << endl ;
Kernel::exit( 2 ) ;
}
// get file info for "."
Stat selfStat;
status = Kernel::fstat( newDir , selfStat ) ;
if( status < 0 )
{
Kernel::perror( PROGRAM_NAME ) ;
Kernel::exit( 3 ) ;
}
// cout <<"Ino " << selfStat.getIno() << endl;
// add entry for "."
DirectoryEntry self(selfStat.getIno() , ".");
memset(directoryEntryBuffer, '\0', DirectoryEntry::DIRECTORY_ENTRY_SIZE);
self.write( directoryEntryBuffer , 0) ;
// cout << "From mkdir " << self.toString() << endl;
status = Kernel::write(newDir, directoryEntryBuffer, DirectoryEntry::DIRECTORY_ENTRY_SIZE ) ;
if( status < 0 )
{
Kernel::perror( PROGRAM_NAME ) ;
Kernel::exit( 4 ) ;
}
// get file info for ".."
Stat parentStat;
string fullPath(argv[i]);
// remove trailing '/'
fullPath = fullPath.substr(0, fullPath.find_last_not_of("/"));
string parentDirName = fullPath.substr(0, fullPath.find_last_of("/"));
sprintf(parentName, parentDirName.c_str());
Kernel::stat(parentName , parentStat);
// add entry for ".."
DirectoryEntry parent(parentStat.getIno() , "..");
memset(directoryEntryBuffer, '\0', DirectoryEntry::DIRECTORY_ENTRY_SIZE);
parent.write( directoryEntryBuffer , 0 );
status = Kernel::write(newDir , directoryEntryBuffer, DirectoryEntry::DIRECTORY_ENTRY_SIZE) ;
if( status < 0 )
{
Kernel::perror( PROGRAM_NAME ) ;
Kernel::exit( 5 ) ;
}
// call close() to close the file
status = Kernel::close( newDir ) ;
if( status < 0 )
{
Kernel::perror( PROGRAM_NAME ) ;
Kernel::exit( 6 ) ;
}
// Update new directory entry's link count
FileSystem *fileSystem = Kernel::openFileSystems;
IndexNode indexNode;
fileSystem->readIndexNode(&indexNode, selfStat.getIno());
indexNode.setNlink(2);
fileSystem->writeIndexNode(&indexNode, selfStat.getIno());
fileSystem->readIndexNode(&indexNode, parent.getIno());
indexNode.setNlink(indexNode.getNlink() + 1);
fileSystem->writeIndexNode(&indexNode, parent.getIno());
}
// exit with success if we process all the arguments
Kernel::exit( 0 ) ;
}