int main(int argc, char *argv[]) { int j; struct sigaction sa; if (argc < 2 || strcmp(argv[1], "--help") == 0) usageErr("%s {s|p} ...\n", argv[0]); setbuf(stdout, NULL); /* Make stdout unbuffered */ sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = handler; if (sigaction(SIGHUP, &sa, NULL) == -1) errExit("sigaction"); if (sigaction(SIGCONT, &sa, NULL) == -1) errExit("sigaction"); printf("parent: PID=%ld, PPID=%ld, PGID=%ld, SID=%ld\n", (long) getpid(), (long) getppid(), (long) getpgrp(), (long) getsid(0)); /* Create one child for each command-line argument */ for (j = 1; j < argc; j++) { switch (fork()) { case -1: errExit("fork"); case 0: /* Child */ printf("child: PID=%ld, PPID=%ld, PGID=%ld, SID=%ld\n", (long) getpid(), (long) getppid(), (long) getpgrp(), (long) getsid(0)); if (argv[j][0] == 's') { /* Stop via signal */ printf("PID=%ld stopping\n", (long) getpid()); raise(SIGSTOP); } else { /* Wait for signal */ alarm(60); /* So we die if not SIGHUPed */ printf("PID=%ld pausing\n", (long) getpid()); pause(); } _exit(EXIT_SUCCESS); default: /* Parent carries on round loop */ break; } } /* Parent falls through to here after creating all children */ sleep(3); /* Give children a chance to start */ printf("parent exiting\n"); exit(EXIT_SUCCESS); /* And orphan them and their group */ }
int main(int argc, char *argv[]) { if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s pathname\n", argv[0]); execlp(argv[1], argv[1], "hello world", (char *) NULL); errExit("execlp"); /* If we get here, something went wrong */ }
int main(int argc, char *argv[]) { if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s shm-name\n", argv[0]); if (shm_unlink(argv[1]) == -1) errExit("shm_unlink"); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s filename\n", argv[0]); execlp(argv[1], argv[1], "Hell world", (char *)NULL); errExit("execlp"); }
int main(int argc, char *argv[]) { char *addr; int fd, j; setbuf(stdout, NULL); if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s file\n", argv[0]); unlink(argv[1]); fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) errExit("open"); for (j = 0; j < MAP_SIZE; j++) write(fd, "a", 1); if (fsync(fd) == -1) errExit("fsync"); close(fd); fd = open(argv[1], O_RDWR); if (fd == -1) errExit("open"); addr = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) errExit("mmap"); printf("After mmap: "); write(STDOUT_FILENO, addr, WRITE_SIZE); printf("\n"); /* Copy-on-write semantics mean that the following modification will create private copies of the pages for this process */ for (j = 0; j < MAP_SIZE; j++) addr[j]++; printf("After modification: "); write(STDOUT_FILENO, addr, WRITE_SIZE); printf("\n"); /* After the following, the mapping contents revert to the original file contents (if MADV_DONTNEED has destructive semantics, as on Linux) */ if (madvise(addr, MAP_SIZE, MADV_DONTNEED) == -1) errExit("madvise"); printf("After MADV_DONTNEED: "); write(STDOUT_FILENO, addr, WRITE_SIZE); printf("\n"); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct sigevent sev; mqd_t mqd; struct mq_attr attr; void *buffer; ssize_t numRead; sigset_t blockMask, emptyMask; struct sigaction sa; if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s mq-name\n", argv[0]); mqd = mq_open(argv[1], O_RDONLY | O_NONBLOCK); if (mqd == (mqd_t) -1) errExit("mq_open"); if (mq_getattr(mqd, &attr) == -1) errExit("mq_getattr"); buffer = malloc(attr.mq_msgsize); if (buffer == NULL) errExit("malloc"); sigemptyset(&blockMask); sigaddset(&blockMask, NOTIFY_SIG); if (sigprocmask(SIG_BLOCK, &blockMask, NULL) == -1) errExit("sigprocmask"); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = handler; if (sigaction(NOTIFY_SIG, &sa, NULL) == -1) errExit("sigaction"); sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = NOTIFY_SIG; if (mq_notify(mqd, &sev) == -1) errExit("mq_notify"); sigemptyset(&emptyMask); for (;;) { sigsuspend(&emptyMask); /* Wait for notification signal */ if (mq_notify(mqd, &sev) == -1) errExit("mq_notify"); while ((numRead = mq_receive(mqd, buffer, attr.mq_msgsize, NULL)) >= 0) printf("Read %ld bytes\n", (long) numRead); if (errno != EAGAIN) /* Unexpected error */ errExit("mq_receive"); } }
int main(int argc, char *argv[]) { int fd, fd1; struct iovec iov[3]; struct stat myStruct; /* First buffer */ int x; /* Second buffer */ #define STR_SIZE 100 char str[STR_SIZE]; /* Third buffer */ ssize_t numRead, totRequired, numWrite; if (argc != 3 || strcmp(argv[1], "--help") == 0) usageErr("%s readFile writeFile\n", argv[0]); fd = open(argv[1], O_RDONLY); if (fd == -1) errExit("open"); totRequired = 0; iov[0].iov_base = &myStruct; iov[0].iov_len = sizeof(struct stat); totRequired += iov[0].iov_len; iov[1].iov_base = &x; iov[1].iov_len = sizeof(x); totRequired += iov[1].iov_len; iov[2].iov_base = str; iov[2].iov_len = STR_SIZE; totRequired += iov[2].iov_len; numRead = my_readv(fd, iov, 3); if (numRead == -1) errExit("readv"); if (numRead < totRequired) printf("Read fewer bytes than requested\n"); printf("total bytes requested: %ld; bytes read: %ld\n", (long) totRequired, (long) numRead); fd1 = creat(argv[2], S_IRUSR | S_IWUSR); if (fd1 == -1) errExit("open"); numWrite = my_writev(fd1, iov, 3); if (numWrite == -1) errExit("writev"); printf("total bytes requested: %ld; bytes write: %ld\n", (long) totRequired, (long) numWrite); exit(EXIT_SUCCESS); }
int main (int argc, char * argv[]) { int j, sigCnt; sigset_t blockMask, emptyMask; struct sigaction sa; if(argc < 2 || strcmp(argv[1], "--help") == 0) usageErr("%s child-sleep-time...\n", argv[0]); setbuf(stdout, NULL); sigCnt = 0; numLiveChildren = argc - 1; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = sigchldHandler; if (sigaction(SIGCHLD, &sa, NULL) == -1) errExit("sigaction"); /* Block SIGCHLD to prevent its delivery if a child terminates before the parents commences the sigsuspend() loop below */ sigemptyset(&blockMask); sigaddset(&blockMask, SIGCHLD); if (sigprocmask(SIG_SETMASK, &blockMask, NULL) == -1) errExit("sigprocmask"); for(j = 1; j < argc; j++) { switch(fork()) { case -1: errExit("fork"); case 0: /* Child - sleeps and then exits */ sleep(getInt(argv[j], GN_NONNEG, "child-sleep-time")); printf("%s Child %d (PID=%ld) exiting\n", currTime("%T"), j, (long) getpid()); _exit(EXIT_SUCCESS); default: /* Parent - loops to create next child */ break; } } /* Parent comes here: wait for SIGCHLD until all children are dead */ sigemptyset(&emptyMask); while (numLiveChildren > 0) { if (sigsuspend(&emptyMask) == -1 && errno != EINTR) errExit("sigsuspend"); sigCnt++; } printf("%s All %d children have terminated; SIGCHLD was caught %d times\n", currTime("%T"), argc - 1, sigCnt); exit(EXIT_SUCCESS); }
int main(int argc,char *argv[]) { char *ptr[MAX_ALLOCS]; int freeStep,freeMin,freeMax,blockSize,numAllocs,j; printf("\n"); if (argc < 3 || strcmp(argv[1],"--help") == 0) { usageErr("%s num-allocs block-size [step [min [max]]]\n",argv[0]); } numAllocs = getInt(argv[1],GN_GT_0,"num-allocs"); if (numAllocs > MAX_ALLOCS) { cmdLineErr("num-allocs > %d\n",MAX_ALLOCS); } blockSize = getInt(argv[2],GN_GT_0 | GN_ANY_BASE,"block-size"); freeStep = (argc > 3) ? getInt(argv[3],GN_GT_0,"step") : 1; freeMin = (argc > 4) ? getInt(argv[4],GN_GT_0,"min") : 1; freeMax = (argc > 5) ? getInt(argv[5],GN_GT_0,"max") : numAllocs; if (freeMax > numAllocs) { cmdLineErr("free-max > num-allocs\n"); } printf("Initial program break: %10p\n",sbrk(0)); printf("Allocating %d*%d bytes\n",numAllocs,blockSize); for (j = 0; j < numAllocs; j++) { ptr[j] = malloc(blockSize); if (ptr[j] == NULL) { errExit("malloc"); } printf("Malloc[%d] program break: %10p\n ",j,sbrk(0)); } printf("Program break is now: %10p\n",sbrk(0)); printf("Freeing blocks from %d to %d in steps of %d\n",freeMin,freeMax,freeStep); for (j = freeMin - 1; j < freeMax; j += freeStep) { free(ptr[j]); } printf("After free(),program break is: %10p\n",sbrk(0)); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { if (argc != 3 || strcmp(argv[1], "--help") == 0) usageErr("%s file length\n", argv[0]); if (truncate(argv[1], getLong(argv[2], GN_ANY_BASE, "length")) == -1) errExit("truncate"); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int j, pol; struct sched_param sp; if (argc < 3 || strchr("rfo" #ifdef SCHED_BATCH /* Linux-specific */ "b" #endif #ifdef SCHED_IDLE /* Linux-specific */ "i" #endif , argv[1][0]) == NULL) usageErr("%s policy priority [pid...]\n" " policy is 'r' (RR), 'f' (FIFO), " #ifdef SCHED_BATCH /* Linux-specific */ "'b' (BATCH), " #endif #ifdef SCHED_IDLE /* Linux-specific */ "'i' (IDLE), " #endif "or 'o' (OTHER)\n", argv[0]); pol = (argv[1][0] == 'r') ? SCHED_RR : (argv[1][0] == 'f') ? SCHED_FIFO : #ifdef SCHED_BATCH /* Linux-specific, since kernel 2.6.16 */ (argv[1][0] == 'b') ? SCHED_BATCH : #endif #ifdef SCHED_IDLE /* Linux-specific, since kernel 2.6.23 */ (argv[1][0] == 'i') ? SCHED_IDLE : #endif SCHED_OTHER; sp.sched_priority = getInt(argv[2], 0, "priority"); /* Only raise CAP_DAC_READ_SEARCH for as long as we need it */ if (raiseCap(CAP_SYS_NICE)) errExit("raiseCap() failed"); for (j = 3; j < argc; j++) if (sched_setscheduler(getLong(argv[j], 0, "pid"), pol, &sp) == -1) errExit("sched_setscheduler"); /* At this point, we won't need any more capabilities, so drop all capabilities from all sets */ if (dropAllCaps() == -1) fatal("dropAllCaps() failed"); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s mount-point\n", argv[0]); if (umount(argv[1]) == -1) errExit("umount"); exit(EXIT_SUCCESS); }
int main(int argc,char *argv[]) { int inputFd,outputFd,openFlags; mode_t filePerms; ssize_t numRead; char buf[BUF_SIZE]; if (argc != 3 || strcmp(argv[1],"--help") == 0) { usageErr("%s old-file new-file\n",argv[0]); } /* Open input and output files */ inputFd = open(argv[1],O_RDONLY); if (inputFd == -1) { errExit("opening file %s",argv[1]); } openFlags = O_CREAT | O_WRONLY | O_TRUNC ; filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; outputFd = open(argv[2],openFlags,filePerms); if (outputFd == -1) { errExit("opening file %s",argv[2]); } /* Transfer data until we encounter end of input or an error */ while ((numRead = read(inputFd,buf,BUF_SIZE)) > 0) { if (write(outputFd,buf,numRead) != numRead) { fatal("couldn't write whole buffer'"); } } if (numRead == -1) { errExit("read"); } if (close(inputFd) == -1) { errExit("close input"); } if (close(outputFd) == -1) { errExit("close output"); } exit(EXIT_SUCCESS); }
int main (int argc, char *argv[]) { if (argc < 2) { usageErr("%s file\n", argv[0]); } for (int i = 1; i < argc; i++) { chmod_a_plus_rX(argv[i]); } exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct itimerspec ts; struct timespec start, now; int maxExp, fd, secs, nanosecs; uint64_t numExp, totalExp; ssize_t s; if (argc < 2 || strcmp(argv[1], "--help") == 0) usageErr("%s secs[/nsecs][:int-secs[/int-nsecs]] [max-exp]\n", argv[0]); itimerspecFromStr(argv[1], &ts); maxExp = (argc > 2) ? getInt(argv[2], GN_GT_0, "max-exp") : 1; fd = timerfd_create(CLOCK_REALTIME, 0); if (fd == -1) errExit("timerfd_create"); if (timerfd_settime(fd, 0, &ts, NULL) == -1) errExit("timerfd_settime"); if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) errExit("clock_gettime"); for (totalExp = 0; totalExp < maxExp;) { /* Read number of expirations on the timer, and then display time elapsed since timer was started, followed by number of expirations read and total expirations so far. */ s = read(fd, &numExp, sizeof(uint64_t)); if (s != sizeof(uint64_t)) errExit("read"); totalExp += numExp; if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) errExit("clock_gettime"); secs = now.tv_sec - start.tv_sec; nanosecs = now.tv_nsec - start.tv_nsec; if (nanosecs < 0) { secs--; nanosecs += 1000000000; } printf("%d.%03d: expirations read: %llu; total=%llu\n", secs, (nanosecs + 500000) / 1000000, (unsigned long long) numExp, (unsigned long long) totalExp); } exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int fd, j, numBlocks; char shellCmd[CMD_SIZE]; /* Command to be passed to system() */ char buf[BUF_SIZE]; /* Random bytes to write to file */ if (argc < 2 || strcmp(argv[1], "--help") == 0) usageErr("%s temp-file [num-1kB-blocks] \n", argv[0]); numBlocks = (argc > 2) ? getInt(argv[2], GN_GT_0, "num-1kB-blocks") : 100000; /* O_EXCL so that we ensure we create a new file */ fd = open(argv[1], O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1) errExit("open"); printf("open file ok and wait for 10s to unlink\n"); sleep(10); if (unlink(argv[1]) == -1) /* Remove filename */ errExit("unlink"); printf("unlink and sleep 30s...\n"); sleep(30); for (j = 0; j < numBlocks; j++) /* Write lots of junk to file */ if (write(fd, buf, BUF_SIZE) != BUF_SIZE) fatal("partial/failed write"); snprintf(shellCmd, CMD_SIZE, "df -k `dirname %s`", argv[1]); system(shellCmd); /* View space used in file system */ if (close(fd) == -1) /* File is now destroyed */ errExit("close"); printf("********** Closed file descriptor\n"); /* See the erratum for page 348 at http://man7.org/tlpi/errata/. Depending on factors such as random scheduler decisions and the size of the file created, the 'df' command executed by the second system() call below does may not show a change in the amount of disk space consumed, because the blocks of the closed file have not yet been freed by the kernel. If this is the case, then inserting a sleep(1) call here should be sufficient to ensure that the the file blocks have been freed by the time of the second 'df' command. */ system(shellCmd); /* Review space used in file system */ exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int s, numThreads; long threadNum; pthread_t *tid; if (argc != 3 || strcmp(argv[1], "--help") == 0) usageErr("%s num-barriers num-threads\n", argv[0]); numBarriers = atoi(argv[1]); numThreads = atoi(argv[2]); /* Allocate array to hold thread IDs */ tid = calloc(sizeof(pthread_t), numThreads); if (tid == NULL) errExit("calloc"); /* Initialize the barrier. The final argument specifies the number of threads that must call pthread_barrier_wait() before any thread will unblock from that call. */ s = pthread_barrier_init(&barrier, NULL, numThreads); if (s != 0) errExitEN(s, "pthread_barrier_init"); /* Create 'numThreads' threads */ for (threadNum = 0; threadNum < numThreads; threadNum++) { s = pthread_create(&tid[threadNum], NULL, threadFunc, (void *) threadNum); if (s != 0) errExitEN(s, "pthread_create"); } /* Each thread prints a start-up message. We briefly delay, and then print a newline character so that an empty line appears after the start-up messages. */ usleep(100000); printf("\n"); /* Wait for all of the threads to terminate */ for (threadNum = 0; threadNum < numThreads; threadNum++) { s = pthread_join(tid[threadNum], NULL); if (s != 0) errExitEN(s, "pthread_join"); } exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int numSigs, scnt; pid_t childPid; sigset_t blockedMask; #ifdef _USE_SIGINFO siginfo_t si; #endif if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s num-sigs\n", argv[0]); numSigs = getInt(argv[1], GN_GT_0, "num-sigs"); /* Block the signal before fork(), so that the child doesn't manage to send it to the parent before the parent is ready to catch it */ sigemptyset(&blockedMask); sigaddset(&blockedMask, TESTSIG); if (sigprocmask(SIG_SETMASK, &blockedMask, NULL) == -1) errExit("sigprocmask"); switch (childPid = fork()) { case -1: errExit("fork"); case 0: /* child */ for (scnt = 0; scnt < numSigs; scnt++) { if (kill(getppid(), TESTSIG) == -1) errExit("kill"); #ifdef _USE_SIGINFO if(sigwaitinfo(&blockedMask, &si) == -1) #else if(sigwaitinfo(&blockedMask, NULL) == -1) #endif errExit("sigwaitinfo"); } exit(EXIT_SUCCESS); default: /* parent */ for (scnt = 0; scnt < numSigs; scnt++) { #ifdef _USE_SIGINFO if(sigwaitinfo(&blockedMask, &si) == -1) #else if(sigwaitinfo(&blockedMask, NULL) == -1) #endif errExit("sigwaitinfo"); if (kill(childPid, TESTSIG) == -1) errExit("kill"); } exit(EXIT_SUCCESS); } }
int main(int argc, char *argv[]) { struct sigaction sa; int sig; sigset_t prevMask, blockMask; if (argc > 1 && strcmp(argv[1], "--help") == 0) usageErr("%s [block-time [handler-sleep-time]]\n", argv[0]); printf("%s: PID is %ld\n", argv[0], (long) getpid()); handlerSleepTime = (argc > 2) ? getInt(argv[2], GN_NONNEG, "handler-sleep-time") : 1; /* Establish handler for most signals. During execution of the handler, mask all other signals to prevent handlers recursively interrupting each other (which would make the output hard to read). */ sa.sa_sigaction = siginfoHandler; sa.sa_flags = SA_SIGINFO; sigfillset(&sa.sa_mask); for (sig = 1; sig < NSIG; sig++) if (sig != SIGTSTP && sig != SIGQUIT) sigaction(sig, &sa, NULL); /* Optionally block signals and sleep, allowing signals to be sent to us before they are unblocked and handled */ if (argc > 1) { sigfillset(&blockMask); sigdelset(&blockMask, SIGINT); sigdelset(&blockMask, SIGTERM); if (sigprocmask(SIG_SETMASK, &blockMask, &prevMask) == -1) errExit("sigprocmask"); printf("%s: signals blocked - sleeping %s seconds\n", argv[0], argv[1]); sleep(getInt(argv[1], GN_GT_0, "block-time")); printf("%s: sleep complete\n", argv[0]); if (sigprocmask(SIG_SETMASK, &prevMask, NULL) == -1) errExit("sigprocmask"); } while (!allDone) /* Wait for incoming signals */ pause(); printf("Caught %d signals\n", sigCnt); exit(EXIT_SUCCESS); }
int main(int argc,char *argv[]) { int j,sigCnt; sigset_t blockMask,emptyMask; struct sigaction sa; if(argc<2 || strcmp(argv[1],"--help")==0) usageErr("%s child-sleep-time...",argv[0]); setbuf(stdout,NULL); sigCnt=0; numLiveChildren=argc-1; sigemptyset(&sa.sa_mask); sa.sa_flags=0; sa.sa_handler=sigchldHandler; if(sigaction(SIGCHLD,&sa,NULL)==-1) errExit("sigaction"); sigemptyset(&blockMask); sigaddset(&blockMask,SIGCHLD); if(sigprocmask(SIG_SETMASK,&blockMask,NULL)==-1) errExit("sigprocmask"); for(j=1;j<argc;j++){ switch(fork()){ case -1: errExit("fork"); case 0: sleep(getInt(argv[j],GN_NONNEG,"child-sleep time")); printf("%s Child=%d (PID=%ld) exiting\n",currTime("%T"), j,(long)getpid()); _exit(EXIT_SUCCESS); default: break; } } sigemptyset(&emptyMask); while(numLiveChildren>0){ if(sigsuspend(&emptyMask) == -1 && errno != EINTR) errExit("sigsuspend"); sigCnt++; } printf("%s All %d chilldren have been terminated; SIGCHLD was caught %d times\n",currTime("%T"),argc-1,sigCnt); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int listenFd, acceptFd, connFd; socklen_t len; /* Size of socket address buffer */ void *addr; /* Buffer for socket address */ char addrStr[IS_ADDR_STR_LEN]; if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s service\n", argv[0]); /* Create listening socket, obtain size of address structure */ listenFd = inetListen(argv[1], 5, &len); if (listenFd == -1) errExit("inetListen"); connFd = inetConnect(NULL, argv[1], SOCK_STREAM); if (connFd == -1) errExit("inetConnect"); acceptFd = accept(listenFd, NULL, NULL); if (acceptFd == -1) errExit("accept"); addr = malloc(len); if (addr == NULL) errExit("malloc"); if (getsockname(connFd, addr, &len) == -1) errExit("getsockname"); printf("getsockname(connFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); if (getsockname(acceptFd, addr, &len) == -1) errExit("getsockname"); printf("getsockname(acceptFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); if (getpeername(connFd, addr, &len) == -1) errExit("getpeername"); printf("getpeername(connFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); if (getpeername(acceptFd, addr, &len) == -1) errExit("getpeername"); printf("getpeername(acceptFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); sleep(30); /* Give us time to run netstat(8) */ exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { if (argc > 2 || (argc > 1 && strcmp(argv[1], "--help") == 0)) usageErr("%s [file]\n", argv[0]); if (acct(argv[1]) == -1) errExit("acct"); printf("Process accounting %s\n", (argv[1] == NULL) ? "disabled" : "enabled"); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { uid_t ruid, euid, suid; int policy; pid_t pid; struct sched_param sp; if (argc < 4 || (argc >= 2 && strcmp("--help", argv[1]) == 0)) usageErr("%s policy priority command arg ...\n", argv[0]); if (strcmp(argv[1], "r") == 0) policy = SCHED_RR; else if (strcmp(argv[1], "f") == 0) policy = SCHED_FIFO; else usageErr("%s r|f priority command arg ...", argv[0]); sp.sched_priority = getInt(argv[2], 0, "priority"); if (getresuid(&ruid, &euid, &suid) == -1) errExit("getresuid error"); switch (pid = fork()) { case -1: errExit("fork error"); case 0: if (euid == 0 && (ruid != 0 || suid != 0)) { if (setresuid(ruid, ruid, ruid) == -1) errExit("setresuid error"); } execvp(argv[3], &argv[3]); errExit("execvp error"); default: if (sched_setscheduler(pid, policy, &sp) == -1) errExit("sched_setscheduler error"); if (waitpid(pid, 0, NULL) == -1) errExit("sched_setscheduler error"); } exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { char *val; if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s environ-var\n", argv[0]); val = getenv(argv[1]); printf("%s\n", (val != NULL) ? val : "No such variable"); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct sockaddr_un svaddr, claddr; int sfd, j; size_t msgLen; ssize_t numBytes; char resp[BUF_SIZE]; if (argc < 2 || strcmp(argv[1], "--help") == 0) usageErr("%s msg...\n", argv[0]); /* Create client socket; bind to unique pathname (based on PID) */ sfd = socket(AF_UNIX, SOCK_DGRAM, 0); if (sfd == -1) errExit("socket"); memset(&claddr, 0, sizeof(struct sockaddr_un)); claddr.sun_family = AF_UNIX; snprintf(claddr.sun_path, sizeof(claddr.sun_path), "/tmp/ud_ucase_cl.%ld", (long) getpid()); if (bind(sfd, (struct sockaddr *) &claddr, sizeof(struct sockaddr_un)) == -1) errExit("bind"); /* Construct address of server */ memset(&svaddr, 0, sizeof(struct sockaddr_un)); svaddr.sun_family = AF_UNIX; strncpy(svaddr.sun_path, SV_SOCK_PATH, sizeof(svaddr.sun_path) - 1); /* Send messages to server; echo responses on stdout */ for (j = 1; j < argc; j++) { msgLen = strlen(argv[j]); /* May be longer than BUF_SIZE */ if (sendto(sfd, argv[j], msgLen, 0, (struct sockaddr *) &svaddr, sizeof(struct sockaddr_un)) != msgLen) fatal("sendto"); numBytes = recvfrom(sfd, resp, BUF_SIZE, 0, NULL, NULL); /* Or equivalently: numBytes = recv(sfd, resp, BUF_SIZE, 0); or: numBytes = read(sfd, resp, BUF_SIZE); */ if (numBytes == -1) errExit("recvfrom"); printf("Response %d: %.*s\n", j, (int) numBytes, resp); } remove(claddr.sun_path); /* Remove client socket pathname */ exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int numSigs, scnt; pid_t childPid; sigset_t blockedMask, emptyMask; struct sigaction sa; if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s num-sigs\n", argv[0]); numSigs = getInt(argv[1], GN_GT_0, "num-sigs"); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = handler; if (sigaction(TESTSIG, &sa, NULL) == -1) errExit("sigaction"); /* Block the signal before fork(), so that the child doesn't manage to send it to the parent before the parent is ready to catch it */ sigemptyset(&blockedMask); sigaddset(&blockedMask, TESTSIG); if (sigprocmask(SIG_SETMASK, &blockedMask, NULL) == -1) errExit("sigprocmask"); sigemptyset(&emptyMask); switch (childPid = fork()) { case -1: errExit("fork"); case 0: /* child */ for (scnt = 0; scnt < numSigs; scnt++) { if (kill(getppid(), TESTSIG) == -1) errExit("kill"); if (sigsuspend(&emptyMask) == -1 && errno != EINTR) errExit("sigsuspend"); } exit(EXIT_SUCCESS); default: /* parent */ for (scnt = 0; scnt < numSigs; scnt++) { if (sigsuspend(&emptyMask) == -1 && errno != EINTR) errExit("sigsuspend"); if (kill(childPid, TESTSIG) == -1) errExit("kill"); } exit(EXIT_SUCCESS); } }
int main(int argc, char *argv[]) { struct sigevent sev; struct itimerspec ts; timer_t *tidlist; int s, j; if (argc < 2) usageErr("%s secs[/nsecs][:int-secs[/int-nsecs]]...\n", argv[0]); tidlist = calloc(argc - 1, sizeof(timer_t)); if (tidlist == NULL) errExit("malloc"); sev.sigev_notify = SIGEV_THREAD; /* Notify via thread */ sev.sigev_notify_function = threadFunc; /* Thread start function */ sev.sigev_notify_attributes = NULL; /* Could be pointer to pthread_attr_t structure */ /* Create and start one timer for each command-line argument */ for (j = 0; j < argc - 1; j++) { itimerspecFromStr(argv[j + 1], &ts); sev.sigev_value.sival_ptr = &tidlist[j]; /* Passed as argument to threadFunc() */ if (timer_create(CLOCK_REALTIME, &sev, &tidlist[j]) == -1) errExit("timer_create"); printf("Timer ID: %ld (%s)\n", (long) tidlist[j], argv[j + 1]); if (timer_settime(tidlist[j], 0, &ts, NULL) == -1) errExit("timer_settime"); } /* The main thread waits on a condition variable that is signaled on each invocation of the thread notification function. We print a message so that the user can see that this occurred. */ s = pthread_mutex_lock(&mtx); if (s != 0) errExitEN(s, "pthread_mutex_lock"); for (;;) { s = pthread_cond_wait(&cond, &mtx); if (s != 0) errExitEN(s, "pthread_cond_wait"); printf("main(): expireCnt = %d\n", expireCnt); } }
int main(int argc, char *argv[]) { int j; if (argc > 1 && strcmp(argv[1], "--help") == 0) usageErr("%s [shmid...]\n", argv[0]); for (j = 1; j < argc; j++) if (shmctl(getInt(argv[j], 0, "shmid"), IPC_RMID, NULL) == -1) errExit("shmctl %s", argv[j]); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { if (argc > 1 && strcmp(argv[1], "--help") == 0) usageErr("%s [dir-path...]\n", argv[0]); if (argc == 1) /* No arguments - use current directory */ listFiles("."); else for (argv++; *argv; argv++) listFiles(*argv); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { void *libHandle; /* Handle for shared library */ void (*funcp)(void); /* Pointer to function with no arguments */ const char *err; if (argc != 3 || strcmp(argv[1], "--help") == 0) usageErr("%s lib-path func-name\n", argv[0]); /* Load the shared library and get a handle for later use */ libHandle = dlopen(argv[1], RTLD_LAZY); if (libHandle == NULL) fatal("dlopen: %s", dlerror()); /* Search library for symbol named in argv[2] */ (void) dlerror(); /* Clear dlerror() */ *(void **) (&funcp) = dlsym(libHandle, argv[2]); /* The rather clumsy cast above is necessary because the ISO C standard does not require that pointers to functions can be cast back and forth to 'void *'. (See TLPI pages 863-864.) SUSv3 TC1 and SUSv4 accept the ISO C requirement and propose casts of the above form as the workaround. However, the 2013 Technical Corrigendum (TC1) to SUSv4 requires casts of the following more natural form to work correctly: funcp = (void (*)()) dlsym(libHandle, argv[2]); Various current compilers (e.g., gcc with the '-pedantic' flag) may still complain about such casts, however. */ err = dlerror(); if (err != NULL) fatal("dlsym: %s", err); /* If the address returned by dlsym() is non-NULL, try calling it as a function that takes no arguments */ if (funcp == NULL) printf("%s is NULL\n", argv[2]); else (*funcp)(); dlclose(libHandle); /* Close the library */ exit(EXIT_SUCCESS); }