#include <stdio.h> // for NULL
// stdio,h includes stddef.h, which defines NULL:
// /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h:
// #define NULL ((void *)0)
#include <assert.h> // for assert()
int do_something(void) {return 0;}
int main()
{
int i, status;
for (i = 0; i < 100; i++)
{
status = do_something();
assert(status == 0);
}
char *p = NULL;
assert(p != NULL);
return 0;
}
/*
gcc assert.c -o assert
./assert
assert: assert.c:21: main: Assertion `p != NULL' failed.
Aborted (core dumped)
gcc -DNDEBUG assert.c -o assert
./assert
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdio.h> // fprintf(), stderr, perror()
#include <string.h> // for strerror()
#include <stdlib.h> // for exit()
#include <errno.h> // for errno macro
// errno.h includes x86_64-linux-gnu/bits/errno,h, which includes
// linux/errno.h, which includes asm-generic/errno.h, which includes
// asm-generic/errno-base.h, which defines ENOENT:
// #define ENOENT 2 /* No such file or directory */
#include <fcntl.h> // for open(), O_RDONLY
// fcntl.h includes x86_64-linux-gnu/bits/fcntl-linux.h,
// which defines O_RDONLY
int main()
{
int fd; // file descriptor
fd = open ("inputfile.txt", O_RDONLY); // open for reading only
if (fd == -1)
{ /* The open failed. Print an error message and exit: */
fprintf (stderr, "Error number: %d\n", ENOENT);
fprintf (stderr, "Error number: %d\n", errno);
fprintf (stderr, "Error opening file: %s\n", strerror(errno));
perror("main");
exit (1); // end program, signalling error
}
return 0;
}
/*
gcc open.c -o open
./open
Error number: 2
Error number: 2
Error opening file: No such file or directory
main: No such file or directory
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdio.h> // printf(), scanf(), fprintf(), stderr
#include <string.h> // for strerror()
#include <stdlib.h> // for exit(), abort()
#include <assert.h> // for assert()
#include <errno.h> // for errno macro
/*
errno.h includes x86_64-linux-gnu/bits/errno,h, which includes
linux/errno.h, which includes asm-generic/errno.h, which includes
asm-generic/errno-base.h, which defines:
#define EPERM 1 // Operation not permitted
#define ENOENT 2 // No such file or directory
#define EINTR 4 // Interrupted system call
#define EIO 5 // I/O error
#define ENOMEM 12 // Out of memory
#define EACCES 13 // Permission denied
#define EFAULT 14 // Bad address
#define ENOTDIR 20 // Not a directory
#define EINVAL 22 // Invalid argument
#define EROFS 30 // Read-only file system
asm-generic/errno.h defines:
#define ENAMETOOLONG 36 // File name too long
#define ELOOP 40 // Too many symbolic links encountered
*/
#include <unistd.h> // for chown(), getuid(), getgid()
#include <linux/limits.h> // for PATH_MAX, NAME_MAX
// #define NAME_MAX 255 /* # chars in a file name */
// #define PATH_MAX 4096 /* # chars in a path name including nul */
#include <sys/stat.h> // for struct stat, stat()
#include <sys/types.h> // uid_t, gid_t
#include <pwd.h> // for struct passwd, getpwuid()
char * getUser(uid_t uid)
{
struct passwd *pws;
pws = getpwuid(uid);
return pws->pw_name;
}
int main()
{
char path[PATH_MAX];
int rval; // return value
struct stat s;
uid_t uid;
gid_t gid;
printf("Path: ");
scanf("%s", path);
uid = getuid();
gid = getgid();
printf("User ID: %d (%s)\n", uid, getUser(uid));
printf("Group ID: %d\n", gid);
rval = chown(path, uid, gid);
if (rval != 0)
{ /* Save errno because it's clobbered by the next system call: */
int error_code = errno;
/* The operation didn't succeed; chown() should return -1 on error: */
assert(rval == -1);
/* Check the value of errno, and take appropriate action: */
switch (error_code)
{
case EPERM: /* Permission denied. */
case EROFS: /* PATH is on a read-only file system. */
case EACCES: /* A component of PATH is not accessible. */
if (stat(path, &s) != -1)
{
printf("File user ID: %d (%s)\n", s.st_uid, getUser(s.st_uid));
printf("File group ID: %d\n", s.st_gid);
}
case ENAMETOOLONG: /* PATH is too long. */
case ENOENT: /* PATH does not exist. */
case ENOTDIR: /* A component of PATH is not a directory. */
case EIO: // I/O error
case EINVAL: // Invalid argument
case ELOOP: // Too many symbolic links encountered
/* Something's wrong with the file. Print an error message: */
fprintf (stderr, "Error number: %d\n", error_code);
fprintf (stderr, "Error changing ownership of \"%s\": %s\n",
path, strerror (error_code));
/* Don't end the program; perhaps give the user a chance to
choose another file... */
break;
case EFAULT: // path contains invalid mem address, probably a bug
abort(); // used for debugging
case ENOMEM: /* Ran out of kernel memory. */
case EINTR: // Interrupted system call
fprintf (stderr, "%s\n", strerror (error_code));
exit(1); // no debugging
default: // unexpected error code, probably a bug
abort(); // used for debugging
}
}
return 0;
}
/*
gcc chown.c -o chown
./chown
Path: /home/user/.bash_history
User ID: 1000 (user)
Group ID: 1001
// No error
./chown
Path: /etc/environment
User ID: 1000 (user)
Group ID: 1001
File user ID: 0 (root)
File group ID: 0
Error number: 1
Error changing ownership of "/etc/environment": Operation not permitted
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdio.h> // for printf(), NULL
#include <stddef.h> // for size_t, ssize_t
#include <stdlib.h> // for malloc(), free()
#include <fcntl.h> // for open(), O_RDONLY
#include <unistd.h> // read(), close()
#define LENGTH 100
char * read_from_file (const char * filename, size_t length);
int main()
{
char *s = read_from_file("readfile.c", LENGTH);
if (s != NULL)
{printf("%s\n", s);}
return 0;
}
char * read_from_file (const char * filename, size_t length)
{
char *buffer;
int fd; // file descriptor
ssize_t bytes_read;
buffer = (char*) malloc (length); /* Allocate the buffer. */
if (buffer == NULL)
{return NULL;}
fd = open (filename, O_RDONLY); /* Open the file for reading. */
if (fd == -1)
{ /* open() failed. Deallocate buffer before returning. */
free (buffer);
return NULL;
}
bytes_read = read (fd, buffer, length); /* Read the data. */
// bytes_read <= length if read() reaches the end of file
// bytes_read == 0 if reading starts at the end of file
if (bytes_read <= 0) // read failed
{ // bytes_read < 0 on error
free (buffer); // Deallocate buffer and
close (fd); // close fd
return NULL; // before returning
}
/* Everything's fine. Close the file and return the buffer. */
close (fd);
return buffer;
}
/*
gcc readfile.c -o readfile
./readfile
#include <stdio.h> // for printf(), NULL // 41 chars with '\n'
#include <stddef.h> // for size_t, ssize_t // 43 chars with '\n'
#include <stdlib // 16 chars, 100 in total
*/