int GetClipText(ClipData *cd) { int rc; ULONG PostCount; char *mem; rc = DosOpenMutexSem(SEM_PREFIX "CLIPSYN", &hmtxSyn); if (rc != 0) return -1; rc = DosOpenEventSem(SEM_PREFIX "CLIPGET", &hevGet); if (rc != 0) return -1; /* rc = DosOpenEventSem(SEM_PREFIX "CLIPPUT", &hevPut);*/ /* if (rc != 0) return -1;*/ rc = DosOpenEventSem(SEM_PREFIX "CLIPEND", &hevEnd); if (rc != 0) return -1; DosRequestMutexSem(hmtxSyn, SEM_INDEFINITE_WAIT); DosResetEventSem(hevEnd, &PostCount); DosPostEventSem(hevGet); DosWaitEventSem(hevEnd, SEM_INDEFINITE_WAIT); if (0 == DosGetNamedSharedMem((void **)&mem, MEM_PREFIX "CLIPDATA", PAG_READ | PAG_WRITE)) { cd->fLen = *(ULONG*)mem; cd->fChar = strdup(mem + 4); DosFreeMem(mem); } else { cd->fLen = 0; cd->fChar = 0; } DosPostEventSem(hevGet); DosReleaseMutexSem(hmtxSyn); /* DosCloseEventSem(hevPut);*/ DosCloseEventSem(hevGet); DosCloseEventSem(hevEnd); DosCloseMutexSem(hmtxSyn); return 0; }
SOM_Scope HMODULE SOMLINK WPSamFM_clsQueryModuleHandle (M_WPSamF *somSelf) { /* M_WPSamFData *somThis = M_WPSamFGetData (somSelf); */ M_WPSamFMethodDebug ("M_WPSamF","WPSamFM_clsQueryModuleHandle"); if(!hevPrfResetLock) if(DosOpenEventSem (HEV_PRFRESETLOCK, &hevPrfResetLock)) if(DosCreateEventSem(HEV_PRFRESETLOCK, // Name &hevPrfResetLock, // Pointer to sem 0, // Not used with named sems TRUE)) // Initial state (TRUE = POSTED) hevPrfResetLock = 0; if(!pShareInitOS2) if (DosGetNamedSharedMem ((PPVOID) &pShareInitOS2, SHARE_INITOS2, PAG_READ | PAG_WRITE)) pShareInitOS2 = 0; if(!hevSammy) if (DosOpenEventSem (HEV_SAMMY, &hevSammy)) hevSammy = 0; if (hmod == NULLHANDLE) { zString zsPathName; /* * Retrieve registered pathname of our module (DLL) and query the * module handle. */ zsPathName = _somLocateClassFile (SOMClassMgrObject, SOM_IdFromString (CLASSNAME), WPSamF_MajorVersion, WPSamF_MinorVersion); if (DosQueryModuleHandle (zsPathName, &hmod)) { DebugE (D_SOM, "_clsQueryModuleHandle", "Failed to load module"); hmod = NULLHANDLE; } } /* end if (hmod == NULLHANDLE) */ DebugULd (D_SOM, "_clsQueryModuleHandle", "hmod", hmod); return (hmod); }
unsigned long SysCreateEventSem(unsigned char *name, unsigned long numargs, RXSTRING args[], char *queuename, RXSTRING *retstr) { unsigned long rc; HEV handle = NULL; /* mutex handle */ if (numargs > 1) return INVALID_ROUTINE; if (numargs == 1) { rc = DosCreateEventSem(args[0].strptr, &handle, DC_SEM_SHARED, 1); /* may already be created try to open it */ if (rc != NO_ERROR) { rc = DosOpenEventSem(args[0].strptr, &handle); } } else { /* unnamed semaphore */ rc = DosCreateEventSem(NULL, &handle, DC_SEM_SHARED, 1); } if (!handle && rc != NO_ERROR) retstr->strlength = 0; /* return null string */ else { /* format the result */ retstr->strlength = sprintf(retstr->strptr, "%lu", handle); } return VALID_ROUTINE; }
static void WaitForSlip(void) { int FirstTime = 1; APIRET rc; short Seconds = Timeout; do { rc = DosOpenEventSem("\\sem32\\slip\\monitor", &slip_running); if (rc) { if (FirstTime) { printf("[ Waiting for SLIP - maximum wait = %d seconds ]\n", Timeout); FirstTime = 0; } Seconds--; if (Seconds >= 0) { if (Debug) { fprintf(stderr, "."); fflush(stderr); } DosSleep(1000L); } } } while (rc && (Seconds >= 0)); if (Debug) { fprintf(stderr, "\n"); } if (Seconds < 0) { printf("The SLIP driver appears not to have started.\n"); exit(1); } } // WaitForSlip()
static APIRET PipeWaitAndResetEventSem(HEV *SemHandle) { #define EVENTSEM_TIMEOUT SEM_INDEFINITE_WAIT APIRET rc; ULONG PostCt; rc = DosWaitEventSem(*SemHandle, EVENTSEM_TIMEOUT); if (!rc) rc = DosResetEventSem(*SemHandle, &PostCt); if (rc == ERROR_INVALID_HANDLE) { rc = DosOpenEventSem(0, SemHandle); if (!rc) { rc = DosWaitEventSem(*SemHandle, EVENTSEM_TIMEOUT); if (!rc) rc = DosResetEventSem(*SemHandle, &PostCt); } } if (rc == ERROR_ALREADY_RESET) rc = 0; return rc; }
static void OpenASem(const char *Name, HEV * Hev) { APIRET rc = DosOpenEventSem(BORCAST Name, Hev); if (rc != 0) { fprintf(stderr, "Error %lu accessing %s - is SLIP up?\n", rc, Name); exit(1); } } // OpenASem()
int PutClipText(ClipData *cd) { int rc; ULONG PostCount; char *mem; rc = DosOpenMutexSem(SEM_PREFIX "CLIPSYN", &hmtxSyn); if (rc != 0) return -1; /* rc = DosOpenEventSem(SEM_PREFIX "CLIPGET", &hevGet);*/ /* if (rc != 0) return -1;*/ rc = DosOpenEventSem(SEM_PREFIX "CLIPPUT", &hevPut); if (rc != 0) return -1; rc = DosOpenEventSem(SEM_PREFIX "CLIPEND", &hevEnd); if (rc != 0) return -1; DosRequestMutexSem(hmtxSyn, SEM_INDEFINITE_WAIT); DosResetEventSem(hevEnd, &PostCount); if (0 == DosAllocSharedMem((void **)&mem, MEM_PREFIX "CLIPDATA", cd->fLen + 5, PAG_COMMIT | PAG_READ | PAG_WRITE)) { ULONG L = cd->fLen; memcpy((void *)mem, (void *)&L, 4); strcpy(mem + 4, cd->fChar); } DosPostEventSem(hevPut); DosWaitEventSem(hevEnd, SEM_INDEFINITE_WAIT); DosPostEventSem(hevPut); DosReleaseMutexSem(hmtxSyn); DosCloseEventSem(hevPut); /* DosCloseEventSem(hevGet); */ DosCloseEventSem(hevEnd); DosCloseMutexSem(hmtxSyn); if (mem) DosFreeMem(mem); return 0; }
static APIRET PipeQueryEventSem(HEV *SemHandle, ULONG *ulPostCt) { APIRET rc; rc = DosQueryEventSem(*SemHandle, ulPostCt); if (rc == ERROR_INVALID_HANDLE) { rc = DosOpenEventSem(0, SemHandle); if (!rc) rc = DosQueryEventSem(*SemHandle, ulPostCt); } return rc; }
unsigned long SysOpenEventSem(unsigned char *name, unsigned long numargs, RXSTRING args[], char *queuename, RXSTRING *retstr) { unsigned long rc; HEV handle = NULL; /* mutex handle */ if (numargs != 1) return INVALID_ROUTINE; /* Only one argument accepted */ if (!string2ulong(args[0].strptr, &handle)) return INVALID_ROUTINE; /* get a binary handle */ /* try to open it */ rc = DosOpenEventSem(NULL, &handle); RETVAL(rc) }
static APIRET PipePostEventSem(HEV *SemHandle) { APIRET rc; rc = DosPostEventSem(*SemHandle); if (rc) { if (rc == ERROR_INVALID_HANDLE) { rc = DosOpenEventSem(0, SemHandle); if (!rc) rc = DosPostEventSem(*SemHandle); } else if (rc == ERROR_ALREADY_POSTED) rc = 0; } return rc; }
Event::Event ( char *tag, char *Name, int OneInstanceOnly ) : Tag(0), DebugFlag(FALSE) { if ( tag ) { Tag = (char*) malloc ( strlen(tag) + 1 ) ; strcpy ( Tag, tag ) ; } /* endif */ #ifdef __OS2__ char FullName [_MAX_PATH] ; strcpy ( FullName, "\\SEM32\\" ) ; strcat ( FullName, Name?Name:"" ) ; unsigned long Status = 1 ; Handle = 0 ; if ( Name && !OneInstanceOnly ) Status = DosOpenEventSem ( PSZ(FullName), &Handle ) ; if ( Status ) { Status = DosCreateEventSem ( PSZ(Name?FullName:0), &Handle, DC_SEM_SHARED, FALSE ) ; if ( OneInstanceOnly && ( Status == ERROR_DUPLICATE_NAME ) ) Log ( "Event(%s): Unable to create semaphore for '%s'. Already exists.", Tag?Tag:"", Name?Name:"" ) ; else if ( Status ) Log ( "Event(%s): Unable to create semaphore for '%s'. Status %i.", Tag?Tag:"", Name?Name:"", Status ) ; } /* endif */ #else Handle = CreateEvent ( 0, TRUE, FALSE, Name ) ; if ( Handle && OneInstanceOnly && ( GetLastError() == ERROR_ALREADY_EXISTS ) ) { Log ( "Event(%s): Unable to create event semaphore '%s'. Already exists.", Tag?Tag:"", Name?Name:"" ) ; CloseHandle ( Handle ) ; Handle = 0 ; } else if ( !Handle ) { DWORD Status = GetLastError ( ) ; Log ( "Event(%s): Unable to create event semaphore '%s'. Status %i.", Tag?Tag:"", Name?Name:"", Status ) ; } /* endif */ #endif } /* endmethod */
/** * Returns the spawn2 semaphore lazily creating it or making sure it's * available in the given process (the current process if NULL). Will return * NULLHANDLE if lazy creation fails. Must be called under global_lock(). */ unsigned long global_spawn2_sem(ProcDesc *proc) { APIRET arc; if (!proc) proc = find_proc_desc(getpid()); ASSERT(proc); if (gpData->spawn2_sem == NULLHANDLE) { ASSERT(proc->spawn2_sem == NULLHANDLE); arc = DosCreateEventSem(NULL, &gpData->spawn2_sem, DC_SEM_SHARED | DCE_AUTORESET, FALSE); if (arc != NO_ERROR) return NULLHANDLE; ASSERT(gpData->spawn2_sem_refcnt == 0); gpData->spawn2_sem_refcnt = 1; proc->spawn2_sem = gpData->spawn2_sem; } else if (proc->spawn2_sem == NULLHANDLE) { arc = DosOpenEventSem(NULL, &gpData->spawn2_sem); ASSERT_MSG(arc == NO_ERROR, "%ld %lx", arc, gpData->spawn2_sem); ASSERT(gpData->spawn2_sem_refcnt != 0); ++gpData->spawn2_sem_refcnt; proc->spawn2_sem = gpData->spawn2_sem; } TRACE("spawn2_sem %lx (refcnt %d)\n", proc->spawn2_sem, gpData->spawn2_sem_refcnt); return proc->spawn2_sem; }
VOID PostEventSemaphore (ULONG Known_key_number) { // Чтобы сообщить о нажатии клавиши, можно включить событийный семафор, // который должен быть создан внешним приложением (например, в одном из // потоков Nice). Задаем название семафора. CHAR Semaphore_name[256] = ""; switch (Known_key_number) { case MMK_POWER: strcpy (Semaphore_name, MMK_POWER_SEMAPHORE_NAME ); break; case MMK_SLEEP: strcpy (Semaphore_name, MMK_SLEEP_SEMAPHORE_NAME ); break; case MMK_MAIL_READER: strcpy (Semaphore_name, MMK_MAIL_READER_SEMAPHORE_NAME ); break; case MMK_MEDIA_PLAYER: strcpy (Semaphore_name, MMK_MEDIA_PLAYER_SEMAPHORE_NAME ); break; case MMK_PAGE_LEFT: strcpy (Semaphore_name, MMK_PAGE_LEFT_SEMAPHORE_NAME ); break; case MMK_PAGE_RIGHT: strcpy (Semaphore_name, MMK_PAGE_RIGHT_SEMAPHORE_NAME ); break; default: return; } // Включаем семафор. if (Semaphore_name[0] != 0) { HEV Semaphore = NULLHANDLE; ULONG Post_count = 0; if (DosOpenEventSem (Semaphore_name, &Semaphore) == NO_ERROR && DosQueryEventSem (Semaphore, &Post_count) == NO_ERROR) { APIRET RC = DosPostEventSem (Semaphore); } if (Semaphore != NULLHANDLE) DosClose (Semaphore); } // Возврат. return; }
int main (int argc, char *argv[]) { APIRET rc; PCHAR pcEnv; PRFPROFILE prfProfile; #ifdef DEBUG ulDebugMask = 0xFFFFFFFF; #endif /* DEBUG */ hab = WinInitialize(0); hmq = WinCreateMsgQueue(hab, 0); DebugS (1, "PM Interface initialized"); /* Shared Memory organisieren */ if (rc = DosGetNamedSharedMem ((PPVOID) &pShareInitOS2, SHARE_INITOS2, PAG_READ | PAG_WRITE)) { if (rc = DosAllocSharedMem( (PPVOID) &pShareInitOS2, // Pointer to shared mem SHARE_INITOS2, // Name CCHSHARE_INITOS2, // Size of shared mem PAG_COMMIT | PAG_READ | PAG_WRITE)) // Flags return(1); else { /* Shared Memory initialisieren */ memset (pShareInitOS2, '\0', CCHSHARE_INITOS2); pShareInitOS2->pszRegFile = (PCHAR) pShareInitOS2 + sizeof(*pShareInitOS2); strcpy (pShareInitOS2->pszRegFile, DosScanEnv (ENV_SYSTEM_INI, &pcEnv) ? "" : pcEnv); pShareInitOS2->pszRootUserIni = pShareInitOS2->pszRegFile + strlen(pShareInitOS2->pszRegFile) + 1; pShareInitOS2->pszRootSystemIni = pShareInitOS2->pszRootUserIni + 1; pShareInitOS2->pszUserIni = pShareInitOS2->pszRootSystemIni + 1; pShareInitOS2->pszSystemIni = pShareInitOS2->pszUserIni + CCHMAXPATH; pShareInitOS2->pszEnvironment = pShareInitOS2->pszSystemIni + CCHMAXPATH; } } DebugS (1, "Shared Memory initialized"); /* Semaphoren organisieren */ rc = DosOpenEventSem (HEV_SAMMY, &hevSammy); if( rc ) rc = DosCreateEventSem( HEV_SAMMY, // Name &hevSammy, // Pointer to sem 0, // Not used with named sems FALSE); // Initial state (FALSE = SET) else /* Sammy ist bereits installiert */ { pShareInitOS2->pszEnvironment[0] = '\0'; pShareInitOS2->pszEnvironment[1] = '\0'; pShareInitOS2->pszSystemIni[0] = '\0'; pShareInitOS2->pszUserIni[0] = '\0'; DosPostEventSem(hevSammy); goto Exit; } if( rc ) { intSammyRetCode = rc; goto Exit; } rc = DosOpenEventSem (HEV_PRFRESETLOCK, &hevPrfResetLock); if( rc ) rc = DosCreateEventSem( HEV_PRFRESETLOCK, // Name &hevPrfResetLock, // Pointer to sem 0, // Not used with named sems TRUE); // Initial state (TRUE = POSTED) if( rc ) { intSammyRetCode = rc; goto Exit; } DebugS (1, "Semaphores initialized"); ChangeWPS(pShareInitOS2->pszUserIni, pShareInitOS2->pszSystemIni); /* Hintergrundloop starten, das Shell mit aktueller Env. startet */ DosCreateThread (&tid1, (PFNTHREAD) thStartProg, (ULONG) ((argc > 1) ? argv[1] : ""), 0, THREADSTACK); DebugS (1, "Background loop started"); /* Hintergrundloop starten, das jeweils nach L�schen einer Semaphore */ /* einen prfReset initiiert */ DosCreateThread (&tid2, (PFNTHREAD) thSwitch, (ULONG) 0, 0, THREADSTACK); while (WinGetMsg (hab, &qmsg, 0, 0, 0)) WinDispatchMsg (hab, &qmsg); if (intSammyRetCode) { DosKillThread (tid1); DosKillThread (tid2); WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "WORKAREA=NO"); WinPostMsg(WinQueryWindow(HWND_DESKTOP, QW_BOTTOM), WM_CLOSE, 0, 0); WinAlarm (HWND_DESKTOP, WA_ERROR); prfProfile.pszSysName = (DosScanEnv (ENV_SYSTEM_INI, &pcEnv) ? "" : pcEnv); prfProfile.pszUserName = (DosScanEnv (ENV_USER_INI, &pcEnv) ? "" : pcEnv); prfProfile.cchUserName = strlen(prfProfile.pszUserName); prfProfile.cchSysName = strlen(prfProfile.pszSysName); DosSleep (1000); DosKillProcess( DKP_PROCESSTREE, ulShellID ); if ( !PrfReset(hab, &prfProfile)) WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "OPEN=ICON;WORKAREA=YES"); } Exit: WinDestroyMsgQueue(hmq); WinTerminate(hab); DebugS (1, "Application terminated"); return intSammyRetCode; }
int main(int argc, char *argv[]) { int do_load,do_unload,do_help,do_path; do_load=do_unload=do_help=do_path=0; char basepath[CCHMAXPATH]; if (argc == 1) do_help = 1; else { for (int i=1; i < argc; i++) { if (strnicmp(argv[i],"-l", 2) == 0) do_load = 1; else if (strnicmp(argv[i],"-u", 2) == 0) do_unload = 1; else if (strnicmp(argv[i],"-h", 2) == 0) do_help = 1; else if (strnicmp(argv[i],"-?", 2) == 0) do_help = 1; else if (strnicmp(argv[i],"-p", 2) == 0) { if (argc > i+1) { strcpy(basepath, argv[i+1]); if (basepath[strlen(basepath)] !='\\') { strcat(basepath, "\\"); } do_path = 1; } else { do_help = 1; } } } } if (do_help) { printf("%s for OS/2 preloader\n"\ "\n"\ "Usage: %s [-h] [-l | -u] [-p path]\n"\ " -h display this help\n"\ " -l load modules\n"\ " -u unload modules\n"\ " -p specify fully qualified path to directory where EXE is located\n", MOZ_APP_DISPLAYNAME, argv[0]); return(1); } if (do_unload) { HEV hev = NULLHANDLE; if (DosOpenEventSem(SEMNAME, &hev) == NO_ERROR) { if (DosPostEventSem(hev) == NO_ERROR) { if (DosCloseEventSem(hev) == NO_ERROR) { return(0); } } } printf("%s for OS/2 preloader is not running\n", MOZ_APP_DISPLAYNAME); return(1); } if (do_path == 0) { /* Get the name of this EXE and use its location as the path */ HMODULE hmodule; DosQueryModFromEIP(&hmodule, NULL, 0, NULL, NULL, (ULONG)ForceModuleLoad); DosQueryModuleName(hmodule, CCHMAXPATH, basepath); char *pchar = strrchr(basepath, '\\'); pchar++; *pchar = '\0'; } if (do_load) { ULONG ulCurMaxFH; LONG ulReqFH = 40; DosSetRelMaxFH(&ulReqFH, &ulCurMaxFH); HEV hev; if (DosCreateEventSem(SEMNAME, &hev, DC_SEM_SHARED, FALSE) != NO_ERROR) { printf("%s for OS/2 preloader is already running\n", MOZ_APP_DISPLAYNAME); return(1); } /* Add directory where EXE is located to LIBPATH */ DosSetExtLIBPATH(basepath, BEGIN_LIBPATH); /* loop through list loading named modules */ char filepath[CCHMAXPATH]; HMODULE hmod; int i = 0, nummodules = 0; while (bindir[i]) { strcpy(filepath,basepath); strcat(filepath,bindir[i]); if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) { ForceModuleLoad(hmod); nummodules++; } i++; } i = 0; while (compdir[i]) { strcpy(filepath, basepath); strcat(filepath, "COMPONENTS\\"); strcat(filepath, compdir[i]); if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) { ForceModuleLoad(hmod); nummodules++; } i++; } if (nummodules > 0) { if (DosWaitEventSem(hev, SEM_INDEFINITE_WAIT) != NO_ERROR) { printf("DosWaitEventSem failed\n"); return(1); } if (DosCloseEventSem(hev) != NO_ERROR) { printf("DosCloseEventSem failed\n"); return(1); } } else { printf("No modules available to load\n"); } } return(0); }
static void * tf (void *arg) { if (pthread_mutex_lock (&lock)) { puts ("1st locking of lock failed"); exit (1); } struct flock fl = { .l_type = F_WRLCK, .l_start = 0, .l_whence = SEEK_SET, .l_len = 10 }; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("fourth fcntl failed"); exit (1); } pthread_mutex_unlock (&lock); pthread_mutex_lock (&lock2); return NULL; } static int do_test (void) { fd = create_temp_file("tst-flock2-", NULL); if (fd == -1) { puts ("create_temp_file failed"); return 1; } int i; for (i = 0; i < 20; ++i) write (fd, "foobar xyzzy", 12); pthread_barrier_t *b; #ifdef __EMX__ APIRET arc; arc = DosAllocSharedMem ((PPVOID) &b, NULL, sizeof (pthread_barrier_t), PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_GETTABLE); if (arc) { puts ("DosAllocSharedMem failed"); return 1; } b->hmtx = NULLHANDLE; arc = DosCreateMutexSem (NULL, &b->hmtx, DC_SEM_SHARED, FALSE); if (arc) { puts ("DosCreateMutexSem failed"); return 1; } b->hev = NULLHANDLE; arc = DosCreateEventSem (NULL, &b->hev, DC_SEM_SHARED | DCE_AUTORESET, FALSE); if (arc) { puts ("DosCreateEventSem failed"); return 1; } b->cnt = 0; b->cnt_max = 2; #else b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (b == MAP_FAILED) { puts ("mmap failed"); return 1; } pthread_barrierattr_t ba; if (pthread_barrierattr_init (&ba) != 0) { puts ("barrierattr_init failed"); return 1; } if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed"); return 1; } if (pthread_barrier_init (b, &ba, 2) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrierattr_destroy (&ba) != 0) { puts ("barrierattr_destroy failed"); return 1; } #endif struct flock fl = { .l_type = F_WRLCK, .l_start = 0, .l_whence = SEEK_SET, .l_len = 10 }; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("first fcntl failed"); return 1; } pid_t pid = fork (); if (pid == -1) { puts ("fork failed"); return 1; } if (pid == 0) { #ifdef __EMX__ arc = DosGetSharedMem (b, PAG_READ | PAG_WRITE); if (arc) { puts ("DosGetSharedMem failed"); return 1; } arc = DosOpenMutexSem (NULL, &b->hmtx); if (arc) { puts ("DosOpenMutexSem failed"); return 1; } arc = DosOpenEventSem (NULL, &b->hev); if (arc) { puts ("DosOpenEventSem failed"); return 1; } #endif /* Make sure the child does not stay around indefinitely. */ alarm (10); /* Try to get the lock. */ if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0) { puts ("child: second flock succeeded"); return 1; } } pthread_barrier_wait (b); if (pid != 0) { fl.l_type = F_UNLCK; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("third fcntl failed"); return 1; } } pthread_barrier_wait (b); pthread_t th; if (pid == 0) { if (pthread_mutex_lock (&lock2) != 0) { puts ("1st locking of lock2 failed"); return 1; } if (pthread_create (&th, NULL, tf, NULL) != 0) { puts ("pthread_create failed"); return 1; } /* Let the new thread run. */ sleep (1); if (pthread_mutex_lock (&lock) != 0) { puts ("2nd locking of lock failed"); return 1; } puts ("child locked file"); } pthread_barrier_wait (b); if (pid != 0) { fl.l_type = F_WRLCK; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0) { puts ("fifth fcntl succeeded"); return 1; } puts ("file locked by child"); } pthread_barrier_wait (b); if (pid == 0) { if (pthread_mutex_unlock (&lock2) != 0) { puts ("unlock of lock2 failed"); return 1; } if (pthread_join (th, NULL) != 0) { puts ("join failed"); return 1; } puts ("child's thread terminated"); } pthread_barrier_wait (b); if (pid != 0) { fl.l_type = F_WRLCK; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0) { puts ("fifth fcntl succeeded"); return 1; } puts ("file still locked"); } pthread_barrier_wait (b); if (pid == 0) { _exit (0); } int status; if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) { puts ("waitpid failed"); return 1; } puts ("child terminated"); if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("sixth fcntl failed"); return 1; } return status; }