Skip to content

Instantly share code, notes, and snippets.

@lifning
Last active August 29, 2015 13:56
Show Gist options
  • Save lifning/9265460 to your computer and use it in GitHub Desktop.
Save lifning/9265460 to your computer and use it in GitHub Desktop.
Messing with nuances of stdin/stdout timing in C
#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
int set_lock(short type) {
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = type;
return fcntl(STDIN_FILENO, F_SETLK, &fl);
}
int lock() {
if (set_lock(F_RDLCK) == -1) {
perror("receiver fcntl: couldn't read-lock stdin\n");
return -1;
}
return 0;
}
int unlock() {
if (set_lock(F_UNLCK) == -1) {
perror("receiver fcntl: couldn't unlock stdin\n");
return -1;
}
return 0;
}
int main() {
int bytes_read;
int pipe_capacity = fcntl(STDIN_FILENO, F_GETPIPE_SZ);
char *buffer;
fprintf(stderr, "receiving pipe size: %d\n", pipe_capacity);
buffer = malloc(pipe_capacity);
setvbuf(stdin, NULL, _IONBF, 0);
if (lock() == -1) {
return 1;
}
while ((bytes_read = read(STDIN_FILENO, buffer, 11)) > 0) {
if (unlock() == -1) {
break;
}
fprintf(stderr, "received %dB at %d: ", bytes_read, (int) time(NULL));
fputs(buffer, stderr);
if (lock() == -1) {
break;
}
sleep(1);
}
free(buffer);
return 0;
}
CFLAGS = -Wall -pedantic
all: print-time delayed-receiver
./print-time | ./delayed-receiver
clean:
$(RM) print-time delayed-receiver *.o
print-time: print-time.o
delayed-receiver: delayed-receiver.o
#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
short get_lock(short type) {
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = type;
if (fcntl(STDOUT_FILENO, F_GETLK, &fl) == -1) {
perror("print fcntl: couldn't check existing locks on stdout\n");
return -1;
}
return fl.l_type;
}
int main() {
int reps = 0;
int pipe_capacity = fcntl(STDOUT_FILENO, F_SETPIPE_SZ, 16);
char *buffer;
fprintf(stderr, "tried to set pipe size to 16B, got %d\n", pipe_capacity);
buffer = malloc(pipe_capacity);
setvbuf(stdout, NULL, _IONBF, 0);
while (reps++ < 10) {
int count;
while (get_lock(F_WRLCK) == F_UNLCK) {
/* wait */
}
count = snprintf(buffer, pipe_capacity, "%d\n", (int) time(NULL));
write(STDOUT_FILENO, buffer, count);
while (get_lock(F_WRLCK) != F_UNLCK) {
/* wait */
}
}
free(buffer);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment