I wrote a small program to make an orphan group processes.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
static void sig_hup(int);
static void pr_ids(char *);
int main(){
char c;
pid_t pid;
pr_ids("parent");
if ((pid = fork()) < 0)
fprintf(stderr, "fork error/n");
else if (pid > 0){
sleep(5);
exit(0);
}
else{
pr_ids("child");
signal(SIGHUP, sig_hup);
kill(getpid(), SIGTSTP);
pr_ids("child");
if (read(0, &c, 1) != 1)
printf("read error from control terminal, errno = %d/n", errno);
exit(0);
}
return 0;
}
static void sig_hup(int signo){
printf("SIGHUP received, pid = %d/n", getpid());
return;
}
static void pr_ids(char *name){
printf("%s, pid = %d, ppid = %d, pgrp = %d/n",
name, getpid(), getppid(), getpgrp());
fflush(stdout);
}
result:
parent, pid = 1616, ppid = 1581, pgrp = 1616
child, pid = 1617, ppid = 1616, pgrp = 1616
SIGHUP received, pid = 1617
child, pid = 1617, ppid = 1, pgrp = 1616
int setuid(uid _t uid);
If you are the "root", then can change real user id, effectiv user id, and saved set user id for uid. If you are a normal
user, you only change effective user id for uid.
During the "exec" is running, it saved the saved set user id from the effective user id, then it check wether saved set user
id bit is opened; opened, set the effective user id by the user id from a program file.
There is a fast copy program's source.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
int main(int argc, char *argv[]){
int fdin, fdout;
char *src, *dst;
struct stat statbuf;
if (argc != 3)
fprintf(stderr, "usage: %s <fromfile> <tofile>/n", argv[0]);
if ((fdin = open(argv[1], O_RDONLY)) < 0)
fprintf(stderr, "can't open %s for reading/n", argv[1]);
if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC)) < 0)
fprintf(stderr, "can't create %s for writing/n", argv[2]);
if (fstat(fdin, &statbuf) < 0)
fprintf(stderr, "fstat() error/n");
if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1)
fprintf(stderr, "lseek() error/n");
if (write(fdout, "", 1) != 1)
fprintf(stderr, "write() error/n");
if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_FILE | MAP_SHARED,
fdin, 0)) == (caddr_t) -1)
fprintf(stderr, "mmap() error/n");
if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, fdout, 0)) == (caddr_t) -1)
fprintf(stderr, "mmap() error/n");
memcpy(dst, src, statbuf.st_size);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
static void sig_hup(int);
static void pr_ids(char *);
int main(){
char c;
pid_t pid;
pr_ids("parent");
if ((pid = fork()) < 0)
fprintf(stderr, "fork error/n");
else if (pid > 0){
sleep(5);
exit(0);
}
else{
pr_ids("child");
signal(SIGHUP, sig_hup);
kill(getpid(), SIGTSTP);
pr_ids("child");
if (read(0, &c, 1) != 1)
printf("read error from control terminal, errno = %d/n", errno);
exit(0);
}
return 0;
}
static void sig_hup(int signo){
printf("SIGHUP received, pid = %d/n", getpid());
return;
}
static void pr_ids(char *name){
printf("%s, pid = %d, ppid = %d, pgrp = %d/n",
name, getpid(), getppid(), getpgrp());
fflush(stdout);
}
result:
parent, pid = 1616, ppid = 1581, pgrp = 1616
child, pid = 1617, ppid = 1616, pgrp = 1616
SIGHUP received, pid = 1617
child, pid = 1617, ppid = 1, pgrp = 1616
int setuid(uid _t uid);
If you are the "root", then can change real user id, effectiv user id, and saved set user id for uid. If you are a normal
user, you only change effective user id for uid.
During the "exec" is running, it saved the saved set user id from the effective user id, then it check wether saved set user
id bit is opened; opened, set the effective user id by the user id from a program file.
There is a fast copy program's source.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
int main(int argc, char *argv[]){
int fdin, fdout;
char *src, *dst;
struct stat statbuf;
if (argc != 3)
fprintf(stderr, "usage: %s <fromfile> <tofile>/n", argv[0]);
if ((fdin = open(argv[1], O_RDONLY)) < 0)
fprintf(stderr, "can't open %s for reading/n", argv[1]);
if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC)) < 0)
fprintf(stderr, "can't create %s for writing/n", argv[2]);
if (fstat(fdin, &statbuf) < 0)
fprintf(stderr, "fstat() error/n");
if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1)
fprintf(stderr, "lseek() error/n");
if (write(fdout, "", 1) != 1)
fprintf(stderr, "write() error/n");
if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_FILE | MAP_SHARED,
fdin, 0)) == (caddr_t) -1)
fprintf(stderr, "mmap() error/n");
if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, fdout, 0)) == (caddr_t) -1)
fprintf(stderr, "mmap() error/n");
memcpy(dst, src, statbuf.st_size);
return 0;
}