/* * p4child.c — дочерняя программа, намеренно меняющая состояние системы. * * Создаёт по одному файлу в каталогах обеих панелей, оставляет CWD в * EXECLEFT, переключает экран в 40x32 и портит используемые Commander * записи палитры. Родитель обязан восстановить всё это после EXEC. */ #include #include #include #include static char child_cwd[256]; static int write_marker(const char *path, const char *text, uint16_t size) { int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC); int result = 0; if (fd < 0) return -1; if (write(fd, text, size) != (int)size) result = -1; if (close(fd) != 0) result = -1; return result; } static void damage_commander_palette(void) { static const uint8_t attrs[] = { 0x1Fu, 0x1Eu, 0x1Bu, 0x30u, 0x70u, 0x4Fu, 0x1Cu, 0x3Cu }; uint8_t i; uint8_t plane; for (i = 0u; i < (uint8_t)sizeof(attrs); i++) { for (plane = 0u; plane < 4u; plane++) { text_pal_set_color(plane, attrs[i], 0xFFu, 0x00u, 0xFFu); } } } int main(void) { static const char left_text[] = "created by P4CHILD\n"; static const char right_text[] = "passive refresh by P4CHILD\n"; int left_result; int right_result; left_result = chdir("\\EXECLEFT"); if (left_result == 0) { left_result = write_marker("CREATED.TXT", left_text, (uint16_t)(sizeof(left_text) - 1u)); } /* Идём через корень, оставляя проверяемые каталоги в формате 8.3. */ right_result = chdir(".."); if (right_result == 0) right_result = chdir("EXECRGHT"); if (right_result == 0) { right_result = write_marker("PASSIVE.TXT", right_text, (uint16_t)(sizeof(right_text) - 1u)); } /* Родитель должен вернуть собственный CWD даже из этого каталога. */ (void)chdir(".."); (void)chdir("EXECLEFT"); (void)settextmode(TEXT_MODE_40x32); damage_commander_palette(); clrscr_attr(0x27u); textattr(0x2Fu); gotoxy(0u, 0u); cputs("P4CHILD.EXE\r\n\r\n"); textattr(0x27u); cputs("Child changed mode, palette and CWD.\r\n"); cprintf("markers: active=%d passive=%d\r\n", left_result, right_result); if (getcwd(child_cwd, (uint16_t)sizeof(child_cwd))) { cprintf("child CWD: %s\r\n", child_cwd); } cputs("\r\nPress Enter to return code 5A..."); (void)getkey(); return 0x5A; }