}
/* Obtain a file descriptor for the \(aqns\(aq file specified
- in argv[1] */
+ in argv[1]. */
fd = open(argv[1], O_RDONLY);
if (fd == \-1) {
}
/* Obtain a file descriptor for the owning user namespace and
- then obtain and display the inode number of that namespace */
+ then obtain and display the inode number of that namespace. */
if (argc < 3 || strchr(argv[2], \(aqu\(aq)) {
userns_fd = ioctl(fd, NS_GET_USERNS);
}
/* Obtain a file descriptor for the parent namespace and
- then obtain and display the inode number of that namespace */
+ then obtain and display the inode number of that namespace. */
if (argc > 2 && strchr(argv[2], \(aqp\(aq)) {
parent_fd = ioctl(fd, NS_GET_PARENT);
fprintf(fp, "\en");
/*
- * Assume the authority to instantiate the key named in argv[2]
+ * Assume the authority to instantiate the key named in argv[2].
*/
if (keyctl(KEYCTL_ASSUME_AUTHORITY, key_to_instantiate) == \-1) {
fprintf(fp, "KEYCTL_ASSUME_AUTHORITY failed: %s\en",
}
/*
- * Fetch the description of the key that is to be instantiated
+ * Fetch the description of the key that is to be instantiated.
*/
if (keyctl(KEYCTL_DESCRIBE, key_to_instantiate,
dbuf, sizeof(dbuf)) == \-1) {
/*
* Fetch the payload of the authorization key, which is
- * actually the callout data given to request_key()
+ * actually the callout data given to request_key().
*/
akp_size = keyctl(KEYCTL_READ, KEY_SPEC_REQKEY_AUTH_KEY,
auth_key_payload, sizeof(auth_key_payload));
seals_arg = argv[3];
/* Create an anonymous file in tmpfs; allow seals to be
- placed on the file */
+ placed on the file. */
fd = memfd_create(name, MFD_ALLOW_SEALING);
if (fd == \-1)
errExit("memfd_create");
- /* Size the file as specified on the command line */
+ /* Size the file as specified on the command line. */
if (ftruncate(fd, len) == \-1)
errExit("truncate");
(intmax_t) getpid(), fd, (intmax_t) getpid(), fd);
/* Code to map the file and populate the mapping with data
- omitted */
+ omitted. */
/* If a \(aqseals\(aq command\-line argument was supplied, set some
- seals on the file */
+ seals on the file. */
if (seals_arg != NULL) {
seals = 0;
}
/* Keep running, so that the file created by memfd_create()
- continues to exist */
+ continues to exist. */
pause();
printf("\en");
/* Code to map the file and access the contents of the
- resulting mapping omitted */
+ resulting mapping omitted. */
exit(EXIT_SUCCESS);
}
sig = atoi(argv[2]);
/* Obtain a PID file descriptor by opening the /proc/PID directory
- of the target process */
+ of the target process. */
snprintf(path, sizeof(path), "/proc/%s", argv[1]);
}
/* Populate a \(aqsiginfo_t\(aq structure for use with
- pidfd_send_signal() */
+ pidfd_send_signal(). */
memset(&info, 0, sizeof(info));
info.si_code = SI_QUEUE;
info.si_pid = getpid();
info.si_value.sival_int = 1234;
- /* Send the signal */
+ /* Send the signal. */
if (pidfd_send_signal(pidfd, sig, &info, 0) == \-1) {
perror("pidfd_send_signal");
if (pfds == NULL)
errExit("malloc");
- /* Open each file on command line, and add it \(aqpfds\(aq array */
+ /* Open each file on command line, and add it \(aqpfds\(aq array. */
for (int j = 0; j < nfds; j++) {
pfds[j].fd = open(argv[j + 1], O_RDONLY);
}
/* Keep calling poll() as long as at least one file descriptor is
- open */
+ open. */
while (num_open_fds > 0) {
int ready;
printf("Ready: %d\en", ready);
- /* Deal with array returned by poll() */
+ /* Deal with array returned by poll(). */
for (int j = 0; j < nfds; j++) {
char buf[10];
/* Assume that AUDIT_ARCH_X86_64 means the normal x86-64 ABI
(in the x32 ABI, all system calls have bit 30 set in the
- \(aqnr\(aq field, meaning the numbers are >= X32_SYSCALL_BIT) */
+ \(aqnr\(aq field, meaning the numbers are >= X32_SYSCALL_BIT). */
if (t_arch == AUDIT_ARCH_X86_64)
upper_nr_limit = X32_SYSCALL_BIT - 1;
struct sock_filter filter[] = {
/* [0] Load architecture from \(aqseccomp_data\(aq buffer into
- accumulator */
+ accumulator. */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, arch))),
/* [1] Jump forward 5 instructions if architecture does not
- match \(aqt_arch\(aq */
+ match \(aqt_arch\(aq. */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, t_arch, 0, 5),
/* [2] Load system call number from \(aqseccomp_data\(aq buffer into
- accumulator */
+ accumulator. */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, nr))),
/* [3] Check ABI - only needed for x86-64 in deny-list use
cases. Use BPF_JGT instead of checking against the bit
- mask to avoid having to reload the syscall number */
+ mask to avoid having to reload the syscall number. */
BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, upper_nr_limit, 3, 0),
/* [4] Jump forward 1 instruction if system call number
- does not match \(aqsyscall_nr\(aq */
+ does not match \(aqsyscall_nr\(aq. */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall_nr, 0, 1),
/* [5] Matching architecture and system call: don\(aqt execute
- the system call, and return \(aqf_errno\(aq in \(aqerrno\(aq */
+ the system call, and return \(aqf_errno\(aq in \(aqerrno\(aq. */
BPF_STMT(BPF_RET | BPF_K,
SECCOMP_RET_ERRNO | (f_errno & SECCOMP_RET_DATA)),
/* [6] Destination of system call number mismatch: allow other
- system calls */
+ system calls. */
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
- /* [7] Destination of architecture mismatch: kill process */
+ /* [7] Destination of architecture mismatch: kill process. */
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS),
};
sigaddset(&mask, SIGQUIT);
/* Block signals so that they aren\(aqt handled
- according to their default dispositions */
+ according to their default dispositions. */
if (sigprocmask(SIG_BLOCK, &mask, NULL) == \-1)
handle_error("sigprocmask");
handle_error("clock_gettime");
/* Create a CLOCK_REALTIME absolute timer with initial
- expiration and interval as specified in command line */
+ expiration and interval as specified in command line. */
new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
new_value.it_value.tv_nsec = now.tv_nsec;
#include <stdio.h>
/* A simple error\-handling function: print an error message based
- on the value in \(aqerrno\(aq and terminate the calling process */
+ on the value in \(aqerrno\(aq and terminate the calling process. */
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e
} while (0)
exit(EXIT_FAILURE);
}
- /* Obtain a handle for shared object specified on command line */
+ /* Obtain a handle for shared object specified on command line. */
handle = dlopen(argv[1], RTLD_NOW);
if (handle == NULL) {
}
/* Discover the size of the buffer that we must pass to
- RTLD_DI_SERINFO */
+ RTLD_DI_SERINFO. */
if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == \-1) {
fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\en", dlerror());
exit(EXIT_FAILURE);
}
- /* Allocate the buffer for use with RTLD_DI_SERINFO */
+ /* Allocate the buffer for use with RTLD_DI_SERINFO. */
sip = malloc(serinfo.dls_size);
if (sip == NULL) {
}
/* Initialize the \(aqdls_size\(aq and \(aqdls_cnt\(aq fields in the newly
- allocated buffer */
+ allocated buffer. */
if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == \-1) {
fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\en", dlerror());
exit(EXIT_FAILURE);
}
- /* Fetch and print library search list */
+ /* Fetch and print library search list. */
if (dlinfo(handle, RTLD_DI_SERINFO, sip) == \-1) {
fprintf(stderr, "RTLD_DI_SERINFO failed: %s\en", dlerror());
/* This sequence is necessary, because uselocale() might return
the value LC_GLOBAL_LOCALE, which can\(aqt be passed as an
- argument to toupper_l() */
+ argument to toupper_l(). */
loc = uselocale((locale_t) 0);
if (loc == (locale_t) 0)
char *new_buff;
struct memfile_cookie *cookie = c;
- /* Buffer too small? Keep doubling size until big enough */
+ /* Buffer too small? Keep doubling size until big enough. */
while (size + cookie\->offset > cookie\->allocated) {
new_buff = realloc(cookie\->buf, cookie\->allocated * 2);
ssize_t xbytes;
struct memfile_cookie *cookie = c;
- /* Fetch minimum of bytes requested and bytes available */
+ /* Fetch minimum of bytes requested and bytes available. */
xbytes = size;
if (cookie\->offset + size > cookie\->endpos)
size_t nread;
char buf[1000];
- /* Set up the cookie before calling fopencookie() */
+ /* Set up the cookie before calling fopencookie(). */
mycookie.buf = malloc(INIT_BUF_SIZE);
if (mycookie.buf == NULL) {
exit(EXIT_FAILURE);
}
- /* Write command\-line arguments to our file */
+ /* Write command\-line arguments to our file. */
for (int j = 1; j < argc; j++)
if (fputs(argv[j], stream) == EOF) {
exit(EXIT_FAILURE);
}
- /* Read two bytes out of every five, until EOF */
+ /* Read two bytes out of every five, until EOF. */
for (long p = 0; ; p += 5) {
if (fseek(stream, p, SEEK_SET) == \-1) {
exit(EXIT_FAILURE);
}
- /* Fetch passwd structure (contains first group ID for user) */
+ /* Fetch passwd structure (contains first group ID for user). */
pw = getpwnam(argv[1]);
if (pw == NULL) {
exit(EXIT_SUCCESS);
}
- /* Retrieve group list */
+ /* Retrieve group list. */
if (getgrouplist(argv[1], pw\->pw_gid, groups, &ngroups) == \-1) {
fprintf(stderr, "getgrouplist() returned \-1; ngroups = %d\en",
exit(EXIT_FAILURE);
}
- /* Display list of retrieved groups, along with group names */
+ /* Display list of retrieved groups, along with group names. */
fprintf(stderr, "ngroups = %d\en", ngroups);
for (int j = 0; j < ngroups; j++) {
}
/* Walk through linked list, maintaining head pointer so we
- can free list later */
+ can free list later. */
for (struct ifaddrs *ifa = ifaddr; ifa != NULL;
ifa = ifa\->ifa_next) {
family = ifa\->ifa_addr\->sa_family;
/* Display interface name and family (including symbolic
- form of the latter for the common families) */
+ form of the latter for the common families). */
printf("%\-8s %s (%d)\en",
ifa\->ifa_name,
(family == AF_INET6) ? "AF_INET6" : "???",
family);
- /* For an AF_INET* interface address, display the address */
+ /* For an AF_INET* interface address, display the address. */
if (family == AF_INET || family == AF_INET6) {
s = getnameinfo(ifa\->ifa_addr,
erange_cnt++;
/* Increment a byte at a time so we can see exactly
- what size buffer was required */
+ what size buffer was required. */
buflen++;
erange_cnt++;
/* Increment a byte at a time so we can see exactly
- what size buffer was required */
+ what size buffer was required. */
buflen++;
int circular, opt, errfnd;
/* The "\-c" command\-line option can be used to specify that the
- list is circular */
+ list is circular. */
errfnd = 0;
circular = 0;
exit(EXIT_FAILURE);
}
- /* Create first element and place it in the linked list */
+ /* Create first element and place it in the linked list. */
elem = new_element();
first = elem;
insque(elem, NULL);
}
- /* Add remaining command\-line arguments as list elements */
+ /* Add remaining command\-line arguments as list elements. */
while (++optind < argc) {
prev = elem;
insque(elem, prev);
}
- /* Traverse the list from the start, printing element names */
+ /* Traverse the list from the start, printing element names. */
printf("Traversing completed list:\en");
elem = first;
char *p = NULL;
va_list ap;
- /* Determine required size */
+ /* Determine required size. */
va_start(ap, fmt);
n = vsnprintf(p, size, fmt, ap);
if (n < 0)
return NULL;
- /* One extra byte for \(aq\e0\(aq */
-
- size = (size_t) n + 1;
+ size = (size_t) n + 1; /* One extra byte for \(aq\e0\(aq */
p = malloc(size);
if (p == NULL)
return NULL;
/* pthread_getattr_np() is a non\-standard GNU extension that
retrieves the attributes of the thread specified in its
- first argument */
+ first argument. */
s = pthread_getattr_np(pthread_self(), &gattr);
if (s != 0)
/* If a command\-line argument was supplied, use it to set the
stack\-size attribute and set a few other thread attributes,
- and set attrp pointing to thread attributes object */
+ and set attrp pointing to thread attributes object. */
if (argc > 1) {
size_t stack_size;
int s;
/* Disable cancellation for a while, so that we don\(aqt
- immediately react to a cancellation request */
+ immediately react to a cancellation request. */
s = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (s != 0)
if (s != 0)
handle_error_en(s, "pthread_setcancelstate");
- /* sleep() is a cancellation point */
+ /* sleep() is a cancellation point. */
sleep(1000); /* Should get canceled while we sleep */
- /* Should never get here */
+ /* Should never get here. */
printf("thread_func(): not canceled!\en");
return NULL;
void *res;
int s;
- /* Start a thread and then send it a cancellation request */
+ /* Start a thread and then send it a cancellation request. */
s = pthread_create(&thr, NULL, &thread_func, NULL);
if (s != 0)
if (s != 0)
handle_error_en(s, "pthread_cancel");
- /* Join with thread to see what its exit status was */
+ /* Join with thread to see what its exit status was. */
s = pthread_join(thr, &res);
if (s != 0)
};
/* Thread start function: display address near top of our stack,
- and return upper\-cased copy of argv_string */
+ and return upper\-cased copy of argv_string. */
static void *
thread_start(void *arg)
size_t stack_size;
void *res;
- /* The "\-s" option specifies a stack size for our threads */
+ /* The "\-s" option specifies a stack size for our threads. */
stack_size = \-1;
while ((opt = getopt(argc, argv, "s:")) != \-1) {
num_threads = argc \- optind;
- /* Initialize thread creation attributes */
+ /* Initialize thread creation attributes. */
s = pthread_attr_init(&attr);
if (s != 0)
handle_error_en(s, "pthread_attr_setstacksize");
}
- /* Allocate memory for pthread_create() arguments */
+ /* Allocate memory for pthread_create() arguments. */
struct thread_info *tinfo = calloc(num_threads, sizeof(*tinfo));
if (tinfo == NULL)
handle_error("calloc");
- /* Create one thread for each command\-line argument */
+ /* Create one thread for each command\-line argument. */
for (int tnum = 0; tnum < num_threads; tnum++) {
tinfo[tnum].thread_num = tnum + 1;
tinfo[tnum].argv_string = argv[optind + tnum];
/* The pthread_create() call stores the thread ID into
- corresponding element of tinfo[] */
+ corresponding element of tinfo[]. */
s = pthread_create(&tinfo[tnum].thread_id, &attr,
&thread_start, &tinfo[tnum]);
}
/* Destroy the thread attributes object, since it is no
- longer needed */
+ longer needed. */
s = pthread_attr_destroy(&attr);
if (s != 0)
handle_error_en(s, "pthread_attr_destroy");
- /* Now join with each thread, and display its returned value */
+ /* Now join with each thread, and display its returned value. */
for (int tnum = 0; tnum < num_threads; tnum++) {
s = pthread_join(tinfo[tnum].thread_id, &res);
sleep(2);
- /* "original_owner_thread" should have exited by now */
+ /* "original_owner_thread" should have exited by now. */
printf("[main] Attempting to lock the robust mutex.\en");
s = pthread_mutex_lock(&mtx);
thread = pthread_self();
- /* Set affinity mask to include CPUs 0 to 7 */
+ /* Set affinity mask to include CPUs 0 to 7. */
CPU_ZERO(&cpuset);
for (int j = 0; j < 8; j++)
if (s != 0)
handle_error_en(s, "pthread_setaffinity_np");
- /* Check the actual affinity mask assigned to the thread */
+ /* Check the actual affinity mask assigned to the thread. */
s = pthread_getaffinity_np(thread, sizeof(cpuset), &cpuset);
if (s != 0)
{
/* The actual arguments to this function are "pointers to
pointers to char", but strcmp(3) arguments are "pointers
- to char", hence the following cast plus dereference */
+ to char", hence the following cast plus dereference. */
return strcmp(*(const char **) p1, *(const char **) p2);
}
if (sem_init(&sem, 0, 0) == \-1)
handle_error("sem_init");
- /* Establish SIGALRM handler; set alarm timer using argv[1] */
+ /* Establish SIGALRM handler; set alarm timer using argv[1]. */
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
alarm(atoi(argv[1]));
/* Calculate relative interval as current time plus
- number of seconds given argv[2] */
+ number of seconds given argv[2]. */
if (clock_gettime(CLOCK_REALTIME, &ts) == \-1)
handle_error("clock_gettime");
printf("main() about to call sem_timedwait()\en");
while ((s = sem_timedwait(&sem, &ts)) == \-1 && errno == EINTR)
- continue; /* Restart if interrupted by handler */
+ continue; /* Restart if interrupted by handler. */
- /* Check what happened */
+ /* Check what happened. */
if (s == \-1) {
if (errno == ETIMEDOUT)
char cwd[PATH_MAX];
/* Change our current working directory to that of the
- crashing process */
+ crashing process. */
snprintf(cwd, PATH_MAX, "/proc/%s/cwd", argv[1]);
chdir(cwd);
- /* Write output to file "core.info" in that directory */
+ /* Write output to file "core.info" in that directory. */
fp = fopen("core.info", "w+");
if (fp == NULL)
exit(EXIT_FAILURE);
/* Display command\-line arguments given to core_pattern
- pipe program */
+ pipe program. */
fprintf(fp, "argc=%d\en", argc);
for (int j = 0; j < argc; j++)
fprintf(fp, "argc[%d]=<%s>\en", j, argv[j]);
- /* Count bytes in standard input (the core dump) */
+ /* Count bytes in standard input (the core dump). */
tot = 0;
while ((nread = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)
void *memory, *name, *desc;
Elf64_Nhdr *note, *next_note;
-/* The buffer is pointing to the start of the section/segment */
+/* The buffer is pointing to the start of the section/segment. */
note = memory;
-/* If the name is defined, it follows the note */
+/* If the name is defined, it follows the note. */
name = note->n_namesz == 0 ? NULL : memory + sizeof(*note);
/* If the descriptor is defined, it follows the name
- (with alignment) */
+ (with alignment). */
desc = note->n_descsz == 0 ? NULL :
memory + sizeof(*note) + ALIGN_UP(note->n_namesz, 4);
-/* The next note follows both (with alignment) */
+/* The next note follows both (with alignment). */
next_note = memory + sizeof(*note) +
ALIGN_UP(note->n_namesz, 4) +
ALIGN_UP(note->n_descsz, 4);
numReqs = argc \- 1;
- /* Allocate our arrays */
+ /* Allocate our arrays. */
struct ioRequest *ioList = calloc(numReqs, sizeof(*ioList));
if (ioList == NULL)
if (aiocbList == NULL)
errExit("calloc");
- /* Establish handlers for SIGQUIT and the I/O completion signal */
+ /* Establish handlers for SIGQUIT and the I/O completion signal. */
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
errExit("sigaction");
/* Open each file specified on the command line, and queue
- a read request on the resulting file descriptor */
+ a read request on the resulting file descriptor. */
for (int j = 0; j < numReqs; j++) {
ioList[j].reqNum = j;
openReqs = numReqs;
- /* Loop, monitoring status of I/O requests */
+ /* Loop, monitoring status of I/O requests. */
while (openReqs > 0) {
sleep(3); /* Delay between each monitoring step */
/* On receipt of SIGQUIT, attempt to cancel each of the
outstanding I/O requests, and display status returned
- from the cancellation requests */
+ from the cancellation requests. */
printf("got SIGQUIT; canceling I/O requests: \en");
}
/* Check the status of each I/O request that is still
- in progress */
+ in progress. */
printf("aio_error():\en");
for (int j = 0; j < numReqs; j++) {
printf("All I/O requests completed\en");
- /* Check status return of all I/O requests */
+ /* Check status return of all I/O requests. */
printf("aio_return():\en");
for (int j = 0; j < numReqs; j++) {
int listen_sock, conn_sock, nfds, epollfd;
/* Code to set up listening socket, \(aqlisten_sock\(aq,
- (socket(), bind(), listen()) omitted */
+ (socket(), bind(), listen()) omitted. */
epollfd = epoll_create1(0);
if (epollfd == \-1) {
int *buffer;
/*
- *Allocate one page of memory
+ * Allocate one page of memory.
*/
buffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, \-1, 0);
errExit("mmap");
/*
- * Put some random data into the page (still OK to touch)
+ * Put some random data into the page (still OK to touch).
*/
*buffer = __LINE__;
printf("buffer contains: %d\en", *buffer);
/*
* Disable access to any memory with "pkey" set,
- * even though there is none right now
+ * even though there is none right now.
*/
status = pkey_set(pkey, PKEY_DISABLE_ACCESS, 0);
if (status)
printf("about to read buffer again...\en");
/*
- * This will crash, because we have disallowed access
+ * This will crash, because we have disallowed access.
*/
printf("buffer contains: %d\en", *buffer);
suseconds_t us;
intmax_t tmp;
- /* Scan the number from the string into the temporary variable */
+ /* Scan the number from the string into the temporary variable. */
sscanf(str, "%jd", &tmp);
- /* Check that the value is within the valid range of suseconds_t */
+ /* Check that the value is within the valid range of suseconds_t. */
if (tmp < \-1 || tmp > 1000000) {
fprintf(stderr, "Scanned value outside valid range!\en");
exit(EXIT_FAILURE);
}
- /* Copy the value to the suseconds_t variable \(aqus\(aq */
+ /* Copy the value to the suseconds_t variable \(aqus\(aq. */
us = tmp;
/* Even though suseconds_t can hold the value \-1, this isn\(aqt
- a sensible number of microseconds */
+ a sensible number of microseconds. */
if (us < 0) {
fprintf(stderr, "Scanned value shouldn\(aqt be negative!\en");
exit(EXIT_FAILURE);
}
- /* Print the value */
+ /* Print the value. */
printf("There are %jd microseconds in half a second.\en",
(intmax_t) us);
int result;
char buffer[BUFFER_SIZE];
- /* Create local socket */
+ /* Create local socket. */
connection_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (connection_socket == \-1) {
memset(&name, 0, sizeof(name));
- /* Bind socket to socket name */
+ /* Bind socket to socket name. */
name.sun_family = AF_UNIX;
strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path) \- 1);
exit(EXIT_FAILURE);
}
- /* This is the main loop for handling connections */
+ /* This is the main loop for handling connections. */
for (;;) {
- /* Wait for incoming connection */
+ /* Wait for incoming connection. */
data_socket = accept(connection_socket, NULL, NULL);
if (data_socket == \-1) {
result = 0;
for (;;) {
- /* Wait for next data packet */
+ /* Wait for next data packet. */
ret = read(data_socket, buffer, sizeof(buffer));
if (ret == \-1) {
exit(EXIT_FAILURE);
}
- /* Ensure buffer is 0\-terminated */
+ /* Ensure buffer is 0\-terminated. */
buffer[sizeof(buffer) \- 1] = 0;
- /* Handle commands */
+ /* Handle commands. */
if (!strncmp(buffer, "DOWN", sizeof(buffer))) {
down_flag = 1;
break;
}
- /* Add received summand */
+ /* Add received summand. */
result += atoi(buffer);
}
- /* Send result */
+ /* Send result. */
sprintf(buffer, "%d", result);
ret = write(data_socket, buffer, sizeof(buffer));
exit(EXIT_FAILURE);
}
- /* Close socket */
+ /* Close socket. */
close(data_socket);
- /* Quit on DOWN command */
+ /* Quit on DOWN command. */
if (down_flag) {
break;
close(connection_socket);
- /* Unlink the socket */
+ /* Unlink the socket. */
unlink(SOCKET_NAME);
int data_socket;
char buffer[BUFFER_SIZE];
- /* Create local socket */
+ /* Create local socket. */
data_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (data_socket == \-1) {
memset(&addr, 0, sizeof(addr));
- /* Connect socket to socket address */
+ /* Connect socket to socket address. */
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) \- 1);
exit(EXIT_FAILURE);
}
- /* Send arguments */
+ /* Send arguments. */
for (int i = 1; i < argc; ++i) {
ret = write(data_socket, argv[i], strlen(argv[i]) + 1);
}
}
- /* Request result */
+ /* Request result. */
strcpy(buffer, "END");
ret = write(data_socket, buffer, strlen(buffer) + 1);
exit(EXIT_FAILURE);
}
- /* Receive result */
+ /* Receive result. */
ret = read(data_socket, buffer, sizeof(buffer));
if (ret == \-1) {
exit(EXIT_FAILURE);
}
- /* Ensure buffer is 0\-terminated */
+ /* Ensure buffer is 0\-terminated. */
buffer[sizeof(buffer) \- 1] = 0;
printf("Result = %s\en", buffer);
- /* Close socket */
+ /* Close socket. */
close(data_socket);