Unix Warmup
Document Sample


Unix Warmup
Ssh -Y poseidon.cs.kent.edu
emacs ~/bin
(k)hexedit a.out
double * ys;
memcpy(ys,xs,size);
ys+=size;
Inode
df
du
Directories, File info
The shell command ls provides information on
a file's
size, ownership, group, type
The shell command stat (on Linux systems)
provides, in addition,
device types, uid, gid, inode
access, modify, and change times
How does the program get this information?
File System Organization
What is a directory?
It is a special kind of file that contains a list of
files and/or other directories. Every directory
contains the itesm “.” and “..”
opendir(name)-Opens a directory stream.
Returns a DIR *.
readdir(DIR *)-gets next record for directory
and returns a struct dirent *.
closedir(DIR *)-close the directory stream.
struct dirent
struct dirent
{
long d_ino; /* inode number */
off_t d_off; /* offset to this dirent */
unsigned short d_reclen; /* length of this d_name */
char d_name [NAME_MAX+1]; /* file name (nullterminated) */
}
Sample Code
/** ls1.c
** purpose list contents of directory or directories
** action if no args, use . else list files in args
**/
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
void do_ls(char []);
main(int ac, char *av[])
{ if ( ac == 1 )
do_ls( "." );
else
while ( ac ){
printf("%s:\n", *++av );
do_ls( *av );
}
}
Sample Code
void do_ls( char dirname[] )
/*
* list files in directory called dirname
*/
{
DIR *dir_ptr; /* the directory */
struct dirent *direntp; /* each entry */
if ( ( dir_ptr = opendir( dirname ) ) == NULL )
fprintf(stderr,"ls1: cannot open %s\n", dirname);
else
{
while ( ( direntp = readdir( dir_ptr ) ) != NULL )
printf("%s\n", direntp>d_name );
closedir(dir_ptr);
}
}
Reading Inodes Data
The information about a file is stored in an
inode.
When the file system is created, a table of
inodes is created to store file information.
A directory only contains the name of a file and
the files inode number.
To find out the size, type, owner, etc of a file we
need to access its inode with the system call
stat.
stat
NAME
stat, fstat, lstat get file status
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *file_name, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *file_name, struct stat *buf);
Stat
DESCRIPTION
These functions return information about the specified file. You do
not need any access rights to the file to get this information but you
need search rights to all directories named in the path leading to the
file.
stat stats the file pointed to by file_name and fills in buf.
lstat is identical to stat, except in the case of a symbolic link,
where the link itself is stated, not the file that it refers to.
fstat is identical to stat, only the open file pointed to by filedes
(as returned by open(2)) is stated in place of file_name.
Stat
They all return a stat structure, which contains the following fields:
struct stat {
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device type (if inode device) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
fileinfo.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
void show_stat_info(char *, struct stat *);
int main(int ac, char *av[])
{struct stat info; /* buffer for file info */
if (ac>1)
if( stat(av[1], &info) != -1 ){
show_stat_info( av[1], &info );
return 0;
}
else
perror(av[1]); /* report stat() errors */
return 1;
}
fileinof.c
void show_stat_info(char *fname, struct stat *buf)
{printf(" mode: %o\n", buf->st_mode); /* type + mode */
printf(" links: %d\n", buf->st_nlink);/* # links */
printf(" user: %d\n", buf->st_uid); /* user id */
printf(" group: %d\n", buf->st_gid); /* group id */
printf(" size: %d\n", buf->st_size); /* file size */
printf("modtime: %d\n", buf->st_mtime);/* modified */
printf(" name: %s\n", fname ); /* filename */
}
mode number
1 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0
rwrwr
umask
UMASK(2) Linux Programmer's Manual UMASK(2)
NAME
umask set file creation mask
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);
DESCRIPTION
umask sets the umask to mask & 0777.
The umask is used by open(2) to set initial file permissions on a
newlycreated file. Specifically, permissions in the umask are turned
off from the mode argument to open(2) (so, for example, the common
umask default value of 022 results in new files being created with per
missions 0666 & ~022 = 0644 = rwrr in the usual case where the
mode is specified as 0666).
Using Masks
Stat constants
#define S_IFMT 0170000 /* bitmask for the file type bitfields*/
#define S_IFSOCK 0140000 /*socket*/
Stat macros:
#define S_ISFIFO(m) (((m) & 0170000)) == (0010000))
Macros and constants listed in man pages
Masks
S_IFMT 0170000 bitmask for the file type bitfields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 fifo
Masks
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set GID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
Setting mode bits
The mode bits can be set with open:
fid = open(filestr, O_CREAT|O_WRONLY|O_TRUNC,
S_IRWXU|S_IRGRP|S_IROTH)
In a shell, one can use chmod:
chmod u+rwx,g+r,o+r myfile
getpwuid
struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
struct passwd {
char *pw_name; /* user name */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user id */
gid_t pw_gid; /* group id */
char *pw_gecos; /* real name */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
getgrgid
struct group *getgrnam(const char *name);
struct group *getgrgid(gid_t gid);
struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group id */
char **gr_mem; /* group members */
};
Note: a users can be in more than one group.
Set UID and Set GID bits
For executable files if these bits are set, the the process will run with the
user and/or group permissions of the owner of the file rather than the user
that started the process
The set GID bit (S_ISGID) has several special uses: For a directory it
indicates that BSD semantics is to be used for that directory: files created
there inherit their group ID from the directory, not from the effective gid of
the creating process, and directories created there will also get the S_ISGID
bit set. For a file that does not have the group execution bit (S_IXGRP)
set, it indicates mandatory file/record locking.
The 'sticky' bit (S_ISVTX) on a directory means that a file in that directory
can be renamed or deleted only by the owner of the file, by the owner of
the directory, and by root.
links
stat reports the the number of links associated with an object. What is that?
When a file is added to a directory, a link is established. When it is removed
its link to that directory is removed. A file can be linked to any number of
different directories and have any number of different names in a directory.
The shell commands link and ln and the system call link will create links
between files in the same file system.
To link files in different file systesm use a symbolic (ln -s, symlink) link.
Modification and Access Times
Modify: The last time the file was written to
Access: The last time the file was read
Change: The last time the permission bits were
changed.
One can change the Access and Modify times
with utime and touch.
Ownership and Group
The shell command and system command
chown can change the ownership of a file
The shell command chgrp and system
command chown can change the group of a
file.
Exercise 3.18
Recursive ls. Standard ls supports the R option. This option lists the
contents of a directory and the contents of all directories below it.
Modify ls2.c to support the R option. Windows program will need to use
GetFileAttributes.
Due February 9
C issues
C Question: What does
strutptr= (struct mystrct *) malloc(nstructs * sizeof(struct mystrct));
do?
safe_read
size_t safe_read(int fd, void *buf, size_t count)
{
size_t n;
do {
n = read(fd, buf, count);
} while (n < 0 && errno == EINTR);
return n;
}
Windows:UNICODE & GENERIC
CHARACTERS
Windows NT supports 16-bit characters
WCHAR or wchar_t
To assure maximum flexibility and source portability, define all characters and strings
using “generic” type TCHAR
Calculate lengths using sizeof(TCHAR)
Include #define UNICODE (to get WCHAR) in all source modules (or #undef
UNICODE to get CHAR)
Define UNICODE before #include <windows.h>
Also define _UNICODE consistently for the generic C library library
Unicode Strings
Constant strings in one of three forms (first 2 are ANSI C)
The last is a macro
"This string uses 8-bit characters"
L"This string uses 16-bit characters"
_T ("This string uses generic characters")
Expands to “T…” if UNICODE is not defined; L”T…” if it is
TEXT macro is the same as _T
LPTSTR expands to either char * or wchar_t *
_?
TEXT vs. _TEXT vs. _T, and UNICODE vs. _UNICODE
The plain versions without the underscore affect the character set the Windows
header files treat as default. So if you define UNICODE, then GetWindowText will
map to GetWindowTextW instead of GetWindowTextA, for example. Similarly,
the TEXT macro will map to L"..." instead of "...".
The versions with the underscore affect the character set the C runtime header files
treat as default. So if you define _UNICODE, then _tcslen will map to wcslen
instead of strlen, for example. Similarly, the _TEXT macro will map to L"..."
instead of "...".
C runtime library
Define _UNICODE consistently with UNICODE
This makes available a wide class of string processing and I/O functions
_fgettc, _itot, _ttoi, _totupper, _totlower
And many more — nearly the complete library
Also, localespecific functions (language specific) (seven in all):
lstrlen, lstrcmp, lstrcpy, lstrcat, …
Be sure to #include <tchar.h> after <windows.h>
Note: Any _ keyword or function is specific to Microsoft
Visual C++ and the Microsoft compiler
Main Program
Windows main is for ASCII; wmain is for Unicode
In place of int main (argc, char * argv[])
or int main (argc, w_char * argv[])
Use #include <tchar.h>
/* this is after <windows.h> */
... int _tmain (int argc, LPTSTR argv[])
The _tmain macro then expands to main or wmain
Depending on definition of _UNICODE
This assures correct operation in all circumstances and combinations
FILE AND DIRECTORY MANAGEMENT
BOOL DeleteFile (LPCTSTR lpFileName)
You cannot delete an open file in Windows NT
(You can in Windows 9x)
FILE AND DIRECTORY MANAGEMENT
Renaming Files
BOOL MoveFile (LPCTSTR lpExisting,
LPCTSTR lpNew)
Source and target files must be on the same drive. Fails if file lpNew exists.
BOOL MoveFileEx (LPCTSTR lpExisting,
LPCTSTR lpNew, DWORD dwFlags)
Source and target files can be on different drives. Succeeds if lpNew exists.
Note: There are no soft links as in UNIX
Shortcuts are not the same thing; they are only recognized by the visual shell
Renaming
Parameters
lpExisting — The name of the existing file or directory
lpNew — Cannot exist with MoveFile
Directories must be on same file system. If NULL the existing
file is deleted
dwFlags
MOVEFILE_REPLACE_EXISTING
To replace an existing file
MOVEFILE_COPY_ALLOWED
Copy then delete
Directories
BOOL CreateDirectory (LPCTSTR lpPath,
LPSECURITY_ATTRIBUTES lpsa)
BOOL RemoveDirectory (LPCTSTR lpPath)
lpPath
Points to a nullterminated string with the directory name
Directories
BOOL SetCurrentDirectory (LPCTSTR lpCurDir)
lpCurDir
The path to the new current directory
There is actually a current directory maintained for each drive
SetCurrentDirectory (TEXT("C:"));
Will set the C: drive directory to its current value
Directories
DWORD GetCurrentDirectory (DWORD cchCurDir,
LPTSTR lpCurDir)
Return:
The string length of the returned pathname
The required buffer size if the buffer is not large enough
This includes the space for the null string terminator
Zero if the function fails
Directories
Windows uses this technique whenever the result’s length is not known
Parameters
cchCurDir
Character length of the buffer for the directory name
cch “Count in characters”
lpCurDir
Points to the buffer to receive the pathname string
Directories
HANDLE FindFirstFile (LPCTSTR lpFilename,
, LPWIN32_FIND_DATA lpffd);
Return:
A search handle. INVALID_HANDLE_VALUE indicates failure.
FindFirstFile examines both subdirectory and filenames, looking for a
Name match (could be "*"). The returned handle is used in subsequent
searches.
typedef struct _WIN32_FIND_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
TCHAR cFileName[ MAX_PATH ];
TCHAR cAlternateFileName[ 14 ];
} WIN32_FIND_DATA,*PWIN32_FIND_DATA,
*LPWIN32_FIND_DATA;
Directories
BOOL FindNextFile (HANDLE hFindFile,
, LPWIN32_FIND_DATA lpffd);
Return:
FALSE in cases of invalid arguments or if no more matching files can be
found, in which cass the GetLastError will return
ERROR_NO_MORE_FILES.
Directories
BOOL FindClose (HANDLE hFindFile,LPWIN32_FIND_DATA lpffd);
PWD
/* cl DWIN32 PWD.C PRINTMSG.C REPRTERR.C */
#include "EvryThng.h"
#define DIRNAME_LEN MAX_PATH + 2
int _tmain (int argc, LPTSTR argv [])
{ /* Buffer to receive current directory allows for the CR,
LF at the end of the longest possible path. */
TCHAR pwdBuffer [DIRNAME_LEN];
DWORD LenCurDir;
LenCurDir = GetCurrentDirectory (DIRNAME_LEN, pwdBuffer);
if (LenCurDir == 0)
ReportError (_T ("Failure getting pathname."), 1, TRUE);
if (LenCurDir > DIRNAME_LEN)
ReportError (_T ("Pathname is too long."), 2, FALSE);
PrintMsg (GetStdHandle (STD_OUTPUT_HANDLE), pwdBuffer);
return 0;
}
Get documents about "