Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
224 volume VI os16<br />
Script e sorgenti del kernel 225<br />
740310 | // There is not such zone, but it is not an error.<br />
740311 | //<br />
740312 | if (!write)<br />
740313 | {<br />
740314 | return ((zno_t) 0);<br />
740315 | }<br />
740316 | //<br />
740317 | // The second level must be initialized.<br />
740318 | //<br />
740319 | allocated_zone = zone_alloc (inode->sb);<br />
740320 | if (allocated_zone == 0)<br />
740321 | {<br />
740322 | //<br />
740323 | // Cannot allocate the zone. The variable ‘errno’ is set<br />
740324 | // by ‘zone_alloc()’.<br />
740325 | //<br />
740326 | return ((zno_t) -1);<br />
740327 | }<br />
740328 | //<br />
740329 | // The zone for the indirection table is allocated:<br />
740330 | // clear the zone and save.<br />
740331 | //<br />
740332 | memset (buffer, 0, SB_MAX_ZONE_SIZE);<br />
740333 | status = zone_write (inode->sb, allocated_zone, buffer);<br />
740334 | if (status < 0)<br />
740335 | {<br />
740336 | //<br />
740337 | // Cannot overwrite the zone. The variable ‘errno’ is<br />
740338 | // set by ‘zone_write()’.<br />
740339 | //<br />
740340 | return ((zno_t) -1);<br />
740341 | }<br />
740342 | //<br />
740343 | // Update the first level index and save it.<br />
740344 | //<br />
740345 | zone_table[i1] = allocated_zone;<br />
740346 | status = zone_write (inode->sb, inode->indirect2, zone_table);<br />
740347 | if (status != 0)<br />
740348 | {<br />
740349 | //<br />
740350 | // Cannot write the zone. The variable ‘errno’ is set<br />
740351 | // by ‘zone_write()’.<br />
740352 | //<br />
740353 | return ((zno_t) -1);<br />
740354 | }<br />
740355 | }<br />
740356 | //<br />
740357 | // The second level can be read, overwriting the array<br />
740358 | // ‘zone_table[]’. The zone number for the second level<br />
740359 | // indirection table is saved inside ‘zone_second’, before<br />
740360 | // overwriting the array.<br />
740361 | //<br />
740362 | zone_second = zone_table[i1];<br />
740363 | status = zone_read (inode->sb, zone_second, zone_table);<br />
740364 | if (status != 0)<br />
740365 | {<br />
740366 | //<br />
740367 | // Cannot read the second level indirect table. The variable<br />
740368 | // ‘errno’ is set by ‘zone_read()’.<br />
740369 | //<br />
740370 | return ((zno_t) -1);<br />
740371 | }<br />
740372 | //<br />
740373 | // The second level was read and ‘zone_table[]’ is now<br />
740374 | // such second one: check if the zone is to be allocated.<br />
740375 | //<br />
740376 | if (zone_table[i2] == 0)<br />
740377 | {<br />
740378 | //<br />
740379 | // There is not such zone, but it is not an error.<br />
740380 | //<br />
740381 | if (!write)<br />
740382 | {<br />
740383 | return ((zno_t) 0);<br />
740384 | }<br />
740385 | //<br />
740386 | // Must be allocated.<br />
740387 | //<br />
740388 | allocated_zone = zone_alloc (inode->sb);<br />
740389 | if (allocated_zone == 0)<br />
740390 | {<br />
740391 | //<br />
740392 | // Cannot allocate the zone. The variable ‘errno’ is set<br />
740393 | // by ‘zone_alloc()’.<br />
740394 | //<br />
740395 | return ((zno_t) -1);<br />
740396 | }<br />
740397 | //<br />
740398 | // The zone is allocated: clear the zone and save.<br />
740399 | //<br />
740400 | memset (buffer, 0, SB_MAX_ZONE_SIZE);<br />
740401 | status = zone_write (inode->sb, allocated_zone, buffer);<br />
740402 | if (status < 0)<br />
740403 | {<br />
740404 | //<br />
740405 | // Cannot overwrite the zone. The variable ‘errno’ is<br />
740406 | // set by ‘zone_write()’.<br />
740407 | //<br />
740408 | return ((zno_t) -1);<br />
740409 | }<br />
740410 | //<br />
740411 | // The zone was allocated and cleared: update the indirect<br />
740412 | // zone table an save it. The inode is not modified, because<br />
740413 | // the indirect table is outside.<br />
740414 | //<br />
740415 | zone_table[i2] = allocated_zone;<br />
740416 | status = zone_write (inode->sb, zone_second, zone_table);<br />
740417 | if (status != 0)<br />
740418 | {<br />
740419 | //<br />
740420 | // Cannot write the zone. The variable ‘errno’ is set<br />
740421 | // by ‘zone_write()’.<br />
740422 | //<br />
740423 | return ((zno_t) -1);<br />
740424 | }<br />
740425 | }<br />
740426 | //<br />
740427 | // The zone is there: return the zone number.<br />
740428 | //<br />
740429 | return (zone_table[i2]);<br />
740430 | }<br />
740431 |}<br />
104.4.32 kernel/fs/path_chdir.c<br />
Si veda la sezione 103.3.30.<br />
750001 |#include <br />
750002 |#include <br />
750003 |#include <br />
750004 |//----------------------------------------------------------------------<br />
750005 |int<br />
750006 |path_chdir (pid_t pid, const char *path)<br />
750007 |{<br />
750008 | proc_t *ps;<br />
750009 | inode_t *inode_directory;<br />
750010 | int status;<br />
750011 | char path_directory[PATH_MAX];<br />
750012 | //<br />
750013 | // Get process.<br />
750014 | //<br />
750015 | ps = proc_reference (pid);<br />
750016 | //<br />
750017 | // The full directory path is needed.<br />
750018 | //<br />
750019 | status = path_full (path, ps->path_cwd, path_directory);<br />
750020 | if (status < 0)<br />
750021 | {<br />
750022 | return (-1);<br />
750023 | }<br />
750024 | //<br />
750025 | // Try to load the new directory inode.<br />
750026 | //<br />
750027 | inode_directory = path_inode (pid, path_directory);<br />
750028 | if (inode_directory == NULL)<br />
750029 | {<br />
750030 | //<br />
750031 | // Cannot access the directory: it does not exists or<br />
750032 | // permissions are not sufficient. Variable ‘errno’ is set by<br />
750033 | // function ‘inode_directory()’.<br />
750034 | //<br />
750035 | errset (errno);<br />
750036 | return (-1);<br />
750037 | }<br />
750038 | //<br />
750039 | // Inode loaded: release the old directory and set the new one.<br />
750040 | //<br />
750041 | inode_put (ps->inode_cwd);<br />
750042 | //<br />
750043 | ps->inode_cwd = inode_directory;<br />
750044 | strncpy (ps->path_cwd, path_directory, PATH_MAX);<br />
750045 | //<br />
750046 | // Return.<br />
750047 | //<br />
750048 | return (0);<br />
750049 |}<br />
104.4.33 kernel/fs/path_chmod.c<br />
Si veda la sezione 103.3.31.<br />
760001 |#include <br />
760002 |#include <br />
760003 |#include <br />
760004 |//----------------------------------------------------------------------<br />
760005 |int<br />
760006 |path_chmod (pid_t pid, const char *path, mode_t mode)<br />
760007 |{<br />
760008 | proc_t *ps;<br />
760009 | inode_t *inode;<br />
760010 | //<br />
760011 | // Get process.<br />
760012 | //<br />
760013 | ps = proc_reference (pid);<br />
760014 | //<br />
760015 | // Try to load the file inode.<br />
760016 | //<br />
760017 | inode = path_inode (pid, path);<br />
760018 | if (inode == NULL)<br />
760019 | {<br />
760020 | //<br />
760021 | // Cannot access the file: it does not exists or permissions are<br />
760022 | // not sufficient. Variable ‘errno’ is set by function<br />
760023 | // ‘inode_directory()’.<br />
760024 | //<br />
760025 | return (-1);<br />
760026 | }<br />
760027 | //<br />
760028 | // Verify to be root or to be the owner.<br />
760029 | //<br />
760030 | if (ps->euid != 0 && ps->euid != inode->uid)<br />
760031 | {<br />
760032 | errset (EACCES); // Permission denied.<br />
760033 | return (-1);<br />
760034 | }<br />
760035 | //<br />
760036 | // Update the mode: the file type is kept and the<br />
760037 | // rest is taken form the parameter ‘mode’.<br />
760038 | //<br />
760039 | inode->mode = (S_IFMT & inode->mode) | (~S_IFMT & mode);<br />
760040 | //<br />
760041 | // Save and release the inode.<br />
760042 | //<br />
760043 | inode->changed = 1;<br />
760044 | inode_save (inode);<br />
760045 | inode_put (inode);<br />
760046 | //<br />
760047 | // Return.<br />
760048 | //<br />
760049 | return (0);<br />
760050 |}<br />
«<br />
«